Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds capability to provision directories on the EFS dynamically #732

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ spec:
{{- end }}
- --v={{ .Values.controller.logLevel }}
- --delete-access-point-root-dir={{ hasKey .Values.controller "deleteAccessPointRootDir" | ternary .Values.controller.deleteAccessPointRootDir false }}
- --delete-provisioned-dir={{ hasKey .Values.controller "deleteProvisionedDir" | ternary .Values.controller.deleteProvisionedDir false }}
env:
- name: CSI_ENDPOINT
value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock
Expand Down
4 changes: 3 additions & 1 deletion charts/aws-efs-csi-driver/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ controller:
# environment: prod
# region: us-east-1
# Enable if you want the controller to also delete the
# path on efs when deleteing an access point
# path on efs when deleting an EFS access point
deleteAccessPointRootDir: false
# Enable if you want the controller to delete any directories it also provisions
deleteProvisionedDir: false
podAnnotations: {}
resources:
{}
Expand Down
4 changes: 3 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ func main() {
volMetricsFsRateLimit = flag.Int("vol-metrics-fs-rate-limit", 5, "Volume metrics routines rate limiter per file system")
deleteAccessPointRootDir = flag.Bool("delete-access-point-root-dir", false,
"Opt in to delete access point root directory by DeleteVolume. By default, DeleteVolume will delete the access point behind Persistent Volume and deleting access point will not delete the access point root directory or its contents.")
deleteProvisionedDir = flag.Bool("delete-provisioned-dir", false,
"Opt in to delete any provisioned directories and their contents. By default, DeleteVolume will not delete the directory behind Persistent Volume. Note: If root squash is enabled on your EFS it's possible this option will not work.")
tags = flag.String("tags", "", "Space separated key:value pairs which will be added as tags for EFS resources. For example, 'environment:prod region:us-east-1'")
)
klog.InitFlags(nil)
Expand All @@ -60,7 +62,7 @@ func main() {
if err != nil {
klog.Fatalln(err)
}
drv := driver.NewDriver(*endpoint, etcAmazonEfs, *efsUtilsStaticFilesPath, *tags, *volMetricsOptIn, *volMetricsRefreshPeriod, *volMetricsFsRateLimit, *deleteAccessPointRootDir)
drv := driver.NewDriver(*endpoint, etcAmazonEfs, *efsUtilsStaticFilesPath, *tags, *volMetricsOptIn, *volMetricsRefreshPeriod, *volMetricsFsRateLimit, *deleteAccessPointRootDir, *deleteProvisionedDir)
if err := drv.Run(); err != nil {
klog.Fatalln(err)
}
Expand Down
73 changes: 41 additions & 32 deletions docs/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ This example requires Kubernetes 1.17 or later and a driver version of 1.2.0 or
1. Download a manifest that deploys a Pod and a PVC.

```sh
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/pod.yaml
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/access_points/specs/pod.yaml
```

1. Deploy the Pod with a sample app and the PVC used by the Pod.
Expand Down
152 changes: 152 additions & 0 deletions examples/kubernetes/dynamic_provisioning/directories/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
## Dynamic Provisioning
**Important**
You can't use dynamic provisioning with Fargate nodes.

This example shows how to create a dynamically provisioned volume created through a directory on the file system and a Persistent Volume Claim (PVC) and consume it from a pod.

**Prerequisite**
This example requires Kubernetes 1.17 or later and a driver version of 1.5.x or later.

1. Create a storage class for Amazon EFS.

1. Retrieve your Amazon EFS file system ID. You can find this in the Amazon EFS console, or use the following AWS CLI command.

```sh
aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text
```

The example output is as follows.

```
fs-582a03f3
```

2. Download a `StorageClass` manifest for Amazon EFS.

```sh
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/directories/specs/storageclass.yaml
```

3. Edit [the file](./specs/storageclass.yaml). Find the following line, and replace the value for `fileSystemId` with your file system ID.

```
fileSystemId: fs-582a03f3
```

Modify the other values as needed:
* `fileSystemId` - The file system under which the access point is created.
* `directoryPerms` - The directory permissions of the root directory created by the access point.
* `gidRangeStart` (Optional) - The starting range of the Posix group ID to be applied onto the root directory of the access point. The default value is `50000`.
* `gidRangeEnd` (Optional) - The ending range of the Posix group ID. The default value is `7000000`.
* `basePath` (Optional) - The path on the file system under which the access point root directory is created. If the path isn't provided, the access points root directory is created under the root of the file system.

4. Deploy the storage class.

```sh
kubectl apply -f storageclass.yaml
```

2. Test automatic provisioning by deploying a Pod that makes use of the PVC:

1. Download a manifest that deploys a Pod and a PVC.

```sh
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/pod.yaml
```

2. Deploy the Pod with a sample app and the PVC used by the Pod.

```sh
kubectl apply -f pod.yaml
```

3. Determine the names of the Pods running the controller.

```sh
kubectl get pods -n kube-system | grep efs-csi-controller
```

The example output is as follows.

```
efs-csi-controller-74ccf9f566-q5989 3/3 Running 0 40m
efs-csi-controller-74ccf9f566-wswg9 3/3 Running 0 40m
```

4. After few seconds, you can observe the controller picking up the change \(edited for readability\). Replace `74ccf9f566-q5989` with a value from one of the Pods in your output from the previous command.

```sh
kubectl logs efs-csi-controller-74ccf9f566-q5989 \
-n kube-system \
-c csi-provisioner \
--tail 10
```

The example output is as follows.

```
[...]
1 controller.go:737] successfully created PV pvc-5983ffec-96cf-40c1-9cd6-e5686ca84eca for PVC efs-claim...
```

If you don't see the previous output, run the previous command using one of the other controller Pods.

5. Confirm that a persistent volume was created with a status of `Bound` to a `PersistentVolumeClaim`:

```sh
kubectl get pv
```

The example output is as follows.

```
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-5983ffec-96cf-40c1-9cd6-e5686ca84eca 20Gi RWX Delete Bound default/efs-claim efs-sc 7m57s
```

6. View details about the `PersistentVolumeClaim` that was created.

```sh
kubectl get pvc
```

The example output is as follows.

```
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
efs-claim Bound pvc-5983ffec-96cf-40c1-9cd6-e5686ca84eca 20Gi RWX efs-sc 9m7s
```

7. View the sample app Pod's status until the `STATUS` becomes `Running`.

```sh
kubectl get pods -o wide
```

The example output is as follows.

```
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
efs-app 1/1 Running 0 10m 192.168.78.156 ip-192-168-73-191.region-code.compute.internal <none> <none>
```
**Note**
If a Pod doesn't have an IP address listed, make sure that you added a mount target for the subnet that your node is in \(as described at the end of [Create an Amazon EFS file system](#efs-create-filesystem)\). Otherwise the Pod won't leave `ContainerCreating` status. When an IP address is listed, it may take a few minutes for a Pod to reach the `Running` status.

1. Confirm that the data is written to the volume.

```sh
kubectl exec efs-app -- bash -c "cat data/out"
```

The example output is as follows.

```
[...]
Tue Mar 23 14:29:16 UTC 2021
Tue Mar 23 14:29:21 UTC 2021
Tue Mar 23 14:29:26 UTC 2021
Tue Mar 23 14:29:31 UTC 2021
[...]
```

2. \(Optional\) Terminate the Amazon EKS node that your Pod is running on and wait for the Pod to be re\-scheduled. Alternately, you can delete the Pod and redeploy it. Complete the previous step again, confirming that the output includes the previous output.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: efs-claim
spec:
accessModes:
- ReadWriteMany
storageClassName: efs-sc
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: Pod
metadata:
name: efs-app
spec:
containers:
- name: app
image: centos
command: ["/bin/sh"]
args: ["-c", "while true; do echo $(date -u) >> /data/out; sleep 5; done"]
volumeMounts:
- name: persistent-storage
mountPath: /data
volumes:
- name: persistent-storage
persistentVolumeClaim:
claimName: efs-claim
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-dir
fileSystemId: fs-92107410
directoryPerms: "700"
gidRangeStart: "1000" # optional
gidRangeEnd: "2000" # optional
basePath: "/dynamic_provisioning" # optional
7 changes: 4 additions & 3 deletions hack/values.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
controller:
create: true
logLevel: 5
serviceAccount:
create: true
deleteProvisionedDir: true
node:
logLevel: 5
serviceAccount:
controller:
create: true

1 change: 1 addition & 0 deletions hack/values_eksctl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ controller:
logLevel: 5
serviceAccount:
create: false # let eksctl create it
deleteProvisionedDir: true
node:
logLevel: 5
serviceAccount:
Expand Down
Loading