如何排查 Amazon ECR 与 Amazon EKS 共用时的问题?

上次更新日期:2023 年 1 月 17 日

使用 Amazon Elastic Kubernetes Service(Amazon EKS)时,我无法从 Amazon Elastic Container Registry(Amazon ECR)提取映像。

简短描述

您可能出于下列原因之一而无法从 Amazon ECR 提取映像:

  • 您无法与 Amazon ECR 端点通信。
  • 您在 Worker 节点的节点实例角色中没有适当的权限。
  • 您尚未创建接口 VPC 端点。

要解决这些问题,请根据您的使用场景执行以下一种或多种解决方法:

  • 排查 Worker 节点与 Amazon ECR 端点之间的通信问题。
  • 更新 Worker 节点的节点实例角色。
  • 确认您的存储库策略正确。
  • 如果您的 EKS 位于不同的 AWS 账户中,请检查您的存储库策略是否允许访问。
  • 创建接口 VPC 端点。
  • 确认您的 AWS Fargate 执行角色配置正确。

解决方法

排查 Worker 节点与 Amazon ECR 端点之间的通信问题

如果您的 Worker 节点无法与 Amazon ECR 端点通信,则您会收到以下错误消息:

Failed to pull image "ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag": rpc error: code = Unknown desc = 
Error response from daemon: Get https://ACCOUNT.dkr.ecr.REGION.amazonaws.com/v2/: net/http: 
request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

要解决此错误,请确认以下事项:

  • 您的工作线程节点的子网具有到 Internet 的路由。检查与您的子网关联的路由表
  • 与您的工作线程节点关联的安全组允许出站 Internet 流量。
  • 您的网络访问控制列表 (ACL) 的传入和传出规则允许访问 Internet。

更新您的 Worker 节点的实例 IAM 角色

假设您的 Worker 节点的实例 AWS Identity and Access Management(IAM)角色没有从 Amazon ECR 提取映像所需的权限。然后,您会从您的 Amazon EKS 容器组(pod)中收到以下错误:

Warning  Failed     14s (x2 over 28s)  kubelet, ip-000-000-000-000.us-west-2.compute.internalFailed to pull image "ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag": rpc error: code = Unknown desc = Error response from daemon: Get https://ACCOUNT.dkr.ecr.REGION.amazonaws.com/v2/imagename/manifests/tag: no basic auth credentials
Warning  Failed     14s (x2 over 28s)  kubelet, ip-000-000-000-000.us-west-2.compute.internal  Error: ErrImagePull
Normal   BackOff    2s (x2 over 28s)   kubelet, ip-000-000-000-000.us-west-2.compute.internal  Back-off pulling image "ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag"
Warning  Failed     2s (x2 over 28s)   kubelet, ip-000-000-000-000.us-west-2.compute.internal  Error: ImagePullBackOff

要解决此错误,请确认您的 Worker 节点使用 AmazonEC2ContainerRegistryReadOnly AWS Identity and Access Management(IAM)托管策略。或者,使用以下 IAM 权限更新您的工作线程节点的 Amazon Elastic Compute Cloud (Amazon EC2) 实例配置文件

"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:GetLifecyclePolicy",
"ecr:GetLifecyclePolicyPreview",
"ecr:ListTagsForResource",
"ecr:DescribeImageScanFindings"

重要提示:最佳方法是使用 AmazonEC2ContainerRegistryReadOnly 策略而非创建重复策略。

更新后的实例 IAM 角色可为您的 Worker 节点提供访问 Amazon ECR 并通过 kubelet 提取映像的权限。kubelet 负责获取并定期刷新 Amazon ECR 凭证。有关详细信息,请参阅 Kubernetes 映像(来自 Kubernetes 网站)。

确认您的存储库策略正确

存储库策略是 IAM 策略的子集,控制对单个 Amazon ECR 存储库的访问。IAM 策略通常用于申请对整个 Amazon ECR 服务的权限,但是也可以控制对特定资源的访问。

1.    为您的一级账户打开 Amazon ECR 控制台

2.    导航到包含 ECR 存储库的 AWS 区域。

3.    在导航窗格中,选择存储库,然后选择您要检查的存储库。

4.    在导航窗格中,选择 Permissions(权限),然后检查您的存储库是否拥有正确的权限。

此示例策略允许特定 IAM 用户描述存储库以及存储库中的映像:

{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "ECR Repository Policy",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:user/MyUsername"
      },
      "Action": [
        "ecr:DescribeImages",
        "ecr:DescribeRepositories"
      ]
    }
  ]
}

如果您的 EKS 位于不同的 AWS 账户中,请确认您的存储库策略是否允许访问

如果您无权访问其他 AWS 账户中的容器映像,则 kubelet 将失败,并显示以下错误:

Failed to pull image "cross-aws-account-id:.dkr.ecr.REGION.amazonaws.com/repo-name:image-tag": rpc error: code = Unknown desc = Error response from daemon: pull access denied for arn:aws:ecr:REGION:cross-aws-account-id:repository/repo-name, repository does not exist or may require 'docker login': denied: User: arn:aws:sts::<aws-account-containing-eks-cluster>:assumed-role/<node-instance-role-for-worker-node is not authorized to perform: ecr:BatchGetImage on resource: arn:aws:ecr:REGION:cross-aws-account-id:repository/repo-name

以下示例策略允许一个 AWS 账户中的实例 IAM 角色描述并从另一个 AWS 账户的 ECR 存储库中提取容器映像:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/eksctl-cross-account-ecr-access-n-NodeInstanceRole"
      },
      "Action": [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:GetRepositoryPolicy",
        "ecr:DescribeRepositories",
        "ecr:ListImages",
        "ecr:DescribeImages",
        "ecr:BatchGetImage",
        "ecr:GetLifecyclePolicy",
        "ecr:GetLifecyclePolicyPreview",
        "ecr:ListTagsForResource",
        "ecr:DescribeImageScanFindings"
      ],
      "Resource": "*"
    }
  ]
}

注意:在 ECR 策略中使用实例 IAM 角色的 ARN,而不是实例配置文件 ARN。

创建接口 VPC 端点

要从 Amazon ECR 提取映像,您必须配置接口 VPC 端点。请参阅 Amazon ECR 接口 VPC 端点(AWS PrivateLink)为 Amazon ECS 创建 VPC 端点部分。

确认您的 Fargate 容器组(pod)执行角色配置正确

如果您在 Amazon 托管存储库检索映像时,您的 Fargate CoreDNS 容器组(pod)卡在 ImagePullBackOff 状态,则您会收到以下错误消息:

Warning   Failed           27s (x2 over 40s)  kubelet            Failed to pull image "151284513677.dkr.ecr.eu-central-1.amazonaws.com/coredns:latest ": rpc error: code = Unknown desc = failed to pull and unpack image "151284513677.dkr.ecr.eu-central-1.amazonaws.com/coredns:latest ": failed to resolve reference "151284513677.dkr.ecr.eu-central-1.amazonaws.com/coredns:latest ": pulling from host 151284513677.dkr.ecr.eu-central-1.amazonaws.com failed with status code [manifests latest]: 401 Unauthorized

要排查此错误,请确保您已将 Fargate 容器组(pod)执行角色设置为使用 AmazonEKSFargatePodExecutionRolePolicy。确保该角色还附加了类似于以下内容的信任策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:eks:example-region:1111222233334444:fargateprofile/example-cluster/*"
        }
      },
      "Principal": {
        "Service": "eks-fargate-pods.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

注意:

请务必在策略中替换以下内容:

  • example-region 替换为您的 AWS 区域的名称
  • 1111222233334444 替换为账号
  • example-cluster 替换为您的集群名称

这篇文章对您有帮助吗?


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