{"id":112,"date":"2023-04-28T09:24:00","date_gmt":"2023-04-28T09:24:00","guid":{"rendered":"https:\/\/cloudtechner.com\/blog\/?p=112"},"modified":"2024-06-13T11:07:36","modified_gmt":"2024-06-13T11:07:36","slug":"setting-up-efs-as-persistent-volume-for-aws-eks","status":"publish","type":"post","link":"https:\/\/cloudtechner.com\/blog\/setting-up-efs-as-persistent-volume-for-aws-eks\/","title":{"rendered":"Setting up EFS as persistent volume for AWS EKS"},"content":{"rendered":"\n<p>Author: <a href=\"https:\/\/www.linkedin.com\/in\/neha-chalia-9b545b247\">Neha Chalia<\/a>, Associate Engineer &#8211; CloudDevOps<\/p>\n\n\n<div class=\"taxonomy-post_tag wp-block-post-terms\"><a href=\"https:\/\/cloudtechner.com\/blog\/tag\/aws\/\" rel=\"tag\">AWS<\/a><span class=\"wp-block-post-terms__separator\">, <\/span><a href=\"https:\/\/cloudtechner.com\/blog\/tag\/backup\/\" rel=\"tag\">Backup<\/a><span class=\"wp-block-post-terms__separator\">, <\/span><a href=\"https:\/\/cloudtechner.com\/blog\/tag\/cloud\/\" rel=\"tag\">Cloud<\/a><span class=\"wp-block-post-terms__separator\">, <\/span><a href=\"https:\/\/cloudtechner.com\/blog\/tag\/storage\/\" rel=\"tag\">Storage<\/a><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:926\/1*DlT3mMPPHwTvnKS5zMhpnw.png\" alt=\"\"\/><\/figure><\/div>\n\n\n<p id=\"895e\">Kubernetes, also known as k8s, is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. Amazon EKS is a managed Kubernetes service to run Kubernetes in the AWS cloud and on-premises data centers.<\/p>\n\n\n\n<p id=\"e0af\">For many applications there may be requirement of persistent storage to persist data even if the process is killed\/restarted\/stopped or the machine hosting the application itself is stopped. Now, if any such application is hosted on Kubernetes, it doesn\u2019t provide data persistence out of the box which means when a pod is re-created, the data is lost. In Kubernetes, data persistent can be achieved using a<strong>&nbsp;Persistent Volume (PV)<\/strong>&nbsp;which is a piece of storage to store data which can be used by pods running in Kubernetes cluster.<\/p>\n\n\n\n<p id=\"cefa\">As we know AWS provides EBS storage service for data persistence and when using AWS EKS , AWS EBS is the default storage for creating Persistent Volume. But biggest challenge with using EBS as Persistent Volume in Kubernetes Cluster is, it can work in&nbsp;<strong>ReadWriteOnce&nbsp;<\/strong>access mode only which means it can be mounted in read-write mode when all the pods are running on single node but if pods are running on multiple nodes, they will not be able to access the data.<\/p>\n\n\n\n<p id=\"c2d5\">In case we have requirement of mounting Persistent Volume on multiple pods running on multiple nodes in read-write mode then in such cases we can\u2019t use AWS EBS as persistent volume in Kubernetes Cluster. For such requirement we can use AWS EFS (Elastic File storage) as Persistent Volume in Kubernetes cluster which works in&nbsp;<strong>ReadWriteMany&nbsp;<\/strong>access mode using which can mount Persistent Volume on multiple pods running on multiple nodes in read-write mode<\/p>\n\n\n\n<p id=\"ad57\">In this blog, I will be explaining how to setup AWS EFS as Persistent Volume in AWS EKS. We will also see the challenge when we use EBS as Persistent Volume in Kubernetes and how that challenge is resolved when we changed to EFS as Persistent Volume.<\/p>\n\n\n\n<p id=\"56de\">Before I jump into the setup part, lets revisit some basic concepts of PV, EBS and EFS.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"75fb\">What is Persistent Volume (PV) and why its need in Kubernetes:<\/h3>\n\n\n\n<p id=\"a36b\">Persistent volume basically provides a way to store data that can be used by multiple pods running in different nodes in the cluster, and that data should persist even after the pod or node is deleted. Persistent Volume are useful in scenarios where we need to store data that needs to survive beyond the lifetime of the pod or container that created it.<\/p>\n\n\n\n<p id=\"4a68\">The need for a persistent volume in Kubernetes arises from the fact that containerized applications are often stateless, meaning that they don\u2019t retain any data when they are restarted or moved to a different node. However, many applications require persistent data storage, such as databases, file systems, or message queues, that must be accessible to multiple pods or containers in a cluster.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"b123\">EBS (Elastic block storage)<\/h3>\n\n\n\n<p id=\"93c1\">EBS is a service offered by Amazon that stores information for Amazon EC2 Instances. EBS volumes can be attached to EC2 Instances and also to cluster. It is also used as a primary storage device for backups, data archiving and disaster recovery.<\/p>\n\n\n\n<p id=\"8912\">Before we jump into setting EFS as a persistent volume in k8s.Let\u2019s start with the setup instructions of EBS.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"76df\">EFS (Elastic File storage)<\/h3>\n\n\n\n<p id=\"42db\">EFS (Elastic File storage) is a storage service that can be accessed by multiple pods running in different nodes within the cluster. By using EFS, we can enable persistent storage for stateful applications running on EKS Cluster without having to manage the underlying infrastructure. EFS volumes can be used to store application data that needs to be persist across pod restarts or node failure.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"8223\">Set up instructions:<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"ed58\">Setup EBS as Persistent Volume in AWS EKS<\/h4>\n\n\n\n<p id=\"81b2\">First lets see how EBS works in Kubernetes Cluster.<\/p>\n\n\n\n<p id=\"f9fc\"><strong>Pre-requisites:<\/strong><\/p>\n\n\n\n<ul>\n<li>Set AWS Identity and Access Management (IAM) permissions for creating and attaching a policy to the Amazon EKS worker node role&nbsp;<strong>CSI Driver Role.<\/strong><\/li>\n\n\n\n<li>Create your Amazon EKS cluster and join your worker nodes to the cluster<\/li>\n\n\n\n<li>Have an existing IAM OpenID Connect (OIDC) provider for your cluster. To determine if you already have a cluster, or to create one, see&nbsp;<a href=\"https:\/\/docs.aws.amazon.com\/eks\/latest\/userguide\/enable-iam-roles-for-service-accounts.html\" target=\"_blank\" rel=\"noreferrer noopener\">Create an IAM OIDC provider for your cluster<\/a><\/li>\n<\/ul>\n\n\n\n<p id=\"10b5\"><strong>Deploy the Amazon EBS CSI driver<\/strong><\/p>\n\n\n\n<p id=\"895c\">1.Firstly, download an example IAM policy with permissions that allow your worker nodes to create and modify Amazon EBS volumes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -o example-iam-policy.json https:\/\/raw.githubusercontent.com\/kubernetes-sigs\/aws-ebs-csi-driver\/v0.9.0\/docs\/example-iam-policy.json<\/code><\/pre>\n\n\n\n<p id=\"9348\">2. Create an IAM policy named&nbsp;<strong>Amazon_EBS_CSI_Driver<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws iam create-policy --policy-name AmazonEKS_EBS_CSI_Driver_Policy --policy-document file:\/\/example-iam-policy.json<\/code><\/pre>\n\n\n\n<p id=\"5a52\">3. View your cluster\u2019s OIDC provider URL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws eks describe-cluster --name your_cluster_name --query \"cluster.identity.oidc.issuer\" --output text<\/code><\/pre>\n\n\n\n<p id=\"364e\"><strong>Note:<\/strong>&nbsp;In step 3, replace&nbsp;<strong>your_cluster_name<\/strong>&nbsp;with your cluster name.<\/p>\n\n\n\n<p id=\"ad9a\">4. Create the following IAM trust policy file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat &lt;&lt;EOF &gt; trust-policy.json<br>{<br>  \"Version\": \"2012-10-17\",<br>  \"Statement\": &#91;<br>    {<br>      \"Effect\": \"Allow\",<br>      \"Principal\": {<br>        \"Federated\": \"arn:aws:iam::YOUR_AWS_ACCOUNT_ID:oidc-provider\/oidc.eks.YOUR_AWS_REGION.amazonaws.com\/id\/&lt;XXXXXXXXXX45D83924220DC4815XXXXX&gt;\"<br>      },<br>      \"Action\": \"sts:AssumeRoleWithWebIdentity\",<br>      \"Condition\": {<br>        \"StringEquals\": {<br>          \"oidc.eks.YOUR_AWS_REGION.amazonaws.com\/id\/&lt;XXXXXXXXXX45D83924220DC4815XXXXX&gt;:sub\": \"system:serviceaccount:kube-system:ebs-csi-controller-sa\"<br>        }<br>      }<br>    }<br>  ]<br>}<br>EOF<\/code><\/pre>\n\n\n\n<p id=\"d8ba\"><strong>Note:<\/strong>&nbsp;In step 4, replace&nbsp;<strong>YOUR_AWS_ACCOUNT_ID<\/strong>&nbsp;with your account ID. Replace&nbsp;<strong>YOUR_AWS_REGION<\/strong>&nbsp;with your AWS Region. Replace&nbsp;<strong>XXXXXXXXXX45D83924220DC4815XXXXX<\/strong>&nbsp;with the value returned in step 3<\/p>\n\n\n\n<p id=\"870e\">5. Create an IAM role:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws iam create-role \\<br>  --role-name AmazonEKS_EBS_CSI_DriverRole \\<br>  --assume-role-policy-document file:\/\/\"trust-policy.json\"<\/code><\/pre>\n\n\n\n<p id=\"b6e7\">6. Attach your new IAM policy to the role:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws iam attach-role-policy \\<br>--policy-arn arn:aws:iam::&lt;AWS_ACCOUNT_ID&gt;:policy\/AmazonEKS_EBS_CSI_Driver_Policy \\<br>--role-name AmazonEKS_EBS_CSI_DriverRole<\/code><\/pre>\n\n\n\n<p id=\"9831\"><strong>Note<\/strong>: The policy ARN can be found in the output from step 2 above.<\/p>\n\n\n\n<p id=\"32aa\">7. To deploy the Amazon EBS CSI driver, run one of the following commands based on your Region:<\/p>\n\n\n\n<p id=\"6b90\">All Regions other than China Regions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -k \"github.com\/kubernetes-sigs\/aws-ebs-csi-driver\/deploy\/kubernetes\/overlays\/stable\/?ref=master\"<\/code><\/pre>\n\n\n\n<p id=\"a93e\">Beijing and Ningxia China Regions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -k \"github.com\/kubernetes-sigs\/aws-ebs-csi-driver\/deploy\/kubernetes\/overlays\/stable-cn\/?ref=master\"<\/code><\/pre>\n\n\n\n<p id=\"cb61\">8. Annotate the&nbsp;<strong>ebs-csi-controller-sa<\/strong>&nbsp;Kubernetes service account with the Amazon Resource Name (ARN) of the IAM role that you created earlier:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl annotate serviceaccount ebs-csi-controller-sa \\<br>  -n kube-system \\<br>  eks.amazonaws.com\/role-arn=arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role\/AmazonEKS_EBS_CSI_DriverRole<\/code><\/pre>\n\n\n\n<p id=\"2c2d\"><strong>Note:<\/strong>&nbsp;Replace&nbsp;<strong>YOUR_AWS_ACCOUNT_ID<\/strong>&nbsp;with your account ID.<\/p>\n\n\n\n<p id=\"b0f5\">9. Delete the driver pods:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl delete pods \\<br>  -n kube-system \\<br>  -l=app=ebs-csi-controller<\/code><\/pre>\n\n\n\n<p id=\"60a0\">Test the Amazon EBS CSI driver:<\/p>\n\n\n\n<p id=\"c532\">You can test your Amazon EBS CSI driver with an application that uses dynamic provisioning. The Amazon EBS volume is provisioned on demand.<\/p>\n\n\n\n<ol>\n<li>Clone the&nbsp;<strong>aws-ebs-csi-driver<\/strong>&nbsp;repository from AWS GitHub:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone https:\/\/github.com\/kubernetes-sigs\/aws-ebs-csi-driver.git<\/code><\/pre>\n\n\n\n<p id=\"bf67\">2. Change your working directory to the folder that contains the Amazon EBS driver test files:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd aws-ebs-csi-driver\/examples\/kubernetes\/dynamic-provisioning\/<\/code><\/pre>\n\n\n\n<p id=\"0335\">3. Create the Kubernetes resources required for testing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f manifests\/<\/code><\/pre>\n\n\n\n<p id=\"639b\">By this we will get one pod.yaml , storageclass.yaml and claim.yaml file and from this execution a storage class, persistent volume claim(PVC) and a pod will get create. In pod.yaml file a persistent volume claim(PVC) is referenced and EBS volume is provisioned only when the pod is created.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*uMPuDCfM9gYI-_Wf9tfcpw.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"fcae\">4.Describe the&nbsp;<strong>ebs-sc<\/strong>&nbsp;storage class:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl describe storageclass ebs-sc<\/code><\/pre>\n\n\n\n<p id=\"163f\">5. Watch the pods in the default namespace and wait for the&nbsp;<strong>app<\/strong>&nbsp;pod\u2019s status to change to&nbsp;<strong>Running<\/strong>. For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get pods --watch<\/code><\/pre>\n\n\n\n<p id=\"b671\">6. View the persistent volume created because of the pod that references the PVC:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get pv<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*344LX-QInsYmqKdyuBShcg.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"fbff\">7. View information about the persistent volume:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl describe pv your_pv_name<\/code><\/pre>\n\n\n\n<p id=\"f13d\"><strong>Note:<\/strong>&nbsp;Replace&nbsp;<strong>your_pv_name<\/strong>&nbsp;with the name of the persistent volume returned from the preceding step 6. The value of the&nbsp;<strong>Source.VolumeHandle<\/strong>&nbsp;property in the output is the ID of the physical Amazon EBS volume created in your account.<\/p>\n\n\n\n<p id=\"5bc0\">8. Verify that the pod is writing data to the volume:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl exec -it app -- cat \/data\/out.txt<\/pre>\n\n\n\n<p id=\"193c\"><strong>Note:<\/strong>&nbsp;The command output displays the current date and time stored in the&nbsp;<strong>\/data\/out.txt<\/strong>&nbsp;file. The file includes the day, month, date, and time.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ef04\">Testing of EBS<\/h3>\n\n\n\n<p id=\"7982\">Now lets test our setup and see how the Persistent Volume works when using EBS as Storage.<\/p>\n\n\n\n<p id=\"de72\"><strong>Case1<\/strong>: If two pods are running on a single node with \u201c<strong>ReadWriteOnce<\/strong>\u201d access mode, then both of the pods can access the their data.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it app1 \/bin\/bash<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*RH7saOz9QJ_4fC9kcTLUmg.png\" alt=\"\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it app2 \/bin\/bash<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*paCugqrSaNq99Tn088y1Gw.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"1d95\"><strong>Case2&nbsp;<\/strong>\u2014 If we try to create Persistent Volume with \u201c<strong>ReadWriteMany<\/strong>\u201d access mode then PV creation will fail.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*3Lyb-mIKqpVsustthAgXjQ.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"324b\"><strong>Case3<\/strong>: If I take two pods running in different nodes with access mode \u201cReadWriteOnce\u201d then both of the pods cannot access their data..at a time only one pod can Read Write and other one can ReadOnly.<\/p>\n\n\n\n<p id=\"fa90\"><strong>Result:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it app1 \/bin\/bash<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*_0Q8F98kmImZTejnRKH7Zg.png\" alt=\"\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it app2 \/bin\/bash<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*l--0dLUXB1u9B8gReSMjCQ.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"a397\">As we can see above, we cannot mount EBS as persistent volume in AWS EKS with multiple pods running in different nodes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"74e5\">Setting up EFS as Persistent Volume in AWS EKS<\/h3>\n\n\n\n<p id=\"4115\">Before deploying the CSI driver, create an IAM role that allows the CSI driver\u2019s service account to make calls to AWS APIs on your behalf.<\/p>\n\n\n\n<ol>\n<li>Download the IAM policy document from GitHub:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -o iam-policy-example.json https:\/\/raw.githubusercontent.com\/kubernetes-sigs\/aws-efs-csi-driver\/v1.2.0\/docs\/iam-policy-example.json<\/code><\/pre>\n\n\n\n<p id=\"d8e5\">2. Create an IAM policy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws iam create-policy \\<br>    --policy-name AmazonEKS_EFS_CSI_Driver_Policy \\<br>    --policy-document file:\/\/iam-policy-example.json<\/code><\/pre>\n\n\n\n<p id=\"086f\">3. Annotate the Kubernetes service account with the IAM role ARN and the IAM role with the Kubernetes service account name. For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws eks describe-cluster --name your_cluster_name --query \"cluster.identity.oidc.issuer\" --output text<\/code><\/pre>\n\n\n\n<p id=\"de7f\"><strong>Note:<\/strong>&nbsp;In step 3, replace&nbsp;<strong>your_cluster_name<\/strong>&nbsp;with your cluster name.<\/p>\n\n\n\n<p id=\"5705\">4. Create the following IAM trust policy, and then grant the&nbsp;<strong>AssumeRoleWithWebIdentity<\/strong>&nbsp;action to your Kubernetes service account. For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat &lt;&lt;EOF &gt; trust-policy.json<br>{<br>  \"Version\": \"2012-10-17\",<br>  \"Statement\": &#91;<br>    {<br>      \"Effect\": \"Allow\",<br>      \"Principal\": {<br>        \"Federated\": \"arn:aws:iam::YOUR_AWS_ACCOUNT_ID:oidc-provider\/oidc.eks.YOUR_AWS_REGION.amazonaws.com\/id\/&lt;XXXXXXXXXX45D83924220DC4815XXXXX&gt;\"<br>      },<br>      \"Action\": \"sts:AssumeRoleWithWebIdentity\",<br>      \"Condition\": {<br>        \"StringEquals\": {<br>          \"oidc.eks.YOUR_AWS_REGION.amazonaws.com\/id\/&lt;XXXXXXXXXX45D83924220DC4815XXXXX&gt;:sub\": \"system:serviceaccount:kube-system:efs-csi-controller-sa\"<br>        }<br>      }<br>    }<br>  ]<br>}<br>EOF<\/code><\/pre>\n\n\n\n<p id=\"135c\"><strong>Note:<\/strong>&nbsp;In step 4, replace&nbsp;<strong>YOUR_AWS_ACCOUNT_ID<\/strong>&nbsp;with your account ID. Replace&nbsp;<strong>YOUR_AWS_REGION<\/strong>&nbsp;with your Region. Replace&nbsp;<strong>XXXXXXXXXX45D83924220DC4815XXXXX<\/strong>&nbsp;with the value returned in step 3.<\/p>\n\n\n\n<p id=\"2a61\">5. Create an IAM role<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws iam create-role \\<br>  --role-name AmazonEKS_EFS_CSI_DriverRole \\<br>  --assume-role-policy-document file:\/\/\"trust-policy.json\"<\/code><\/pre>\n\n\n\n<p id=\"9e82\">6. Attach your new IAM policy to the role.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws iam attach-role-policy \\<br>  --policy-arn arn:aws:iam::&lt;AWS_ACCOUNT_ID&gt;:policy\/AmazonEKS_EFS_CSI_Driver_Policy \\<br>  --role-name AmazonEKS_EFS_CSI_DriverRole<\/code><\/pre>\n\n\n\n<p id=\"14d1\">7. Install the driver using images stored in the public Amazon ECR registry by downloading the manifest:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl kustomize \"github.com\/kubernetes-sigs\/aws-efs-csi-driver\/deploy\/kubernetes\/overlays\/stable\/?ref=release-1.3\" &gt; public-ecr-driver.yaml<\/code><\/pre>\n\n\n\n<p id=\"e0e8\">8. Edit the file \u2018public-ecr-driver.yaml\u2019 and annotate \u2018efs-csi-controller-sa\u2019 Kubernetes service account section with the ARN of the IAM role that you created:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apiVersion: v1<br>kind: ServiceAccount<br>metadata:<br>  labels:<br>    app.kubernetes.io\/name: aws-efs-csi-driver<br>  annotations:<br>    eks.amazonaws.com\/role-arn: arn:aws:iam::&lt;accountid&gt;:role\/AmazonEKS_EFS_CSI_DriverRole<br>  name: efs-csi-controller-sa<br>  namespace: kube-system<\/code><\/pre>\n\n\n\n<p id=\"82fe\">Deploy the Amazon EFS CSI driver:<\/p>\n\n\n\n<p id=\"21d2\">The Amazon EFS CSI driver allows multiple pods to write to a volume at the same time with the&nbsp;<strong>ReadWriteMany<\/strong>&nbsp;mode.<\/p>\n\n\n\n<ol>\n<li>To deploy the Amazon EFS CSI driver, apply the manifest:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f public-ecr-driver.yaml<\/code><\/pre>\n\n\n\n<p id=\"ad9d\">2. If your cluster contains only AWS Fargate pods (no nodes), then deploy the driver with the following command (all Regions):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f https:\/\/raw.githubusercontent.com\/kubernetes-sigs\/aws-efs-csi-driver\/master\/deploy\/kubernetes\/base\/csidriver.yaml<\/code><\/pre>\n\n\n\n<p id=\"1b8b\">3. Get the VPC ID for your Amazon EKS cluster:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws eks describe-cluster --name your_cluster_name --query \"cluster.resourcesVpcConfig.vpcId\" --output text<\/code><\/pre>\n\n\n\n<p id=\"8cf8\"><strong>Note:<\/strong>&nbsp;In step 3, replace&nbsp;<strong>your_cluster_name<\/strong>&nbsp;with your cluster name.<\/p>\n\n\n\n<p id=\"609e\">4. Get the CIDR range for your VPC cluster:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws ec2 describe-vpcs --vpc-ids YOUR_VPC_ID --query \"Vpcs&#91;].CidrBlock\" --output text<\/code><\/pre>\n\n\n\n<p id=\"b770\"><strong>Note:<\/strong>&nbsp;In step 4, replace the&nbsp;<strong>YOUR_VPC_ID<\/strong>&nbsp;with the VPC ID from the preceding step 3.<\/p>\n\n\n\n<p id=\"aed0\">5. Create a security group that allows inbound network file system (NFS) traffic for your Amazon EFS mount points:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws ec2 create-security-group --description efs-test-sg --group-name efs-sg --vpc-id YOUR_VPC_ID<\/code><\/pre>\n\n\n\n<p id=\"99a8\"><strong>Note:<\/strong>&nbsp;Replace&nbsp;<strong>YOUR_VPC_ID<\/strong>&nbsp;with the output from the preceding step 3. Save the&nbsp;<strong>GroupId<\/strong>&nbsp;for later.<\/p>\n\n\n\n<p id=\"3ede\">6. Add an NFS inbound rule so that resources in your VPC can communicate with your Amazon EFS file system:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws ec2 authorize-security-group-ingress --group-id sg-xxx --protocol tcp --port 2049 --cidr YOUR_VPC_CIDR<\/code><\/pre>\n\n\n\n<p id=\"302b\"><strong>Note:<\/strong>&nbsp;Replace&nbsp;<strong>YOUR_VPC_CIDR<\/strong>&nbsp;with the output from the preceding step 4. Replace&nbsp;<strong>sg-xxx<\/strong>&nbsp;with the security group ID from the preceding step 5.<\/p>\n\n\n\n<p id=\"e064\">7. Create an Amazon EFS file system for your Amazon EKS cluster:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws efs create-file-system --creation-token eks-efs<\/code><\/pre>\n\n\n\n<p id=\"eb01\"><strong>Note:<\/strong>&nbsp;Save the&nbsp;<strong>FileSystemId<\/strong>&nbsp;for later use.<\/p>\n\n\n\n<p id=\"91a1\">8. To create a mount target for Amazon EFS, run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws efs create-mount-target --file-system-id FileSystemId --subnet-id SubnetID --security-group sg-xxx<\/code><\/pre>\n\n\n\n<p id=\"5779\"><strong>Important:<\/strong>&nbsp;Be sure to run the command for all the Availability Zones with the&nbsp;<strong>SubnetID<\/strong>&nbsp;in the Availability Zone where your worker nodes are running. Replace&nbsp;<strong>FileSystemId<\/strong>&nbsp;with the output of the preceding step 7 (where you created the Amazon EFS file system). Replace&nbsp;<strong>sg-xxx<\/strong>&nbsp;with the output of the preceding step 5 (where you created the security group). Replace&nbsp;<strong>SubnetID<\/strong>&nbsp;with the subnet used by your worker nodes. To create mount targets in multiple subnets, you must run the command in step 8 separately for each subnet ID. It\u2019s a best practice to create a mount target in each Availability Zone where your worker nodes are running.<\/p>\n\n\n\n<p id=\"1b63\"><strong>Note:<\/strong>&nbsp;You can create mount targets for all the Availability Zones where worker nodes are launched. Then, all the Amazon Elastic Compute Cloud (Amazon EC2) instances in the Availability Zone with the mount target can use the file system.<\/p>\n\n\n\n<p id=\"9303\">The Amazon EFS file system and its mount targets are now running and ready to be used by pods in the cluster.<\/p>\n\n\n\n<p id=\"4a03\">Test the Amazon EFS CSI driver:<\/p>\n\n\n\n<p id=\"558c\">You can test the Amazon EFS CSI driver by deploying two pods that write to the same file.<\/p>\n\n\n\n<ol>\n<li>Clone the&nbsp;<strong>aws-efs-csi-driver<\/strong>&nbsp;repository from AWS GitHub:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone https:\/\/github.com\/kubernetes-sigs\/aws-efs-csi-driver.git<\/code><\/pre>\n\n\n\n<p id=\"f83a\">2. Change your working directory to the folder that contains the Amazon EFS CSI driver test files:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd aws-efs-csi-driver\/examples\/kubernetes\/multiple_pods\/<\/code><\/pre>\n\n\n\n<p id=\"3bf1\">3. Retrieve your Amazon EFS file system ID that was created earlier:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws efs describe-file-systems --query \"FileSystems&#91;*].FileSystemId\" --output text<\/code><\/pre>\n\n\n\n<p id=\"8411\"><strong>Note:<\/strong>&nbsp;If the command in step 3 returns more than one result, you can use the Amazon EFS file system ID that you saved earlier.<\/p>\n\n\n\n<p id=\"5de9\">4. In the&nbsp;<strong>specs\/pv.yaml<\/strong>&nbsp;file, replace the&nbsp;<strong>spec.csi.volumeHandle<\/strong>&nbsp;value with your Amazon EFS&nbsp;<strong>FileSystemId<\/strong>&nbsp;from previous steps.<\/p>\n\n\n\n<p id=\"d8a5\">5. Create the Kubernetes resources required for testing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f specs\/<\/code><\/pre>\n\n\n\n<p id=\"8b1d\"><strong>Note:<\/strong>&nbsp;The&nbsp;<strong>kubectl<\/strong>&nbsp;command in the preceding step 5 creates an Amazon EFS storage class, PVC, persistent volume, and two pods (<strong>app1<\/strong>&nbsp;and&nbsp;<strong>app2<\/strong>).<\/p>\n\n\n\n<p id=\"83f8\">6 . List the persistent volumes in the default namespace, and look for a persistent volume with the<\/p>\n\n\n\n<p id=\"37e9\"><strong>default\/efs-claim<\/strong>&nbsp;claim:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get pv -w<\/code><\/pre>\n\n\n\n<p id=\"9004\">7. Describe the persistent volume:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl describe pv efs-pv<\/code><\/pre>\n\n\n\n<p id=\"0502\">8. Test if the two pods are writing data to the file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it app1 -- tail \/data\/out1.txt <br>kubectl exec -it app2 -- tail \/data\/out1.txt<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"04ee\">Testing of EFS<\/h3>\n\n\n\n<p id=\"93c5\">If I take 2 pods with access mode\u201dReadWriteMany\u201d,and both of them running in different nodes and If I have created file in pod1 running in e.g textfile1.txt,textfile2.txt and then it should also be reflected in pod2 and vice versa and If I will write some content in any file e.g textfile1.txt and I insert something like for e.g hello\u2026validated for efs..then all the contents will also show to me when I accessed it from pod2 ..<\/p>\n\n\n\n<p id=\"cbfe\"><strong>Result:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it app3 \/bin\/bash<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*VzY0ZRWxrkN2d6EbvzEKfg.png\" alt=\"\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it app4 \/bin\/bash<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*i6ihro44zkpZY_Pwc1qLhQ.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"fc97\">As we can see that we can successfully mount persistent volume in EFS in ReadWriteMany access mode which works with multiple pods running in different nodes as EBS does not work in this scenario. So, in the case of stateful application that requires ReadWriteMany mode, EFS should be the preferred choice over EBS.<\/p>\n\n\n\n<p id=\"03e0\"><strong>Some of the specific use cases\/benefits of using EFS in Kubernetes Cluster<\/strong><\/p>\n\n\n\n<ol>\n<li><strong>Cross-AZ Redundancy:&nbsp;<\/strong>Since all data written to EFS is available to multiple AWS availability zones, it can help to make Kubernetes applications scalable and highly available. Scaled pods can share the same data in case of dependency on the same data across pods.<\/li>\n\n\n\n<li><strong>Content management system and web server support:<\/strong>&nbsp;EFS is a robust throughput file system capable of enabling content management systems and web serving applications, such as archives, websites, or blogs.<\/li>\n\n\n\n<li><strong>Dynamic Scaling:&nbsp;<\/strong>It is better to choose EFS when it is difficult to estimate the amount of storage the application will use because EFS is built to elastically scale.<\/li>\n<\/ol>\n\n\n\t<div id=\"respond\" class=\"comment-respond wp-block-post-comments-form\">\n\t\t<h3 id=\"reply-title\" class=\"comment-reply-title\">Leave a Reply <small><a rel=\"nofollow\" id=\"cancel-comment-reply-link\" href=\"\/blog\/wp-json\/wp\/v2\/posts\/112#respond\" style=\"display:none;\">Cancel reply<\/a><\/small><\/h3><form action=\"https:\/\/cloudtechner.com\/blog\/wp-comments-post.php\" method=\"post\" id=\"commentform\" class=\"comment-form\"><p class=\"comment-notes\"><span id=\"email-notes\">Your email address will not be published.<\/span> <span class=\"required-field-message\">Required fields are marked <span class=\"required\">*<\/span><\/span><\/p><p class=\"comment-form-comment\"><label for=\"comment\">Comment <span class=\"required\">*<\/span><\/label> <textarea id=\"comment\" name=\"comment\" cols=\"45\" rows=\"8\" maxlength=\"65525\" required=\"required\"><\/textarea><\/p><p class=\"comment-form-author\"><label for=\"author\">Name <span class=\"required\">*<\/span><\/label> <input id=\"author\" name=\"author\" type=\"text\" value=\"\" size=\"30\" maxlength=\"245\" autocomplete=\"name\" required=\"required\" \/><\/p>\n<p class=\"comment-form-email\"><label for=\"email\">Email <span class=\"required\">*<\/span><\/label> <input id=\"email\" name=\"email\" type=\"text\" value=\"\" size=\"30\" maxlength=\"100\" aria-describedby=\"email-notes\" autocomplete=\"email\" required=\"required\" \/><\/p>\n<p class=\"comment-form-url\"><label for=\"url\">Website<\/label> <input id=\"url\" name=\"url\" type=\"text\" value=\"\" size=\"30\" maxlength=\"200\" autocomplete=\"url\" \/><\/p>\n<p class=\"comment-form-cookies-consent\"><input id=\"wp-comment-cookies-consent\" name=\"wp-comment-cookies-consent\" type=\"checkbox\" value=\"yes\" \/> <label for=\"wp-comment-cookies-consent\">Save my name, email, and website in this browser for the next time I comment.<\/label><\/p>\n<p class=\"form-submit\"><span class=\"bloghash-submit-form-button\"><input name=\"submit\" type=\"submit\" id=\"submit\" class=\"submit\" value=\"Post Comment\" \/><\/span> <input type='hidden' name='comment_post_ID' value='112' id='comment_post_ID' \/>\n<input type='hidden' name='comment_parent' id='comment_parent' value='0' \/>\n<\/p><\/form>\t<\/div><!-- #respond -->\n\t\n\n\n<p><a href=\"https:\/\/medium.com\/@neha.chalia?source=post_page-----d16f5f46951e--------------------------------\"><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Author: Neha Chalia, Associate Engineer &#8211; CloudDevOps Kubernetes, also known as k8s, is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. Amazon EKS&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,18,72],"tags":[9,51,10,73],"_links":{"self":[{"href":"https:\/\/cloudtechner.com\/blog\/wp-json\/wp\/v2\/posts\/112"}],"collection":[{"href":"https:\/\/cloudtechner.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudtechner.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudtechner.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudtechner.com\/blog\/wp-json\/wp\/v2\/comments?post=112"}],"version-history":[{"count":2,"href":"https:\/\/cloudtechner.com\/blog\/wp-json\/wp\/v2\/posts\/112\/revisions"}],"predecessor-version":[{"id":150,"href":"https:\/\/cloudtechner.com\/blog\/wp-json\/wp\/v2\/posts\/112\/revisions\/150"}],"wp:attachment":[{"href":"https:\/\/cloudtechner.com\/blog\/wp-json\/wp\/v2\/media?parent=112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudtechner.com\/blog\/wp-json\/wp\/v2\/categories?post=112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudtechner.com\/blog\/wp-json\/wp\/v2\/tags?post=112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}