玩转aws之(二)eks 设置efs(nfs)存储卷pvc

目录

1. 前言

2. 配置步骤

3. 安装csi驱动

3.1 创建iam policy

3.2 安装CFS csi驱动

4. 创建EFS

4.1 创建EFS访问安全组及放通EKS访问

4.2 根据EKS集群创建对应的EFS文件系统

4.3 创建挂载目标

5. 创建存储类

5.1 获取efs id

5.2 创建存储类

6. 创建pvc

7. pod挂载pvc使用

8. 总结  


1. 前言

EKS支持两种持久性存储:

Amazon Elastic Block Store(Amazon EBS):硬盘

Amazon Elastic File System (Amazon EFS):提供简单、无服务器、 set-and-forget 弹性文件系统用于AWS Cloud服务和本地资源,支持网络文件系统版本 4(NFSv4.1 和 NFSv4.0)协议。

使用场景,部署服务多副本,多个pod需共享访问文件,因此通过nfs存储挂载pvc,实现文件共享访问。

2. 配置步骤

3. 安装csi驱动

这里分为两个步骤(授权访问EFS)

  • 创建iam policy和eks serviceaccount
  • EKS安装CFS csi驱动

3.1 创建iam policy

3.1.1 下载 IAM policy json文件

curl -o iam-policy-example.json https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/docs/iam-policy-example.json

3.1.2 创建iam policy

# 策略名可自定义,替换AmazonEKS_EFS_CSI_Driver_Policy 即可
aws iam create-policy 
    --policy-name AmazonEKS_EFS_CSI_Driver_Policy 
    --policy-document file://iam-policy-example.json

3.1.3 创建eks serviceaccount

# 运行下面的命令,以创建 IAM 角色和 Kubernetes 服务账户。它还将策略附加到角色,用 IAM 角色 ARN 对 Kubernetes 服务账户添加注释,并将 Kubernetes 服务账户名称添加到 IAM 角色的信任策略中。请将 my-cluster 替换为您的集群名称,并将 111122223333 替换为您的账户 ID。将 region-code 替换为集群所在的 AWS 区域。如果您的集群位于 AWS GovCloud(美国东部)或 AWS GovCloud(美国西部)AWS 区域,则将 arn:aws: 替换为 arn:aws-us-gov:。
eksctl create iamserviceaccount 
    --cluster my-cluster 
    --namespace kube-system 
    --name efs-csi-controller-sa 
    --attach-policy-arn arn:aws:iam::111122223333:policy/AmazonEKS_EFS_CSI_Driver_Policy 
    --approve 
    --region region-code

3.2 安装CFS csi驱动

helm安装efs csi驱动

helm repo add aws-efs-csi-driver https://kubernetes-sigs.github.io/aws-efs-csi-driver/
helm repo update
# 使用 Helm Chart 安装驱动程序的版本。请将存储库地址替换为集群的容器镜像地址,即集群所在可用区
# 镜像地址参考:https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/add-ons-images.html
helm upgrade -i aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver 
    --namespace kube-system 
    --set image.repository=602401143452.dkr.ecr.region-code.amazonaws.com/eks/aws-efs-csi-driver 
    --set controller.serviceAccount.create=false 
    --set controller.serviceAccount.name=efs-csi-controller-sa

4. 创建EFS

  • 根据EKS集群创建对应的EFS文件系统
  • 创建EFS访问安全组及放通EKS访问
  • 根据集群节点可用区网络创建挂载目标

4.1 创建EFS访问安全组及放通EKS访问

检索EKS集群所在的 VPC ID,并将其存储在变量中,以便在后续步骤中使用。将 my-cluster 替换为您的集群名称

vpc_id=$(aws eks describe-cluster 
    --name my-cluster 
    --query "cluster.resourcesVpcConfig.vpcId" 
    --output text)

检索您的集群的 VPC 的 CIDR 范围,并将其存储在变量中,以便在后续步骤中使用

cidr_range=$(aws ec2 describe-vpcs 
    --vpc-ids $vpc_id 
    --query "Vpcs[].CidrBlock" 
    --output text)

创建一个安全组,将 example values 替换为您自己的值

security_group_id=$(aws ec2 create-security-group 
    --group-name MyEfsSecurityGroup 
    --description "My EFS security group" 
    --vpc-id $vpc_id 
    --output text)

 创建一条入站规则,该入站规则允许来自您的集群 VPC 的 CIDR 的入站 NFS 流量

aws ec2 authorize-security-group-ingress 
    --group-id $security_group_id 
    --protocol tcp 
    --port 2049 
    --cidr $cidr_range

4.2 根据EKS集群创建对应的EFS文件系统

创建文件系统。将 region-code 替换为集群所在的 AWS 区域

file_system_id=$(aws efs create-file-system 
    --region region-code 
    --performance-mode generalPurpose 
    --query 'FileSystemId' 
    --output text)

4.3 创建挂载目标

确定 VPC 中子网的 ID 以及子网所在的可用区

aws ec2 describe-subnets 
    --filters "Name=vpc-id,Values=$vpc_id" 
    --query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' 
    --output table

输出示例如下

|                           DescribeSubnets                          |
+------------------+--------------------+----------------------------+
| AvailabilityZone |     CidrBlock      |         SubnetId           |
+------------------+--------------------+----------------------------+
|  region-codec    |  192.168.128.0/19  |  subnet-EXAMPLE6e421a0e97  |
|  region-codeb    |  192.168.96.0/19   |  subnet-EXAMPLEd0503db0ec  |
|  region-codec    |  192.168.32.0/19   |  subnet-EXAMPLEe2ba886490  |
|  region-codeb    |  192.168.0.0/19    |  subnet-EXAMPLE123c7c5182  |
|  region-codea    |  192.168.160.0/19  |  subnet-EXAMPLE0416ce588p  |
+------------------+--------------------+----------------------------+

根据eks节点所在子网添加挂载目标,节点是多可用区,则每个可用区的子网都将运行一次命令,将 subnet-EXAMPLEe2ba886490 替换为相应的子网 ID

aws efs create-mount-target 
    --file-system-id $file_system_id 
    --subnet-id subnet-EXAMPLEe2ba886490 
    --security-groups $security_group_id

5. 创建存储类

这里使用存储类动态生成pvc的方式

5.1 获取efs id

aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text
# 输出示例如下
fs-582a03f3

5.2 创建存储类

# 下载storageclass.yaml
curl -o storageclass.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml
#编辑文件,将 fileSystemId 的值替换为cfs ID
fileSystemId: fs-582a03f3
# 创建存储类
kubectl apply -f storageclass.yaml

kubectl get sc 
NAME            PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
efs-sc          efs.csi.aws.com         Delete          Immediate              false                  152m

6. 创建pvc

# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: efs-claim
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: efs-sc
  resources:
    requests:
      storage: 5Gi
      
kubectl apply -f pvc.yaml      

7. pod挂载pvc使用

#pod.yaml
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

kubectl apply -f pod.yaml

8. 总结  

efs csi驱动和efs创建、安全组配置须根据步骤一一进行,否则pod挂载pvc使用时,有可能出现问题,如:Stale file handlers for EFS ,Stale file handlers for EFS mounts · Issue #614 · kubernetes-sigs/aws-efs-csi-driver (github.com)

觉得好用就收藏吧~ a~w~s~t~u~i