如何解决 Amazon EKS 中 EBS 卷挂载的问题?

上次更新日期:2022 年 3 月 24 日

我在 Amazon Elastic Kubernetes Service (Amazon EKS) 集群中挂载 Amazon Elastic Block Store (Amazon EBS) 卷时,在我的一组容器(pod)中收到以下错误:

“Timeout expired waiting for volumes to attach or mount for pod”(等待卷为pod 进行附加或挂载的超时已过期)

如何排查此问题?

解决方法

在开始执行以下问题排查步骤之前,请确认您具备以下条件:

  • 您的“ebs-csi-controller-sa”服务账户 IAM 角色所需的 AWS Identity and Access Management (IAM) 权限
  • 有效的 PersistentVolumeClaim (PVC) 与一组容器(pod)存在于相同的命名空间中。
  • 使用树内配置程序“kubernetes.io/aws-ebs”或 Amazon EBS Container Storage Interface (CSI) 驱动程序配置程序“ebs.csi.aws.com”的有效 EBS 存储类定义。

验证 Amazon EBS CSI 驱动程序控制器和节点 pod 是否正在运行

Amazon EBS CSI 驱动程序包括作为部署运行的控制器 pod 和作为守护进程组运行的节点 pod。运行以下命令来验证这些 pod 是否在您的集群中运行:

kubectl get all -l app.kubernetes.io/name=aws-ebs-csi-driver -n kube-system

注意:Windows Worker 节点或 EKS Fargate 不支持 Amazon EBS CSI 驱动程序。

确保已安装的 Amazon EBS CSI 驱动程序版本与集群的 Kubernetes 版本兼容

验证 PVC 在绑定到 EBS 持久卷时是否遇到问题

要验证 PVC 是否遇到问题,请运行以下命令查看事件。在以下示例命令中,将 pvc-namenamespace 替换为适合您环境的正确值。

kubectl describe pvc <pvc-name> -n <namespace>

如果您使用的是动态卷调配,请查看返回的事件以确定卷调配是成功还是失败。您还可以看到 PVC 绑定到的相应持久卷名称,如以下示例所示:

Name:          ebs-claim
Namespace:     default
StorageClass:  ebs-sc
Status:        Bound
Volume:        pvc-5cbd76de-6f15-41e4-9948-2bba2574e205
Annotations:   pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
               volume.beta.kubernetes.io/storage-provisioner: ebs.csi.aws.com
               volume.kubernetes.io/selected-node: ip-10-0-2-57.ec2.internal
. . . . .
. . . . . 
Events:
  Type    Reason                 Age                    From                                                                                      Message
  ----    ------                 ----                   ----                                                                                      -------
. . . . .
  Normal  Provisioning           5m22s                  ebs.csi.aws.com_ebs-csi-controller-57d4cbb9cc-dr9cd_8f0373e8-4e58-4dd0-b83c-da6f9ad5d5ce  External provisioner is provisioning volume for claim "default/ebs-claim"
  Normal  ProvisioningSucceeded  5m18s                  ebs.csi.aws.com_ebs-csi-controller-57d4cbb9cc-dr9cd_8f0373e8-4e58-4dd0-b83c-da6f9ad5d5ce  Successfully provisioned volume pvc-5cbd76de-6f15-41e4-9948-2bba2574e205

如果调配失败,请在事件中找到错误消息。

查看Amazon EBS CSI 控制器 pod 的日志

检查控制器 pod 日志以了解挂载失败的原因。如果卷在创建过程中出现故障,请参阅 ebs-plugin 和 csi-provisioner 日志。运行以下命令以检索 ebs-plugin 容器日志:

kubectl logs deployment/ebs-csi-controller -n kube-system -c ebs-plugin
kubectl logs daemonset/ebs-csi-node -n kube-system -c ebs-plugin

运行以下命令以检索 csi-provisioner 容器日志:

kubectl logs deployment/ebs-csi-controller -n kube-system -c csi-provisioner

如果 EBS 卷无法连接到 pod,请查看 csi-attacher 日志以了解原因。运行以下命令以检索 csi-attacher 容器日志:

kubectl logs deployment/ebs-csi-controller -n kube-system -c csi-attacher

验证 Amazon EBS CSI 驱动程序控制器服务账户是否带有正确的 IAM 角色注释,以及 IAM 角色是否具有所需的权限

PVC 事件或 ebs-csi-controller 日志中未经授权的错误是由以下原因引起的:

1.    运行以下命令以确定 ebs-csi-controller pod 使用的服务账户是否具有正确的注释:

kubectl describe sa ebs-csi-controller-sa -n kube-system

验证是否存在以下注释:

eks\.amazonaws\.com/role-arn"="arn:aws:iam::111122223333:role/AmazonEKS_EBS_CSI_DriverRole

2.    验证集群的 IAM OIDC 提供程序是否已创建,以及 IAM 角色是否具有执行 EBS API 调用所需的权限。此外,请验证 IAM 角色的信任策略是否信任服务账户 ebs-csi-controller-sa

3.    查看您账户的 AWS CloudTrail 日志,以验证是否正在进行 CreateVolume、AttachVolume 和 DetachVolume 调用。同时查看 CloudTrail 日志以确定是哪个主体进行了调用。此信息可帮助您确定服务账户 IAM 角色是在由控制器使用还是由 Worker 节点 IAM 角色使用。

验证持久卷的节点关联性

创建的每个持久卷都具有节点关联性,以限制将持久卷附加到单个可用区内的节点。这是因为 EBS 卷只能连接到在创建它们的同一可用区上运行的 pod 或节点。如果调度到一个可用区节点上的 pod 尝试在另一个可用区中使用 EBS 持久卷,您会收到类似以下内容的错误:

"FailedScheduling: 1 node(s) had volume node affinity conflict".

为避免出现这种情况,请使用 StatefulSets 而不是 Deployment,以便为与 pod 位于同一可用区内的 StatefulSets 的每个 pod 创建一个唯一的 EBS 卷。

您可以通过运行以下命令来验证持久卷的节点关联性。在以下示例命令中,将 persistent-volume-name 替换为您的卷名称。

kubectl describe pv <persistent-volume-name>

注意:请记住,您不能将 EBS 卷挂载到运行在两个不同 Worker 节点上的两个不同的 pod。EBS 卷可以附加到在一个节点上运行的 pod,但不能同时附加到另一个节点。如果您尝试将 EBS 卷附加到不同 Worker 节点上的两个不同 pod,则 pod 会发生故障,并且您会收到类似以下内容的错误:

"Warning FailedAttachVolume 2m38s attachdetach-controller Multi-Attach error for volume "pvc-1cccsdfdc8-fsdf6-43d6-a1a9-ea837hf7h57fa" Volume is already exclusively attached to one node and can't be attached to another"

确保您的 EBS 控制器 pod 可以连接到 EC2 API

如果您在 EBS-CSI-Controller 日志中看到指示连接超时的错误,则说明 EBS CSI 控制器可能未连接到 EC2 API。如果控制器 pod 存在与 EC2 API 的连接问题,则在创建 PVC 时,您会看到类似以下内容的错误:

Warning   ProvisioningFailed       persistentvolumeclaim/storage-volume-1   failed to provision volume with StorageClass "ebs-sc": rpc error: code = DeadlineExceeded desc = context deadline exceeded

要更正此错误,请验证 EBS 控制器 pod 的子网是否可以连接到 EC2 API。如果您使用 HTTP/HTTPS 代理运行私有集群,请验证您的 EBS CSI 控制器 pod 是否配置为使用 HTTP/HTTPS 代理。EBS CSI 驱动程序的 Helm 安装支持设置 HTTP/HTTPS 代理


这篇文章对您有帮助吗?


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