如何解决 Amazon ECS 中的“CannotPullContainerError: 您已达到拉取速率限制”错误?

3 分钟阅读
0

当我试图从 Docker Hub 拉取映像时,我的 Amazon Elastic Container Service(Amazon ECS)任务失败,并出现以下错误: “CannotPullContainerError:检查映像已重试 5 次:httpReaderSeeker:无法打开:意外状态代码 https://registry-1.docker.io/v2/manifests/sha256:2bb501e6429 请求太多 - 服务器消息:toomanyrequests: 您已达到拉取速率限制。您可以通过身份验证和升级来提高限制:https://www.docker.com/increase-rate-limit”

简短描述

当您试图从公共 Docker Hub 存储库(位于 Docker Hub 网站)提取映像,且此前已达到 Docker 提取速率限制(从 Docker Hub 网站),便会发生这一错误。如超过速率限制,将返回 HTTP 状态码 429。Docker Hub 使用 IP 地址对用户进行身份验证,而提取速率限制则基于单个 IP 地址。对于匿名用户,速率限制设置为每个 IP 地址每 6 小时拉取 100 次。对于有 Docker ID 的身份已验证用户,拉取速率设置为每 6 小时提取 200 次。如映像提取请求超过了这些限制,Amazon ECS 将拒绝请求,直到 6 小时的窗口期结束。如果您正在运行 Amazon ECS 或 Amazon Elastic Kubernetes Service(Amazon EKS)工作负载,则数据将通过具有固定 IP 地址的 NAT 网关来提取。在这种情况下,当超过拉取限制时,请求就会受到限制。

通过 AWSSupport-TroubleshootECSTaskFailedToStart 运行手册来解决 Amazon ECS 任务启动失败错误。此自动化会审查以下配置:

  • 与已配置的容器注册表的网络连接
  • 缺少执行角色所需的 AWS Identity and Access Management(IAM)权限
  • 虚拟私有云(VPC)端点连接
  • 安全组规则配置
  • AWS Secrets Manager 密钥参考
  • 日志配置

解决方法

重要事项:

  • 在与您的 ECS 集群资源所在的同一 AWS 区域使用 AWSSupport-TroubleshootECSTaskFailedToStart 运行手册。
  • 使用运行手册时,必须使用最近失败的任务 ID。如果失败的任务是 Amazon ECS 一部分,则在服务中使用最近失败的任务。在自动化执行期间,失败任务必须在 ECS:DescribeTasks 中可见。默认情况下,已停止的 ECS 任务在进入已停止状态后的 1 小时内保持可见。使用最近失败的任务 ID 可防止任务状态清理功能在自动化过程中导致分析中断。

**注意:**如果运行手册的输出未提供建议,请使用下一节中的手动故障排除法。

若要运行 AWSSupport-TroubleshootECSTaskFailedToStart 运行手册,请执行:

1.    打开 AWS Systems Manager 控制台

2.    在导航窗格的变更管理下,选择自动化

3.    选择执行自动化

4.    选择由 Amazon 所有选项卡。

5.    在自动化文档下,搜索TroubleshootECSTaskFailedToStart

6.    选择 AWSSupport-TroubleshootECSTaskFailedToStart 卡。
**注意:**确保选择卡上的单选按钮,而不是超链接的自动化名称。

7.    选择下一步
注意: 执行后,分析结果将填充到全局输出部分。但是,请等待文档状态变为成功。此外,请注意输出部分中的任何异常。

8.    对于执行自动化文档,选择简单执行

9.    在输入参数部分,对于 AutomationAssumeRole,输入允许 Systems Manager Automation 来执行操作的角色的 ARN。
**注意:**确保 AutomationAssumeRole 或 IAM 用户或角色拥有运行 AWSSupport-TroubleshootECSTaskFailedToStart 运行手册所需的 IAM 权限。如未指定 IAM 角色,则 Systems Manager Automation 将使用运行此运行手册的 IAM 用户或角色的权限。有关为 Systems Manager Automation 创建代入角色的详细信息,请参阅任务 1: 为自动化创建服务角色

10.    对于 ClusterName,输入任务启动失败的集群名称。

11.    对于 TaskId,输入最近失败的任务的标识。

12.    选择执行

根据自动化的输出,使用以下手动故障排除步骤之一。

将公有映像复制到 Amazon ECR 私有注册表

创建一个 Amazon Elastic Container Registry(Amazon ECR)存储库,然后将映像推送到这个新的存储库。当从 Amazon ECR 存储库提取映像时,便可避免超过 Docker Hub 的提取限制。

1.    运行与以下类似的命令,便可从 Docker Hub 提取映像:

docker pull example-image

2.    运行与以下类似的命令,对 Docker 客户端进行身份验证,以访问 Amazon ECR 注册表:

aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin 1111222233334444.dkr.ecr.eu-west-1.amazonaws.com

3.    运行与以下类似的命令,以此标记要推送到存储库的映像:

docker tag myrepository:latest 1111222233334444.dkr.ecr.eu-west-1.amazonaws.com/myrepository:latest

4.    运行与以下类似的命令,以便将 Docker 映像推送到 Amazon ECR 注册表:

docker push 1111222233334444.dkr.ecr.eu-west-1.amazonaws.com/myrepository:latest

5.    运行与以下类似的命令来更新 Docker 文件,以使用新推送的 Amazon ECR 映像作为基础映像:

FROM 1111222233334444.dkr.ecr.eu-west-1.amazonaws.com/myrepository:tag

在前面的命令中,请将以下值替换为您的值:

  • example-image 替换为要推送的公有映像的名称
  • 1111222233334444 替换为您的账户 ID
  • myrepository:latest 替换为您的 Amazon ECR 注册表名称
  • us-east-1 替换为您选择的区域

验证 Docker Hub 提取

当使用 Docker Hub 进行身份验证时,作为身份已验证的用户,您有更多的速率限制,并且基于 Docker 用户名而受到速率限制。将您的 Docker Hub 用户名和密码作为机密存储在 AWS Secrets Manager ,然后使用此密钥向 Docker Hub 进行身份验证。

为 Docker Hub 凭证创建 Secrets Manager 密钥

要为您的 Docker Hub 凭证创建密钥,请使用启用私有注册表身份验证创建基本密钥部分下的说明。

更新任务执行 IAM 角色

要授予 Amazon ECS 任务访问密钥的权限,请手动将所需权限作为内联策略添加到任务执行角色。

1.    打开 IAM 控制台

2.    在导航窗格中,选择角色

3.    在角色列表中搜索 ecsTaskExecutionRole,然后选择角色以查看附加的策略。

4.    在权限选项卡上选择添加权限,然后选择创建内联策略

5.    在创建策略页面中选择 JSON,然后复制并粘贴以下策略:

{
	"Version": "2012-10-17",
	"Statement": [{
		"Effect": "Allow",
		"Action": [
			"secretsmanager:GetSecretValue",
			"kms:Decrypt"
		],
		"Resource": [
			"arn:aws:secretsmanager:eu-west-1:1111222233334444:secret:dockerhub-0knT",
			"arn:aws:kms:eu-west-1:1111222233334444:key/mykey"
		]
	}]
}

在前面的策略中,将以下值替换为您的值:

  • 1111222233334444 替换为您的账户 ID
  • eu-east-1 替换为您选择的区域
  • mykey 替换为您的 AWS KMS 密钥

**注意:**仅当您的密钥使用自定义 AWS Key Management Service(AWS KMS)密钥时,才将 kms:Decrypt 包括在内。将自定义密钥的 ARN 作为资源添加。

6.    选择查看策略

7.    对于名称,输入策略的名称(ECSSecrets)。

8.    选择创建策略

创建使用密钥进行 Docker 身份验证的任务定义

遵循使用经典控制台创建任务定义中的说明,以此创建 Amazon ECS 任务定义。对于任务执行角色,选择您在上一节中更新的任务执行 IAM 角色。

容器定义部分中,完成以下步骤:

1.     选择添加容器

2.    对于容器名称,输入容器的名称。

3.     对于映像,输入映像的名称,或包括您的私有映像的路径(例如:repository-url/image.tag)。

4.    选择私有存储库身份验证

5.    对于 Secrets Manager ARN 或名称,输入您创建的密钥的 ARN。

6.    选择添加

创建 Amazon ECS 集群并运行 Amazon ECS 任务

创建 Amazon ECS 集群。然后,使用您创建的任务定义来运行任务

将 Amazon ECR 公有注册表用于公有容器映像

识别您在 Docker 文件中使用的公有映像。使用适当的搜索筛选器在 Amazon ECR 公有库中搜索这些映像。您无需进行身份验证即可浏览公有存储库和拉取映像。Amazon ECR Public 包含常用的基础映像,包括操作系统、AWS 发布的映像、Kubernetes 附加组件和构件。从 Amazon ECR 公有注册表中提取映像,以避免达到 Docker Hub 的速率限制。

在任务定义中使用这些映像作为容器映像的来源:

ContainerDefinitions: [
 {
 ...
 Image: 'public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest'
 ...
 }
 ]

您也可以选择使用这些映像作为 Docker 文件中的基础映像:

Docker File  
FROM public.ecr.aws/amazonlinux/amazonlinux:latest

升级到 Docker Pro 或 Team 订阅

如需要更多提取,请将您的计划升级到 Docker ProTeam 订阅,该订阅在 24 小时内可提供 50,000 次提取。有关定价计划的详细信息,请参阅定价和订阅(来自 Docker Hub 网站)。

相关信息

Amazon ECR 定价

Amazon ECR 公共服务限额

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