Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ RUN mkdir -p /tmp/rpms && \
then echo "Installing efs-utils from Amazon Linux 2 yum repo" && \
yum -y install --downloadonly --downloaddir=/tmp/rpms amazon-efs-utils-1.35.0-1.amzn2.noarch; \
else echo "Installing efs-utils from github using the latest git tag" && \
yum -y install systemd git rpm-build make openssl-devel curl && \
yum -y install systemd git rpm-build make openssl-devel curl golang cmake && \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \
source $HOME/.cargo/env && \
rustup update && \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,33 @@ subjects:
roleRef:
kind: ClusterRole
name: efs-csi-external-provisioner-role-describe-secrets
apiGroup: rbac.authorization.k8s.io
apiGroup: rbac.authorization.k8s.io
{{- if .Values.controller.fileSystemIdRefs.enabled }}
---
# Permissions needed for pulling file system id
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: efs-csi-filesystem-id-reader-role
labels:
app.kubernetes.io/name: {{ include "aws-efs-csi-driver.name" . }}
rules:
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: efs-csi-filesystem-id-reader-role-binding
labels:
app.kubernetes.io/name: {{ include "aws-efs-csi-driver.name" . }}
subjects:
- kind: ServiceAccount
name: {{ .Values.controller.serviceAccount.name }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: efs-csi-filesystem-id-reader-role
apiGroup: rbac.authorization.k8s.io
{{- end }}
2 changes: 1 addition & 1 deletion charts/aws-efs-csi-driver/templates/storageclass.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
name: {{ .name }}
{{- with .annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- toYaml . | nindent 4 }}
{{- end }}
provisioner: efs.csi.aws.com
{{- with .mountOptions }}
Expand Down
5 changes: 3 additions & 2 deletions charts/aws-efs-csi-driver/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ controller:
# topologyKey: kubernetes.io/hostname
# whenUnsatisfiable: ScheduleAnyway
topologySpreadConstraints: []
# Enable reading filesystem IDs from configmap/secret
fileSystemIdRefs:
enabled: false

## Node daemonset variables

Expand Down Expand Up @@ -219,8 +222,6 @@ storageClasses: []
# annotations:
# # Use that annotation if you want this to your default storageclass
# storageclass.kubernetes.io/is-default-class: "true"
# mountOptions:
# - tls
# parameters:
# provisioningMode: efs-ap
# fileSystemId: fs-1122aabb
Expand Down
4 changes: 3 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ func main() {
maxInflightMountCalls = flag.Int64("max-inflight-mount-calls", driver.UnsetMaxInflightMountCounts, "New NodePublishVolume operation will be blocked if maximum number of inflight calls is reached. If maxInflightMountCallsOptIn is true, it has to be set to a positive value.")
volumeAttachLimitOptIn = flag.Bool("volume-attach-limit-opt-in", false, "Opt in to use volume attach limit.")
volumeAttachLimit = flag.Int64("volume-attach-limit", driver.UnsetVolumeAttachLimit, "Maximum number of volumes that can be attached to a node. If volumeAttachLimitOptIn is true, it has to be set to a positive value.")
forceUnmountAfterTimeout = flag.Bool("force-unmount-after-timeout", false, "Enable force unmount if normal unmount times out during NodeUnpublishVolume.")
unmountTimeout = flag.Duration("unmount-timeout", driver.DefaultUnmountTimeout, "Timeout for unmounting a volume during NodePublishVolume when forceUnmountAfterTimeout is true. If the timeout is reached, the volume will be forcibly unmounted. The default value is 30 seconds.")
)
klog.InitFlags(nil)
flag.Parse()
Expand All @@ -65,7 +67,7 @@ func main() {
if err != nil {
klog.Fatalln(err)
}
drv := driver.NewDriver(*endpoint, etcAmazonEfs, *efsUtilsStaticFilesPath, *tags, *volMetricsOptIn, *volMetricsRefreshPeriod, *volMetricsFsRateLimit, *deleteAccessPointRootDir, *adaptiveRetryMode, *maxInflightMountCallsOptIn, *maxInflightMountCalls, *volumeAttachLimitOptIn, *volumeAttachLimit)
drv := driver.NewDriver(*endpoint, etcAmazonEfs, *efsUtilsStaticFilesPath, *tags, *volMetricsOptIn, *volMetricsRefreshPeriod, *volMetricsFsRateLimit, *deleteAccessPointRootDir, *adaptiveRetryMode, *maxInflightMountCallsOptIn, *maxInflightMountCalls, *volumeAttachLimitOptIn, *volumeAttachLimit, *forceUnmountAfterTimeout, *unmountTimeout)
if err := drv.Run(); err != nil {
klog.Fatalln(err)
}
Expand Down
2 changes: 2 additions & 0 deletions deploy/kubernetes/base/node-daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ spec:
- --max-inflight-mount-calls=10
- --volume-attach-limit-opt-in=false
- --volume-attach-limit=20
- --force-unmount-after-timeout=false
- --unmount-timeout=30s
env:
- name: CSI_ENDPOINT
value: unix:/csi/csi.sock
Expand Down
15 changes: 12 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ The following CSI interfaces are implemented:
| Parameters | Values | Default | Optional | Description |
|-----------------------|--------|-----------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| provisioningMode | efs-ap | | false | Type of volume provisioned by efs. Currently, Access Points are supported. |
| fileSystemId | | | false | File System under which access points are created. |
| fileSystemId | | | true* | File System under which access points are created. See footnote for usage details. |
| fileSystemIdConfigRef | | | true* | Reference to a ConfigMap containing the filesystem ID in format `namespace/name/key`. See footnote for usage details. |
| fileSystemIdSecretRef | | | true* | Reference to a Secret containing the filesystem ID in format `namespace/name/key`. See footnote for usage details. |
| directoryPerms | | | false | Directory permissions for [Access Point root directory](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html#enforce-root-directory-access-point) creation. |
| uid | | | true | POSIX user Id to be applied for [Access Point root directory](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html#enforce-root-directory-access-point) creation. |
| gid | | | true | POSIX group Id to be applied for [Access Point root directory](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html#enforce-root-directory-access-point) creation. |
Expand All @@ -38,9 +40,10 @@ The following CSI interfaces are implemented:
| subPathPattern | | `/${.PV.name}` | true | The template used to construct the subPath under which each of the access points created under Dynamic Provisioning. Can be made up of fixed strings and limited variables, is akin to the 'subPathPattern' variable on the [nfs-subdir-external-provisioner](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner) chart. Supports `.PVC.name`,`.PVC.namespace` and `.PV.name` |
| ensureUniqueDirectory | | true | true | **NOTE: Only set this to false if you're sure this is the behaviour you want**.<br/> Used when dynamic provisioning is enabled, if set to true, appends the a UID to the pattern specified in `subPathPattern` to ensure that access points will not accidentally point at the same directory. |
| az | | "" | true | Used for cross-account mount. `az` under storage class parameter is optional. If specified, mount target associated with the az will be used for cross-account mount. If not specified, a random mount target will be picked for cross account mount |
| reuseAccessPoint | | false | true | When set to true, it creates the Access Point client-token from the provided PVC name. So that the AccessPoint can be replicated from a different cluster if same PVC name and storageclass configuration are used. |
| reuseAccessPoint | | false | true | When set to true, it creates the Access Point client-token from the provided PVC name. So that the AccessPoint can be replicated from a different cluster if same PVC name and storageclass configuration are used. This feature is currently only supported for a single filesystem per account/region. If attempting to reuse access points across multiple clusters and filesystems within the same region, volume provisioning will fail. If you wish to use the same EFS accesspoint across different clusters for multiple filesystems in a single region, we recommend manually creating the access points and [statically provisioning](https://github.com/kubernetes-sigs/aws-efs-csi-driver/tree/master/examples/kubernetes/access_points) those volumes. |

**Note**
* **Filesystem ID Source (marked with \*)**: Exactly one of `fileSystemId`, `fileSystemIdConfigRef`, or `fileSystemIdSecretRef` must be specified to provide the EFS filesystem ID. For detailed usage guide, see the [ConfigMap and Secret Resolution Guide](./filesystem-id-resolution.md).
* Custom Posix group Id range for Access Point root directory must include both `gidRangeStart` and `gidRangeEnd` parameters. These parameters are optional only if both are omitted. If you specify one, the other becomes mandatory.
* When using a custom Posix group ID range, there is a possibility for the driver to run out of available POSIX group Ids. We suggest ensuring custom group ID range is large enough or create a new storage class with a new file system to provision additional volumes.
* `az` under storage class parameter is not be confused with efs-utils mount option `az`. The `az` mount option is used for cross-az mount or efs one zone file system mount within the same aws account as the cluster.
Expand All @@ -49,6 +52,7 @@ The following CSI interfaces are implemented:
* The uid/gid configured on the access point is either the uid/gid specified in the storage class, a value in the gidRangeStart-gidRangeEnd (used as both uid/gid) specified in the storage class, or is a value selected by the driver is no uid/gid or gidRange is specified.
* We suggest using [static provisioning](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/examples/kubernetes/static_provisioning/README.md) if you do not wish to use user identity enforcement.

---
If you want to pass any other mountOptions to Amazon EFS CSI driver while mounting, they can be passed in through the Persistent Volume or the Storage Class objects, depending on whether static or dynamic provisioning is used. The following are examples of some mountOptions that can be passed:
* **lookupcache**: Specifies how the kernel manages its cache of directory entries for a given mount point. Mode can be one of all, none, pos, or positive. Each mode has different functions and for more information you can refer to this [link](https://linux.die.net/man/5/nfs).
* **iam**: Use the CSI Node Pod's IAM identity to authenticate with Amazon EFS.
Expand Down Expand Up @@ -171,7 +175,7 @@ You can find previous efs-csi-driver versions' images from [here](https://galler

### Features
* Static provisioning - Amazon EFS file system needs to be created manually first, then it could be mounted inside container as a persistent volume (PV) using the driver.
* Dynamic provisioning - Uses a persistent volume claim (PVC) to dynamically provision a persistent volume (PV). On Creating a PVC, kuberenetes requests Amazon EFS to create an Access Point in a file system which will be used to mount the PV.
* Dynamic provisioning - Uses a persistent volume claim (PVC) to dynamically provision a persistent volume (PV). On Creating a PVC, Kubernetes requests Amazon EFS to create an Access Point in a file system which will be used to mount the PV.
* Mount Options - Mount options can be specified in the persistent volume (PV) or storage class for dynamic provisioning to define how the volume should be mounted.
* Encryption of data in transit - Amazon EFS file systems are mounted with encryption in transit enabled by default in the master branch version of the driver.
* Cross account mount - Amazon EFS file systems from different aws accounts can be mounted from an Amazon EKS cluster.
Expand Down Expand Up @@ -359,6 +363,11 @@ After deploying the driver, you can continue to these sections:
| max-inflight-mount-calls | | -1 | true | New NodePublishVolume operation will be blocked if maximum number of inflight calls is reached. If maxInflightMountCallsOptIn is true, it has to be set to a positive value. |
| volume-attach-limit-opt-in | | false | true | Opt in to use volume attach limit. |
| volume-attach-limit | | -1 | true | Maximum number of volumes that can be attached to a node. If volumeAttachLimitOptIn is true, it has to be set to a positive value. |
| force-unmount-after-timeout | | false | true | Enable force unmount if normal unmount times out during NodeUnpublishVolume |
| unmount-timeout | | 30s | true | Timeout for unmounting a volume during NodePublishVolume when forceUnmountAfterTimeout is true. If the timeout is reached, the volume will be forcibly unmounted. The default value is 30 seconds. |

#### Force Unmount After Timeout
The `force-unmount-after-timeout` feature addresses issues when `NodeUnpublishVolume` gets called infinite times and hangs indefinitely due to broken NFS connections. When enabled, if a normal unmount operation exceeds the configured timeout, the driver will forcibly unmount the volume to prevent indefinite hanging and allow the operation to complete.

#### Suggestion for setting max-inflight-mount-calls and volume-attach-limit

Expand Down
40 changes: 40 additions & 0 deletions docs/filesystem-id-resolution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Dynamic Filesystem ID Resolution

The EFS CSI driver supports dynamic filesystem ID resolution from Kubernetes ConfigMaps and Secrets. This enables workflows where tools provision EFS filesystems and write the filesystem ID to Kubernetes resources, which the CSI driver reads automatically during volume provisioning.

**Reference Format:** `namespace/name/key`

**Parameter Requirements:** Exactly one of `fileSystemId`, `fileSystemIdConfigRef`, or `fileSystemIdSecretRef` must be specified in StorageClass parameters.

**Example with ConfigMap:**
```yaml
# ConfigMap created
apiVersion: v1
kind: ConfigMap
metadata:
name: efs-config
namespace: kube-system
data:
fileSystemId: fs-02604354c13d0316d
---
# StorageClass references the ConfigMap
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemIdConfigRef: "kube-system/efs-config/fileSystemId"
directoryPerms: "700"
```

**Enabling RBAC Permissions (Required):**

This feature requires additional RBAC permissions for the controller service account to read ConfigMaps and Secrets. When installing via Helm, enable with:
```bash
helm install aws-efs-csi-driver ./charts/aws-efs-csi-driver \
--set controller.fileSystemIdRefs.enabled=true
```

For static manifest installations, manually apply the RBAC resources from the Helm chart templates.
1 change: 0 additions & 1 deletion examples/kubernetes/access_points/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ Also you can verify that data is written into the EFS filesystems:
```
spec:
mountOptions:
- tls
- accesspoint=fsap-068c22f0246419f75
```
as this could subject you to
Expand Down
2 changes: 0 additions & 2 deletions examples/kubernetes/cross_account_mount/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
mountOptions:
- tls
parameters:
provisioningMode: efs-ap
fileSystemId: fs-1234abcd
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@ apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
mountOptions:
- tls
4 changes: 0 additions & 4 deletions examples/kubernetes/volume_path/specs/example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ spec:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: efs-sc
mountOptions:
- tls
csi:
driver: efs.csi.aws.com
volumeHandle: fs-e8a95a42:/dir1
Expand Down Expand Up @@ -46,8 +44,6 @@ spec:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: efs-sc
mountOptions:
- tls
csi:
driver: efs.csi.aws.com
volumeHandle: fs-e8a95a42:/dir2
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,4 @@ replace k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.33.2

go 1.25.0

toolchain go1.25.1
toolchain go1.25.3
Loading