如何使用 Amazon EKS 中的持久性存储?

上次更新时间:2022 年 5 月 10 日

我想使用 Amazon Elastic Kubernetes Service(Amazon EKS)中的持久性存储。

简短描述

可以通过以下任何一种选项设置 Amazon EKS 中的持久性存储:

要使用这些选项中的一种,完成以下任何一个部分中的步骤:

  • 选项 A:部署并测试 Amazon EBS CSI 驱动程序
  • 选项 B:部署并测试 Amazon EFS CSI 驱动程序

本文中的命令要求 kubectl 版本 1.14 或更高版本。要查看您的 kubectl 版本,请运行以下命令:

kubectl version --client --short

注意:最佳做法是确保安装最新版本的驱动程序。有关更多信息,请参阅 GitHub 存储库中的 Amazon EBS CSI 驱动程序Amazon EFS CSI 驱动程序

解决方法

注意:如果您在运行 AWS Command Line Interface(AWS CLI)命令时收到错误,请确保您使用的是最新的 AWS CLI 版本

在完成任一部分的步骤前,您必须:

1.    安装 AWS CLI

2.    设置 AWS Identity and Access Management (IAM) 权限,以创建并附加策略至 Amazon EKS 工作线程节点角色 CSI Driver Role

3.    创建 Amazon EKS 集群并将 Worker 节点添加到该集群。

4.    您的集群上是否存在现有的 IAM OpenID Connect(OIDC)提供程序。要确定您是否已有集群或要创建集群,请参阅为您的集群创建 IAM OIDC 提供程序

注意:要验证您的 Worker 节点已附加到您的集群,请运行 kubectl get nodes 命令。

选项 A:部署并测试 Amazon EBS CSI 驱动程序

部署 Amazon EBS CSI 驱动程序:

1.    要下载 IAM 策略示例,而且其具有让您的工作线程节点可以创建与修改 Amazon EBS 卷的权限:

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

2.    创建 IAM 策略,命名为 Amazon_EBS_CSI_Driver

aws iam create-policy --policy-name AmazonEKS_EBS_CSI_Driver_Policy --policy-document file://example-iam-policy.json

3.    查看集群的 OIDC 提供商 URL:

aws eks describe-cluster --name your_cluster_name --query "cluster.identity.oidc.issuer" --output text

注意:在步骤 3 中,将 your_cluster_name 替换为您的集群名称。

4.    创建以下 IAM 信任策略文件:

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

注意:在步骤 4 中,将 YOUR_AWS_ACCOUNT_ID 替换为您的账户 ID。将 YOUR_AWS_REGION 替换为您的 AWS 区域。将 XXXXXXXXXX45D83924220DC4815XXXXXXX 替换为步骤 3 中返回的值。

5.    创建 IAM 角色:

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

6.    将新的 IAM 策略附加到角色:

aws iam attach-role-policy \
--policy-arn arn:aws:iam::111122223333:policy/AmazonEKS_EBS_CSI_Driver_Policy \
--role-name AmazonEKS_EBS_CSI_DriverRole

7.    要部署 Amazon EBS CSI 驱动程序,请根据您的区域运行以下命令之一:

除中国区域之外的所有区域:

kubectl apply -k "github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable/?ref=master"

北京和宁夏中国区域:

kubectl apply -k "github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable-cn/?ref=master"

8.    使用您先前所创建的 IAM 角色的 Amazon Resource Name (ARN) 来注释 ebs-csi-Controller-sa Kubernetes 服务账户:

kubectl annotate serviceaccount ebs-csi-controller-sa \
  -n kube-system \
  eks.amazonaws.com/role-arn=arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/AmazonEKS_EBS_CSI_DriverRole

注意:YOUR_AWS_ACCOUNT_ID 替换为您的账户 ID。

9.    删除驱动程序 Pod:

kubectl delete pods \
  -n kube-system \
  -l=app=ebs-csi-controller

注意:将使用分配给角色的 IAM 策略中的 IAM 权限自动重新部署驱动程序 Pod。有关更多信息,请参阅 Amazon EBS CSI 驱动程序

测试 Amazon EBS CSI 驱动程序:

您可以利用使用动态预置的应用程序对 Amazon EBS CSI 驱动程序进行测试。Amazon EBS 卷是按需预置的。

1.    从 AWS GitHub 中克隆 aws-ebs-csi-驱动程序

git clone https://github.com/kubernetes-sigs/aws-ebs-csi-driver.git

2.    将您的工作目录更改为包含 Amazon EBS 驱动程序测试文件的文件夹,请运行以下命令:

cd aws-ebs-csi-driver/examples/kubernetes/dynamic-provisioning/

3.    创建测试所需的 Kubernetes 资源:

kubectl apply -f manifests/

注意:kubectl 命令会创建 StorageClass (来自 Kubernetes 网站)、PersistentVolumeClaim (PVC) (来自 Kubernetes 网站) 和 Pod。Pod 将引用 PVC。仅在创建 Pod 时对 Amazon EBS 卷进行预置。

4.    描述 ebs-sc 存储类:

kubectl describe storageclass ebs-sc

5.    在默认命名空间中观看 Pod 并等待 app Pod 的状态更改为 Running。例如:

kubectl get pods --watch

6.    查看因引用 PVC 的 Pod 而创建的持久性卷:

kubectl get pv

7.    查看有关持久性卷的信息:

kubectl describe pv your_pv_name

注意:pv_name 替换为前述第 6 步中返回的持久性卷的名称。输出中的 Source.VolumeHandle 属性的值为在您的账户中创建的物理 Amazon EBS 卷的 ID。

8.    验证 Pod 是否正在向卷写入数据:

kubectl exec -it app -- cat /data/out.txt

注意:命令输出显示的是存储在/data/out.txt 文件中的当前日期和时间。该文件包括日、月、日期和时间。

选项 B:部署并测试 Amazon EFS CSI 驱动程序

在部署 CSI 驱动程序之前,请创建允许 CSI 驱动程序的服务账户代表您调用 AWS API 的 IAM 角色。

1.    从 GitHub 下载 IAM 策略文档:

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

2.    创建一个 IAM 策略:

aws iam create-policy \
    --policy-name AmazonEKS_EFS_CSI_Driver_Policy \
    --policy-document file://iam-policy-example.json

3.    使用 IAM 角色 ARN 和 IAM 角色为 Kubernetes 服务账户注释 Kubernetes 服务账户名称。例如:

aws eks describe-cluster --name your_cluster_name --query "cluster.identity.oidc.issuer" --output text

注意:在步骤 3 中,将 your_cluster_name 替换为您的集群名称。

4.    创建以下 IAM 信任策略,然后将 AssumeRoleWithWebIdentity 操作授予您的 Kubernetes 服务账户。例如:

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

注意:在步骤 4 中,将 YOUR_AWS_ACCOUNT_ID 替换为您的账户 ID。将 YOUR_AWS_REGION 替换为您的区域。将 XXXXXXXXXX45D83924220DC4815XXXXXXX 替换为步骤 3 中返回的值。

5.    创建 IAM 角色:

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

6.    将新的 IAM 策略附加到角色:

aws iam attach-role-policy \
  --policy-arn arn:aws:iam::<AWS_ACCOUNT_ID>:policy/AmazonEKS_EFS_CSI_Driver_Policy \
  --role-name AmazonEKS_EFS_CSI_DriverRole

7.    创建一个以您所创建 IAM 角色的 ARN 来注释的 Kubernetes 服务账户。例如:

cat << EOF > efs-service-account.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: efs-csi-controller-sa
  namespace: kube-system
  labels:
    app.kubernetes.io/name: aws-efs-csi-driver
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/AmazonEKS_EFS_CSI_DriverRole
EOF

注意:YOUR_AWS_ACCOUNT_ID 替换为您的账户 ID。

8.    应用清单:

kubectl apply -f efs-service-account.yaml

部署 Amazon EFS CSI 驱动程序:

Amazon EFS CSI 驱动程序允许多个 Pod 在 ReadWriteMany 模式中同时写入卷。

1.    要部署 Amazon EFS CSI 驱动程序,请根据您的区域或集群类型运行以下命令之一:

除中国区域之外的所有区域:

kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/ecr/?ref=release-1.1"

北京和宁夏中国区域:

kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/?ref=release-1.1"

如果您的集群只包含 AWS Fargate Pod(没有节点),请使用以下命令(适用于所有区域)部署驱动程序:

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/deploy/kubernetes/base/csidriver.yaml

2.    获取 Amazon EKS 集群的 VPC ID:

aws eks describe-cluster --name your_cluster_name --query "cluster.resourcesVpcConfig.vpcId" --output text

注意:在步骤 2 中,将 your_cluster_name 替换为您的集群名称。

3.    获取 VPC 集群的 CIDR 范围:

aws ec2 describe-vpcs --vpc-ids YOUR_VPC_ID --query "Vpcs[].CidrBlock" --output text

注意:在步骤 3 中,将 YOUR_VPC_ID 替换为前述第 2 步中的 VPC ID。

4.    创建安全组,为您的 Amazon EFS 挂载点允许入站网络文件系统 (NFS) 流量,运行以下命令:

aws ec2 create-security-group --description efs-test-sg --group-name efs-sg --vpc-id YOUR_VPC_ID

注意:YOUR_VPC_ID 替换为前述第 2 步中的输出。保存 GroupId 以待将来使用。

5.    添加 NFS 入站规则,以便 VPC 中的资源可以与 Amazon EFS 文件系统进行通信:

aws ec2 authorize-security-group-ingress --group-id sg-xxx --protocol tcp --port 2049 --cidr YOUR_VPC_CIDR

注意:YOUR_VPC_CIDR 替换为前述第 3 步中的输出。将 sg-xxx 替换为前述第 4 步中的安全组 ID。

6.    为您的 Amazon EKS 集群创建 Amazon EFS 文件系统:

aws efs create-file-system --creation-token eks-efs

注意:保存 FileSystemId 以待将来使用。

7.    要为 Amazon EFS 创建挂载目标,请运行以下命令:

aws efs create-mount-target --file-system-id FileSystemId --subnet-id SubnetID --security-group sg-xxx

重要提示:请务必在工作线程节点所运行的可用区中使用 SubnetID 对所有可用区运行命令。将 FileSystemId 替换为前述第 6 步中(在此步骤中创建了 Amazon EFS 文件系统)的输出。将 sg-xxx替换为前述第 4 步中(在此步骤中创建了安全组)的输出。将 SubnetID 替换为工作线程节点使用的子网。要在多个子网中创建挂载目标,您必须为每个子网 ID 分别运行步骤 7 中的命令。最佳实践是在工作线程节点运行的每个可用区中创建挂载目标。

注意:您可以为工作线程节点启动所在的全部可用区创建挂载目标。之后,具有挂载目标的可用区内的所有 Amazon Elastic Compute Cloud (Amazon EC2) 实例都可以使用文件系统。

该 Amazon EFS 文件系统及其挂载目标现会运行,而且随时可被集群中的 Pod 所使用。

测试 Amazon EFS CSI 驱动程序:

您可以通过部署两个 Pod,写入相同的文件,以测试 Amazon EFS CSI 驱动程序。

1.    从 AWS GitHub 中克隆 aws-efs-csi-driver 存储库:

git clone https://github.com/kubernetes-sigs/aws-efs-csi-driver.git

2.    将您的工作目录更改为包含 Amazon EFS CSI 驱动程序测试文件的文件夹,请运行以下命令:

cd aws-efs-csi-driver/examples/kubernetes/multiple_pods/

3.    检索之前创建的 Amazon EFS 文件系统 ID:

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

注意:若第 3 步中的命令返回了多个结果,您可以使用之前保存的 Amazon EFS 文件系统 ID。

4.    在 specs/pv.yaml 文件中,将 spec.csi.volumeHandle 值替换为之前步骤中的 Amazon EFS FileSystemId

5.    创建测试所需的 Kubernetes 资源:

kubectl apply -f specs/

注意:前述第 5 步中的 kubectl 命令会创建 Amazon EFS 存储类、PVC、持久性卷和 2 个 Pod(app1app2)。

6.    在默认命名空间中列出持久卷,然后使用 default/efs-claim 申请来查找一个持久卷:

kubectl get pv -w

7.    描述持久性卷:

kubectl describe pv efs-pv

8.    测试两个 pod 是否正在将数据写入文件:

kubectl exec -it app1 -- tail /data/out1.txt 
kubectl exec -it app2 -- tail /data/out1.txt

等待大约一分钟。该输出显示由两个 Pod 写入到 /data/out1.txt 的当前日期。


这篇文章对您有帮助吗?


您是否需要账单或技术支持?