Stay organized with collections
Save and categorize content based on your preferences.
The Elastic File System (EFS) is the
underlying AWS mechanism for providing storage (disk space) to your cluster.
A PersistentVolume is a cluster resource that makes EFS
storage available to your workloads and ensures that it persists even when no
workloads are connected to it. This topic describes how a workload can access a
PersistentVolume with a PersistentVolumeClaim.
This page is for Operators and Storage specialists who want to
configure and manage storage. To learn more about common roles and example tasks
that we reference in Google Cloud content, see
Common GKE user roles and tasks.
GKE on AWS supports static provisioning of PersistentVolumes for all
supported Kubernetes versions. For clusters at Kubernetes version 1.24 or
later, GKE on AWS also supports dynamic provisioning. To use dynamic
provisioning, your cluster administrator must configure it. To learn how, see
configure a PersistentVolume.
Create a PersistentVolumeClaim
Choose the appropriate tab below depending on whether you want your workload to
connect to a statically or dynamically-provisioned persistent volume.
Static
These instructions assume that your cluster administrator has already provisioned
at least one PersistentVolume. To access this PersistentVolume and use its
underlying EFS with your workloads, create a PersistentVolumeClaim.
To create a PersistentVolumeClaim for a statically-provisioned PersistentVolume,
copy the following YAML manifest into a file named efs-claim.yaml.
apiVersion:v1kind:PersistentVolumeClaimmetadata:name:CLAIM_NAMEspec:accessModes:-ReadWriteManystorageClassName:""# Leave as empty string for static provisioningresources:requests:storage:5Gi
Replace:
CLAIM_NAME: a name you choose for your PersistentVolumeClaim
to bind to - for example, efs-claim1. Leave blank to bind to the
default storage class
Apply the YAML to your cluster.
kubectlapply-fefs-claim.yaml
This output confirms the PersistentVolumeClaim's creation.
persistentvolumeclaim/CLAIM_NAME created
Dynamic
These instructions assume that your cluster administrator has already
provisioned at least one StorageClass for dynamic provisioning. To create a
dynamically-provisioned PersistentVolume with this StorageClass and use the
underlying EFS access point with your workloads, create a PersistentVolumeClaim.
To create a PersistentVolumeClaim, follow these steps. The EFS CSI driver uses
this PersistentVolumeClaim with the indicated StorageClass to dynamically
provision a PersistentVolume.
Copy the following YAML manifest into a file named efs-claim.yaml.
CLAIM_NAME: a name you choose for your PersistentVolumeClaim -
for example, efs-claim1
EFS_STORAGE_CLASS_NAME: the name of the StorageClass you want
your PersistentVolumeClaim to bind to. Leave this field blank to bind to
the default storage class
Apply the YAML to your cluster.
kubectlapply-fefs-claim.yaml
The output confirms the PersistentVolumeClaim's creation.
persistentvolumeclaim/CLAIM_NAME created
Create a StatefulSet
After you have created a PersistentVolumeClaim, you can use it in a workload.
This section creates a sample StatefulSet that uses a PersistentVolumeClaim.
You can also use a PersistentVolumeClaim with other workload types
such as Pods and Deployments by referencing the claim in spec.volumes.
To create a StatefulSet that mounts the EFS resource referenced in your
PersistentVolumeClaim, perform the following steps.
Copy the following YAML manifest into a file named efs-statefulset.yaml.
This example manifest launches an Ubuntu Linux container that mounts your
EFS resource at /efs-data. The container writes every five seconds to a
file on your EFS resource named out.txt.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-09-04 UTC."],[],[],null,["# Use an EFS resource\n\nThe [Elastic File System](https://aws.amazon.com/efs/) (EFS) is the\nunderlying AWS mechanism for providing storage (disk space) to your cluster.\nA PersistentVolume is a cluster resource that makes EFS\nstorage available to your workloads and ensures that it persists even when no\nworkloads are connected to it. This topic describes how a workload can access a\nPersistentVolume with a PersistentVolumeClaim.\n\nThis page is for Operators and Storage specialists who want to\nconfigure and manage storage. To learn more about common roles and example tasks\nthat we reference in Google Cloud content, see\n[Common GKE user roles and tasks](/kubernetes-engine/enterprise/docs/concepts/roles-tasks).\n\nGKE on AWS supports static provisioning of PersistentVolumes for all\nsupported Kubernetes versions. For clusters at Kubernetes version 1.24 or\nlater, GKE on AWS also supports dynamic provisioning. To use dynamic\nprovisioning, your cluster administrator must configure it. To learn how, see\n[configure a `PersistentVolume`](/kubernetes-engine/multi-cloud/docs/aws/how-to/configure-efs).\n| **Note:** Dynamic provisioning is available in GKE on AWS as a preview feature. Contact Google Cloud your support team for access.\n\nCreate a PersistentVolumeClaim\n------------------------------\n\nChoose the appropriate tab below depending on whether you want your workload to\nconnect to a statically or dynamically-provisioned persistent volume. \n\n### Static\n\nThese instructions assume that your cluster administrator has already provisioned\nat least one PersistentVolume. To access this PersistentVolume and use its\nunderlying EFS with your workloads, create a PersistentVolumeClaim.\n\nTo create a PersistentVolumeClaim for a statically-provisioned PersistentVolume,\ncopy the following YAML manifest into a file named `efs-claim.yaml`. \n\n apiVersion: v1\n kind: PersistentVolumeClaim\n metadata:\n name: \u003cvar translate=\"no\"\u003e\u003cspan class=\"devsite-syntax-l devsite-syntax-l-Scalar devsite-syntax-l-Scalar-Plain\"\u003eCLAIM_NAME\u003c/span\u003e\u003c/var\u003e\n spec:\n accessModes:\n - ReadWriteMany\n storageClassName: \"\" # Leave as empty string for static provisioning\n resources:\n requests:\n storage: 5Gi\n\nReplace:\n\n- \u003cvar translate=\"no\"\u003eCLAIM_NAME\u003c/var\u003e: a name you choose for your PersistentVolumeClaim to bind to - for example, `efs-claim1`. Leave blank to bind to the default storage class\n\n| **Note:** You must use the same `storageClassName` value for your PersistentVolume and PersistentVolumeClaim resources.\n\n1. Apply the YAML to your cluster.\n\n kubectl apply -f efs-claim.yaml\n\n This output confirms the PersistentVolumeClaim's creation. \n\n persistentvolumeclaim/\u003cvar translate=\"no\"\u003eCLAIM_NAME\u003c/var\u003e created\n\n### Dynamic\n\nThese instructions assume that your cluster administrator has already\nprovisioned at least one StorageClass for dynamic provisioning. To create a\ndynamically-provisioned PersistentVolume with this StorageClass and use the\nunderlying EFS access point with your workloads, create a PersistentVolumeClaim.\n\nTo create a PersistentVolumeClaim, follow these steps. The EFS CSI driver uses\nthis PersistentVolumeClaim with the indicated StorageClass to dynamically\nprovision a PersistentVolume.\n\n1. Copy the following YAML manifest into a file named `efs-claim.yaml`.\n\n apiVersion: v1\n kind: PersistentVolumeClaim\n metadata:\n name: \u003cvar translate=\"no\"\u003e\u003cspan class=\"devsite-syntax-l devsite-syntax-l-Scalar devsite-syntax-l-Scalar-Plain\"\u003eCLAIM_NAME\u003c/span\u003e\u003c/var\u003e\n spec:\n accessModes:\n - ReadWriteMany\n storageClassName: \"\u003cvar translate=\"no\"\u003eEFS_STORAGE_CLASS_NAME\u003c/var\u003e\"\n resources:\n requests:\n storage: 5Gi\n\nReplace:\n\n- \u003cvar translate=\"no\"\u003eCLAIM_NAME\u003c/var\u003e: a name you choose for your PersistentVolumeClaim - for example, `efs-claim1`\n- \u003cvar translate=\"no\"\u003eEFS_STORAGE_CLASS_NAME\u003c/var\u003e: the name of the StorageClass you want your PersistentVolumeClaim to bind to. Leave this field blank to bind to the default storage class\n\n1. Apply the YAML to your cluster.\n\n kubectl apply -f efs-claim.yaml\n\n The output confirms the PersistentVolumeClaim's creation. \n\n persistentvolumeclaim/\u003cvar translate=\"no\"\u003eCLAIM_NAME\u003c/var\u003e created\n\nCreate a StatefulSet\n--------------------\n\nAfter you have created a PersistentVolumeClaim, you can use it in a workload.\nThis section creates a sample StatefulSet that uses a PersistentVolumeClaim.\nYou can also use a PersistentVolumeClaim with other workload types\nsuch as Pods and Deployments by referencing the claim in `spec.volumes`.\n\nTo create a StatefulSet that mounts the EFS resource referenced in your\nPersistentVolumeClaim, perform the following steps.\n\n1. Copy the following YAML manifest into a file named `efs-statefulset.yaml`.\n This example manifest launches an Ubuntu Linux container that mounts your\n EFS resource at `/efs-data`. The container writes every five seconds to a\n file on your EFS resource named `out.txt`.\n\n apiVersion: apps/v1\n kind: StatefulSet\n metadata:\n name: efs-shell\n spec:\n selector:\n matchLabels:\n app: test-efs\n serviceName: efs-app\n replicas: 1\n template:\n metadata:\n labels:\n app: test-efs\n spec:\n terminationGracePeriodSeconds: 10\n containers:\n - name: linux\n image: ubuntu:bionic\n command: [\"/bin/sh\"]\n args: [\"-c\", \"while true; do echo $(date -u) \u003e\u003e /efs-data/out.txt; sleep 5; done\"]\n volumeMounts:\n - name: efs-volume\n mountPath: /efs-data\n volumes:\n - name: efs-volume\n persistentVolumeClaim:\n claimName: \u003cvar translate=\"no\"\u003e\u003cspan class=\"devsite-syntax-l devsite-syntax-l-Scalar devsite-syntax-l-Scalar-Plain\"\u003eCLAIM_NAME\u003c/span\u003e\u003c/var\u003e\n\n Replace \u003cvar translate=\"no\"\u003eCLAIM_NAME\u003c/var\u003e with the name of the PersistentVolumeClaim\n you specified previously - for example, `efs-claim1`.\n2. Apply the YAML to your cluster.\n\n kubectl apply -f efs-statefulset.yaml\n\n The output confirms the StatefulSet's creation. \n\n statefulset.apps/efs-shell created\n\n The StatefulSet might take several minutes to download and launch the container\n image.\n3. Confirm the StatefulSet's Pod is in `Running` status with `kubectl get pods`.\n\n kubectl get pods -l app=test-efs\n\n The output includes the name of the Pod and its status. In the following\n response, the Pod's name is `efs-shell-0`. \n\n NAME READY STATUS RESTARTS AGE\n efs-shell-0 1/1 Running 0 1m\n\n4. After the Pod is in Running status, use `kubectl exec` to connect to\n the Pod hosting the StatefulSet.\n\n kubectl exec -it efs-shell-0 -- bash\n\n The `kubectl` command launches a shell on the Pod.\n5. To confirm that your EFS resource is mounted, check the contents of\n the `out.txt` file with the `tail` command.\n\n tail /efs-data/out.txt\n\n The output contains recent times in UTC.\n6. Disconnect from the Pod with the `exit` command.\n\n exit\n\n Your shell returns to your local machine.\n\nClean up\n--------\n\nTo remove the StatefulSet, use `kubectl delete`. \n\n kubectl delete -f efs-statefulset.yaml\n\nWhat's next\n-----------\n\n- Learn how to [configure an EFS resource](/kubernetes-engine/multi-cloud/docs/aws/how-to/configure-efs)\n- Learn how to [use StorageClasses with your workloads](/kubernetes-engine/multi-cloud/docs/aws/how-to/storage-class)"]]