如何排查使用 Amazon EFS CSI 控制器动态创建 Kubernetes 持久卷对象时出现的问题?

3 分钟阅读
0

我在创建使用持久卷声明的 Amazon Elastic Kubernetes Service(Amazon EKS)容器组(pod)时收到错误。持久卷动态创建,处于“待处理”状态。

解决方法

Amazon Elastic File System(Amazon EFS)CSI 驱动程序使用服务账户的 AWS Identity and Access Management(IAM)角色(IRSA)功能。此功能要求正确配置各种组件,包括 OpenID Connect(OIDC)提供程序、IAM 角色和访问权限。这些组件使用 IAM 角色策略和 Kubernetes 服务账户进行配置。根据收到的错误,尝试以下问题排查步骤。

**注意:**如果在运行 AWS CLI 命令时遇到错误,请确保您使用的是最新版本的 AWS CLI

storageclass.storage.k8s.io "<STORAGE_CLASS_NAME>" not found

此错误表明由您的 PersistentVolumeClaim 对象定义中的参数 storageClassName 引用的存储类不存在且必须创建。

要解决此错误,请执行以下操作:

1.    创建 Kubernetes 存储类对象。

2.    下载 Amazon EFS 的存储类清单:

curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml

3.    编辑下载的文件。找到以下语句,然后将 fileSystemId 的值替换为您的文件系统 ID。

fileSystemId: fs-582a03f344f0fc633 # Replace the filesystem id

4.    部署存储类:

kubectl apply -f storageclass.yaml

failed to provision volume with StorageClass "<STORAGE_CLASS_NAME>": rpc error: code = InvalidArgument desc = File System does not exist: Resource was not found

此错误表明存储类对象引用的 fileSystemId 要么在区域中不存在,要么不正确。

要解决此错误,请验证存储类中引用的 Amazon EFS 文件系统是否正确以及是否存在于区域中:

kubectl get storageclass `kubectl get pvc ${PVC_NAME} -o jsonpath='{.spec.storageClassName}'` -o jsonpath='{.parameters.fileSystemId}'

**注意:**请务必将 PVC_NAME 替换为您的 PersistentVolumeClaim 的名称。

如果返回的 EFS 文件系统(fileSystemId)在区域中不存在,则删除 Kubernetes 存储类对象。然后,为 fileSystemId 字段添加正确的文件系统 ID,再次创建。

failed to provision volume with StorageClass "<STORAGE_CLASS_NAME>": rpc error: code = Internal desc = Failed to fetch File System info: Describe File System failed: WebIdentityErr: failed to retrieve credentials caused by: InvalidIdentityToken: No OpenIDConnect provider found in your account for https://oidc.eks.<REGION-CODE>.amazonaws.com/id/<OIDC ID> status code: 400, request id: <REQUEST ID>

此错误表明没有在 IAM 中为 Amazon EKS 集群创建提供的 IAM OIDC 身份。

1.    检索您的集群的 OIDC 提供程序 ID 并将其存储在变量中:

oidc_id=$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5); echo $oidc_id

**注意:**请务必将 CLUSTER_NAME 替换为您的集群的名称。

2.    为您的集群创建 IAM OIDC 身份提供程序:

eksctl utils associate-iam-oidc-provider --cluster ${CLUSTER_NAME} –-approve

**注意:**如果您无法使用 eksctl 实用工具创建 IAM OIDC 提供程序,则使用 AWS 管理控制台

failed to provision volume with StorageClass "<STORAGE_CLASS_NAME>": rpc error: code = Unauthenticated desc = Access Denied.请确保您拥有正确的 AWS 权限:访问被拒绝

此错误表明 IRSA 没有所需的访问权限(示例:elasticfilesystem:CreateAccessPoint)。

1.    检索 EFS CSI 控制器部署使用的服务账户:

kubectl get deploy -n kube-system efs-csi-controller -o=jsonpath={'.spec.template.spec.serviceAccount'}

2.    找到服务账户使用的 IAM 角色:

kubectl get sa -n kube-system ${SERVICE_ACCOUNT} -oyaml -o=jsonpath={'.metadata.annotations.eks\.amazonaws\.com/role-arn'}

3.    从 GitHub 下载 IAM policy 文档:

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

4.    如果 IAM policy 不存在,则进行创建:

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

5.    将此 IAM policy 附加到您之前检索的 IAM 角色,并通过 EFS CSI 控制器部署使用的服务账户进行注释。

aws iam attach-role-policy --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AmazonEKS_EFS_CSI_Driver_Policy --role-name ${IAM_ROLE_NAME}

注意:

您可以通过运行以下命令来检索账户 ID:

aws sts get-caller-identity --query "Account" --output text

您可以通过运行以下命令来检索 IAM 角色:

echo $IAM_ROLE_ARN | cut -d "/" -f2

Failed to fetch File System info: Describe File System failed: WebIdentityErr: failed to retrieve credentials caused by: AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity

您之所以收到此错误,是因为以下原因之一:

  • 未提供 IAM 权限 sts:AssumeRoleWithWebIdentity
  • 附加到 IAM 角色的信任关系文档中列出的 IAM OIDC 身份提供程序不正确。
  • 提到的 Kubernetes 服务账户(例如:system:serviceaccount:kube-system:efs-csi-controller-sa)与 EFS CSI 控制器部署使用的服务账户不匹配。

要排查此错误,请执行以下操作:

1.    检索您的集群的 OIDC 提供程序 ID 并将其存储在变量中。

oidc_id=$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5); echo ${oidc_id}

请务必将 CLUSTER_NAME 替换为您的集群的名称。

2.    验证 AWS 账户中是否存在 IAM OIDC 提供程序 ID:

aws iam list-open-id-connect-providers | grep $oidc_id | cut -d "/" -f4

3.    查看附加到 IAM 角色的信任关系文档:

aws iam get-role --role-name ${IAM_ROLE_NAME} --output json --query "Role.AssumeRolePolicyDocument"

验证是否允许操作 sts:AssumeRoleWithWebIdentity。此外,确认 IAM OIDC ID 与上述命令返回的 OIDC ID 匹配。

注意:

您可以通过运行以下命令来检索 IAM 角色:

echo $IAM_ROLE_ARN | cut -d "/" -f2

相关信息

服务账户的 IAM 角色

Amazon EFS CSI 驱动程序

AWS 官方
AWS 官方已更新 1 年前