先决条件

安装Amazon CLI

##amd64 架构安装
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

##arm64 架构安装
curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

安装 eksctl

eksctl 安装文档:https://docs.amazonaws.cn/eks/latest/userguide/eksctl.html

curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
eksctl version

配置 Amazon CLI

##正确填写Access Key信息,并确保有EKS/EFS/安全组 相关操作权限
aws configure

Amazon EFS CSI 驱动程序

官方文档:https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/efs-csi.html

1.创建 IAM policy

创建允许 CSI 驱动程序的服务账户代表您调用 AWS API 的 IAM policy
##下载 IAM policy 文档
curl -o iam-policy-example.json https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/docs/iam-policy-example.json

##创建策略
aws iam create-policy \
    --policy-name Policy_EKS_EFS_CSI_Driver \
    --policy-document file://iam-policy-example.json

2.创建 IAM 角色并向其附加此 IAM policy

查看集群的 OIDC 提供商 URL
##将 my-cluster 替换为您的集群名称。如果命令的输出为 None,请查看先决条件。
aws eks describe-cluster --name my-cluster \
--query "cluster.identity.oidc.issuer" \
--output text
创建 IAM 角色

向 Kubernetes 服务账户授予 AssumeRoleWithWebIdentity 操作权限

##将 111122223333 替换为您的账户 ID;
##将 EXAMPLED539D4633E53DE1B71EXAMPLE 和 region-code 替换为在上一步中返回的值;
##如果您的集群位于 AWS GovCloud(美国东部)或 AWS GovCloud(美国东部)AWS 区域,请将arn:aws-cn: 替换为 arn:aws-us-gov:
##

cat << EOF > trust-policy.json 
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws-cn:iam::111122223333:oidc-provider/oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:efs-csi-controller-sa"
        }
      }
    }
  ]
}
EOF

创建角色:Role_EKS_EFS_CSI_Driver

aws iam create-role \
  --role-name Role_EKS_EFS_CSI_Driver \
  --assume-role-policy-document file://"trust-policy.json"

向角色附加 IAM policy

##请将 111122223333 替换为您的账户 ID;
##如果您的集群位于 AWS GovCloud(美国东部)或 AWS GovCloud(美国东部)AWS 区域,请将arn:aws-cn: 替换为 arn:aws-us-gov:
##
aws iam attach-role-policy \
  --policy-arn arn:aws-cn:iam::111122223333:policy/Policy_EKS_EFS_CSI_Driver\
  --role-name Role_EKS_EFS_CSI_Driver

创建一个使用您创建的 IAM 角色的 ARN 进行注释的 Kubernetes 服务账户

##将 111122223333 替换为您的账户 ID
##如果您的集群位于 AWS GovCloud(美国东部)或 AWS GovCloud(美国东部)AWS 区域,请将arn:aws-cn: 替换为 arn:aws-us-gov:
##
cat << EOF > efs-service-account.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/name: aws-efs-csi-driver
  name: efs-csi-controller-sa
  namespace: kube-system
  annotations:
    eks.amazonaws.com/role-arn: arn:aws-cn:iam::111122223333:role/Role_EKS_EFS_CSI_Driver
EOF

在集群上创建 Kubernetes 服务账户

kubectl apply -f efs-service-account.yaml

验证结果

kubectl get ServiceAccount/efs-csi-controller-sa -n kube-system

2.安装Amazon EFS驱动程序

此过程需要 Helm V3 或更高版本。要安装或升级 Helm

安装helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
添加chart仓库
helm repo add aws-efs-csi-driver https://kubernetes-sigs.github.io/aws-efs-csi-driver/
##更新存储库。
helm repo update
使用 Helm Chart 安装驱动程序
  • efs-csi-controller
  • efs-csi-node
##请将存储库地址替换为集群的容器镜像地址;region-code替换为你仓库的区域。
helm upgrade -i --timeout 20m aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver --wait --wait-for-jobs --debug\
    --namespace kube-system \
    --set controller.serviceAccount.create=false \
    --set controller.serviceAccount.name=efs-csi-controller-sa
验证安装结果(状态是否为Running)
kubectl get pod -n kube-system -l "app.kubernetes.io/name=aws-efs-csi-driver,app.kubernetes.io/instance=aws-efs-csi-driver"

输出结果如下:

NAME                                 READY   STATUS    RESTARTS   AGE
efs-csi-controller-8cd49f9f6-wssmf   3/3     Running   0          2m16s
efs-csi-controller-8cd49f9f6-xjfxd   3/3     Running   0          2m16s
efs-csi-node-2wk62                   3/3     Running   0          2m16s
efs-csi-node-ktnl4                   3/3     Running   0          2m16s
efs-csi-node-mh7cm                   3/3     Running   0          2m16s

创建 EFS 安全组

也可在平台手动创建。

官方文档:https://docs.amazonaws.cn/efs/latest/ug/mounting-fs.html

1.检索您的集群所在的 VPC ID。

  • 可在EKS平台自行查看,或者使用以下命令获取;
  • 将 my-cluster 替换为您的集群名称;
##将VPC ID存储在变量中,以便在后续步骤中使用。
vpc_id=$(aws eks describe-cluster \
    --name my-cluster \
    --query "cluster.resourcesVpcConfig.vpcId" \
    --output text)

##检查变量
echo ${vpc_id}

2.检索您的集群的 VPC 的 CIDR 范围

##将CIDR存储在变量中,以便在后续步骤中使用。
cidr_range=$(aws ec2 describe-vpcs \
    --vpc-ids $vpc_id \
    --query "Vpcs[].CidrBlock" \
    --output text)

##检查变量
echo ${cidr_range}

3.创建一个安全组

  • 该安全组包含一条允许您的 Amazon EFS 挂载点的入站 NFS 流量的入站规则;
  • 要进一步限制对文件系统的访问,您可以将 CIDR 用于子网,而不是 VPC;
##创建安全组。将 example values 替换为您自己的值;
security_group_id=$(aws ec2 create-security-group \
    --group-name FW-EFS-TEST \
    --description "My EFS security group" \
    --vpc-id $vpc_id \
    --output text)

##查看创建好的安全组id
echo ${security_group_id}

##创建一条入站规则,该入站规则允许来自您的集群 VPC 的 CIDR 的入站 NFS 流量;
aws ec2 authorize-security-group-ingress \
    --group-id $security_group_id \
    --protocol tcp \
    --port 2049 \
    --cidr $cidr_range

为 EKS 集群创建EFS 文件系统

1.创建文件系统

##region替换为您的集群所在的 AWS 区域
file_system_id=$(aws efs create-file-system \
    --region cn-north-1 \
    --performance-mode generalPurpose \
    --tags Key=Name,Value=EKS-EFS-TEST \
    --query 'FileSystemId' \
    --output text)

##查看创建好的EFS id
echo ${file_system_id}

2.创建挂载目标

##查看您的集群节点的 IP 地址。
kubectl get nodes -owide |awk '{print $1,$6}'

##确定 VPC 中子网的 ID 以及子网所在的可用区。
aws ec2 describe-subnets \
    --filters "Name=vpc-id,Values=$vpc_id" \
    --query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' \
    --output table

为节点所在的子网添加挂载目标。从前两个步骤的输出来看,集群node使用 IP 地址位于 ID 为 subnet-EXAMPLEe2ba886490 的子网的 CidrBlock 内。

##以下命令会为节点所在的子网创建一个挂载目标(如果集群中有很多节点,那么您应该替换相应的子网 ID后多次运行命令)
aws efs create-mount-target \
    --file-system-id $file_system_id \
    --subnet-id subnet-EXAMPLEe2ba886490 \
    --security-groups $security_group_id
  • 平台查看创建结果image.png

部署使用控制器所创建的持久性卷的示例应用程序

您必须使用 1.2x 版或更高版本的 Amazon EFS CSI 驱动程序,该驱动程序需要 1.17 或更高版本的集群。

1.为 EFS 创建存储类

为 EFS 创建存储类。有关所有参数和配置选项,请参阅 GitHub 上的 Amazon EFS CSI 驱动程序

##查看EFS 文件系统 ID,${file_system_id} 为前面创建EFS生成的变量
aws efs describe-file-systems --query "FileSystems[*].FileSystemId" |grep "${file_system_id}"

##下载 Amazon EFS 的 StorageClass 清单。
curl -o aws-efs-storageclass.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml

##编辑 yaml文件
kind: StorageClass
apiVersion: storage.k8s.io/v1
allowVolumeExpansion: true    ##添加此行
volumeBindingMode: WaitForFirstConsumer   ##修改卷绑定模式
metadata:
  name: efs-qqq-test
provisioner: efs.csi.aws.com
parameters:
  provisioningMode: efs-ap
  fileSystemId: fs-582a03f3  ##替换为你的文件系统 ID
  directoryPerms: "700"
  gidRangeStart: "1000" # optional
  gidRangeEnd: "2000" # optional
  basePath: "/dynamic_provisioning" # optional

##部署存储类
kubectl apply -f aws-efs-storageclass.yaml

##查看存储类
kubectl get storageclass

2.测试EFS 自动预置

部署pod和PVC
##下载一个清单,该清单将部署一个 Pod 和一个 PersistentVolumeClaim。
curl -o pod-efs.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/pod.yaml

##存储类名使用为上面配置的名字
sed -i 's/storageClassName: efs-sc/storageClassName: efs-qqq-test/g' pod-efs.yaml

##使用示例应用程序和 Pod 使用的 PersistentVolumeClaim 来部署 Pod。
kubectl apply -f pod-efs.yaml
验PV
##确定运行控制器的 Pod 的名称。
kubectl get pods -n kube-system | grep efs-csi-controller
#####输出示例如下:
efs-csi-controller-8cd49f9f6-wssmf              3/3     Running   0               13m
efs-csi-controller-8cd49f9f6-xjfxd              3/3     Running   0               13m

##几秒钟后,观察输出日志
kubectl logs --tail=10 -f deployment/efs-csi-controller -n kube-system -c csi-provisioner

kubectl logs --tail 10 -f efs-csi-controller-8cd49f9f6-wssmf \
    -n kube-system \
    -c csi-provisioner

##查看创建的 PersistentVolumeClaim 的详细信息
kubectl describe pvc/efs-claim

##确认已创建PVC状态为 Bound 至 PersistentVolumeClaim 的持久性卷
kubectl get pv

##请查应用程序容器的状态,直到 STATUS 变成 Running
kubectl get pods -o wide

##确认数据已写入到卷。
kubectl exec efs-app -- bash -c "cat data/out"

##检查无问题后删除pod
kubectl delete -f pod-efs.yaml