如何解决 Amazon ECR 与 Amazon EKS 共用时的问题?

3 分钟阅读
0

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

概述

由于以下任一原因,您无法从 Amazon ECR 拉取映像:

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

根据您的用例,使用以下一个或多个解决方案。

解决方案

解决 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)

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

  • 您的 Worker 节点的子网有一条路由通往互联网。检查与您的子网关联的路由表
  • 与您的 Worker 节点关联的安全组允许出站互联网流量。
  • 您的网络访问控制列表 (ACL) 的入口和出口规则允许访问互联网。

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

在下列示例中,您的 Worker 节点的实例 AWS Identity and Access Management(AWS IAM)角色没有从 Amazon ECR 拉取映像所需的权限。在这种情况下,您的 Amazon EKS 容器组(pod)就会出现以下错误:

Warning  Failed     14s (x2 over 28s)  kubelet, ip-000-000-000-000.us-west-2.compute.internal  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/imagename/manifests/tag: no basic auth credentialsWarning  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 权限更新您的 Worker 节点的 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 网站上的 Images

确认您的存储库策略正确

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

  1. 打开您的主账户的 Amazon ECR 控制台
  2. 导航到包含 ECR 存储库的 AWS 区域。
  3. 在导航窗格上,选择存储库。然后,选择要检查的存储库。
  4. 在导航窗格上,选择权限。然后,检查您的仓库是否具有正确的权限。
    此示例策略允许特定 IAM 用户描述存储库和存储库中的映像:
    {  
      "Version": "2012-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 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",
      "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": "*"
    }
  ]
}

**注意:**将 example_region 替换为您的 AWS 区域的名称。将 1111222233334444 替换为账号,将 example-cluster 替换为您的集群名称。

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