View a markdown version of this page

从第三方注册表迁移容器镜像 - Amazon ECR
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

从第三方注册表迁移容器镜像

使用本指南将容器映像从外部注册表一次性复制到不支持 ECR Pull Through Cache 的 Amazon ECR 私有注册表中。

如果您的源是支持的上游注册表,则无需执行一次性复制。将上游注册表与 Amazon ECR 私有注册表同步要配置自动缓存,请参阅。

注意

Amazon ECR 会存储您复制的图像版本。不会自动从源注册表中提取较新的版本。要更新映像,请将新版本推送到您的 Amazon ECR 存储库。

迁移概述

迁移容器镜像涉及以下六个步骤:

  1. 在构建和部署文件中识别外部图像引用。

  2. 规划您的 Amazon ECR 存储库结构。

  3. 将图像复制到 Amazon ECR。

  4. 验证镜像完整性。

  5. 更新您的部署配置。

  6. 监控和验证。

先决条件

在开始之前,请验证以下几点:

  • 安装和配置 Amazon CLI 版本 2. 有关更多信息,请参阅 Install or update to the latest version of the Amazon CLI

  • 安装 Docker Engine 或 Docker 桌面版 20.10 或更高版本。有关更多信息,请参阅 Docker 文档中的安装 Docker 引擎

  • (可选)Installskopeo,这是一款开源工具,用于在没有本地 Docker 守护程序的情况下在注册表之间复制容器镜像。有关安装说明,请参阅上的 Skopeo。 GitHub

  • 验证您的 IAM 身份是否有权对您的注册表进行身份验证、创建存储库和推送映像。将AmazonEC2ContainerRegistryFullAccess托管策略附加到您用来运行这些命令的 IAM 用户或角色。有关更多信息,请参阅 Amazon 亚马逊弹性容器注册表的托管策略

步骤 1:识别外部图像引用

搜索用于构建和部署容器映像的文件,以获取对第三方注册表的引用。

以下命令使用 Linux 和 macOS 外壳语法。在 Windows 上,使用适用于 Linux 的 Windows 子系统 (WSL) 或 Git Bash。

识别部署清单中的参考文献

在您的 Amazon ECS 任务定义或 Amazon EKS 清单中搜索非 ECR 图片引用。

对于 Kubernetes 清单:

grep -rnH --include="*.yaml" --include="*.yml" "image:" . | grep -iv "dkr.ecr"

要运行 Amazon EKS 工作负载:

kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{range .spec.initContainers[*]}{.image}{"\n"}{end}{end}' | sort -u | grep -iv "dkr.ecr"

对于 Amazon ECS 任务定义:

aws ecs list-task-definitions --status ACTIVE --query 'taskDefinitionArns' --output text | \ tr '\t' '\n' | \ xargs -I {} aws ecs describe-task-definition --task-definition {} \ --query 'taskDefinition.containerDefinitions[].image' --output text | \ tr '\t' '\n' | sort -u | grep -iv "dkr.ecr"

识别 Dockerfiles 中的参考文献

要查找在构建目录中引用外部注册表的FROM指令,请执行以下操作:

grep -rnH --include="Dockerfile*" "FROM" . | grep -iv "dkr.ecr"

输出显示了引用 Amazon ECR 之外的图像的文件和行号。例如:

./app/Dockerfile:1:FROM python:3.11-slim
./service/Dockerfile:1:FROM nginx:1.25
./worker/Dockerfile:3:FROM redis:7-alpine

识别拉动频率(可选)

要了解您的工作负载从第三方注册表提取的频率,请查看上游注册表的使用情况分析(例如,Docker Hub 在账户控制面板中提供提取率数据)。高拉频率会增加达到速率限制的风险。有关 Docker Hub 速率限制,请参阅 Docker 文档中的 Docker Hub 速率限制

第 2 步:规划存储库结构

在复制图像之前,请决定如何在 Amazon ECR 中对其进行整理。

存储库命名-Amazon ECR 支持带有正斜杠的命名空间前缀。使用命名空间按团队、环境或应用程序对相关图像进行分组。命名空间还为每个前缀启用限定范围的 IAM 策略。例如:

base-images/python base-images/nginx team-a/web-app team-b/api-service

标签不可变性-对于生产映像,启用标签不可变性以防止图像标签被覆盖。有关更多信息,请参阅 防止映像标签在 Amazon ECR 中被覆盖

加密-在创建存储库之前选择您的加密配置。存储库创建后,您无法更改加密配置。有关更多信息,请参阅 静态加密

存储成本-Amazon ECR 会对每个存储库中的图像层进行重复数据消除。如果多个图像共享相同的基础图层,则每个存储库只需要为这些图层支付一次费用。在计划迁移哪些图像时,请将其考虑在成本估算中。

存储库创建模板-如果您要迁移许多映像,请使用您的首选设置(标签不可变性、加密、生命周期策略)为推送时创建操作配置存储库创建模板。Amazon ECR 在第一次推送期间代表您创建存储库时会应用模板设置。有关更多信息,请参阅 用于控制在缓存拉取、推送时创建或复制操作期间创建的存储库的模板

托管签名-如果您计划使用托管签名对图像进行签名,请在推送图像之前配置您的签名规则。签名仅在推送时发生。有关更多信息,请参阅 在亚马逊 ECR 中签名图片

Cross-Region 复制-如果您的工作负载在多个 Amazon 区域运行,请在推送映像之前配置复制规则。复制仅复制配置规则后推送的图像。有关更多信息,请参阅 Amazon ECR 中的私有映像复制

注意

Multi-architecture 除了清单列表之外,图片(清单列表)还要求您复制所有平台特定的清单。如果您使用 Docker,则docker pulldocker push命令仅处理与您的本地架构相匹配的平台。skopeo copy --all用于复制所有平台完好无损的多架构映像。

第 3 步:将图像复制到 Amazon ECR

在复制图像之前,请对您的 Amazon ECR 私有注册表进行身份验证。您的注册表 URL 遵循以下格式account-id.dkr.ecr.region.amazonaws.com。在以下示例中,请us-east-1使用您的 Amazon 账户 ID 和您的地区替换111122223333。在aws-cn分区中,注册表 URL 后缀为.amazonaws.com.cn。在所有其他分区 (aws,aws-us-gov) 中,后缀为.amazonaws.com

要查找您的账户 ID,请运行:

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

有关身份验证方法的更多信息,请参阅Amazon ECR 中的私有注册表身份验证

如果您使用 Docker(选项 A),请使用以下方式进行身份验证:

aws ecr get-login-password --region us-east-1 | \ docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com

如果您使用 skopeo(选项 B),请改为使用进行skopeo login身份验证。Skopeo 与 Docker 分开维护自己的凭证存储:

aws ecr get-login-password --region us-east-1 | \ skopeo login 111122223333.dkr.ecr.us-east-1.amazonaws.com --username AWS --password-stdin

选择以下方法之一来复制您的图像。

选项 A:使用 Docker CLI 进行复制

少数单平台图像使用此方法。有关推送工作流程的详细介绍,请参阅。在 Amazon ECR 中移动映像的整个生命周期

  1. 创建目标存储库(如果存储库已存在,则跳过此步骤):

    aws ecr create-repository \ --repository-name base-images/nginx \ --region us-east-1 \ --image-tag-mutability IMMUTABLE \ --encryption-configuration encryptionType=AES256
  2. 如果您使用经过身份验证的帐户从 Docker Hub 提取,以避免速率限制,请docker login docker.io先运行。从第三方注册表中提取镜像:

    docker pull nginx:1.25
  3. 为你的 Amazon ECR 存储库的图片添加标签:

    docker tag nginx:1.25 111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
  4. 将图片推送到 Amazon ECR:

    docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
  5. 要在存储库创建后检索存储库 URI,请运行:

    aws ecr describe-repositories --repository-names base-images/nginx --query 'repositories[0].repositoryUri' --output text
注意

Docker CLI 仅复制与您的本地计算机匹配的平台。要复制多架构映像,请使用选项 B 和。skopeo

选项 B:使用 skopeo 进行复制(建议用于批量迁移)

skopeo工具直接在注册表之间复制图像,无需将其拉到本地计算机。这种方法可以更快地执行批量操作,并且支持多架构映像。Skopeo 使用传输前缀来识别图像位置。docker://用于远程注册表。

  1. 如果需要,请向源注册表进行身份验证。例如,对于 Docker Hub 来说:

    echo YOUR_TOKEN | skopeo login docker.io --username YOUR_USERNAME --password-stdin
  2. 创建目标存储库:

    aws ecr create-repository \ --repository-name base-images/nginx \ --region us-east-1
  3. 复制镜像(单一平台):

    skopeo copy docker://docker.io/library/nginx:1.25 \ docker://111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
  4. 要在所有平台上复制多架构映像,请添加标--all志:

    skopeo copy --all docker://docker.io/library/nginx:1.25 \ docker://111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
注意

skopeo copy不复制与图像关联的 OCI 反向链接对象(签名、SBOM、证明)。如果您的源图片有关联的反向链接对象,请单独复制它们,或者在迁移后使用托管签名对图片进行重新签名。

使用脚本进行批量复制

要迁移多张图像,请创建一个列出源和目标对的文本文件,然后使用脚本复制它们。

创建一个名为 images-to-migrate.txt 的文件:

docker.io/library/nginx:1.25 base-images/nginx:1.25 docker.io/library/python:3.11-slim base-images/python:3.11-slim docker.io/library/redis:7-alpine base-images/redis:7-alpine ghcr.io/org/custom-app:v2.1.0 team-a/custom-app:v2.1.0

运行以下脚本:

#!/usr/bin/env bash set -euo pipefail ACCOUNT_ID="111122223333" REGION="us-east-1" REGISTRY="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com" aws ecr get-login-password --region ${REGION} | \ skopeo login ${REGISTRY} --username AWS --password-stdin while IFS=' ' read -r SOURCE DEST; do REPO_NAME=$(echo "${DEST}" | cut -d: -f1) # Create repository if it does not exist aws ecr create-repository \ --repository-name "${REPO_NAME}" \ --region "${REGION}" 2>/dev/null || true echo "Copying ${SOURCE} to ${REGISTRY}/${DEST}" skopeo copy --all "docker://${SOURCE}" "docker://${REGISTRY}/${DEST}" done < images-to-migrate.txt
注意

Amazon ECR 对推送操作强制执行 API 速率限制。对于大型迁移,如果遇到限制,请添加带有指数退避的重试逻辑。授权令牌将在 12 小时后过期。如果您的迁移需要更长的时间,请在继续之前重新运行身份验证命令。

步骤 4:验证镜像完整性

复制图像后,验证 Amazon ECR 中的图像摘要是否与来源相匹配。

  1. 在 Amazon ECR 中获取图片摘要:

    aws ecr describe-images \ --repository-name base-images/nginx \ --image-ids imageTag=1.25 \ --query 'imageDetails[0].imageDigest' \ --output text
    注意

    对于单平台图像,请直接比较摘要。对于使用复制的多架构映像--all,Amazon ECR imageDigest 中的表示清单列表。改用skopeo inspect --raw(如下所示)比较清单列表内容。

  2. 将摘要与源注册表进行比较。skopeo用于检查来源:

    skopeo inspect docker://docker.io/library/nginx:1.25 | grep Digest
  3. 摘要必须与复制的单平台图像相匹配。skopeo如果它们不匹配,则表示复制未成功完成。重试复制操作。如果您使用 Docker(选项 A),则摘要可能会有所不同,因为 Docker 可以在拉取和推送期间重新处理图层。要精确保存摘要,请使用skopeo

  4. 对于多架构映像,aws ecr describe-images返回清单列表和单个平台清单。要直接比较清单列表摘要,请在源和目标skopeo inspect --raw上使用:

    skopeo inspect --raw docker://111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25
  5. (可选)对迁移的映像运行映像扫描以识别漏洞。有关更多信息,请参阅 在 Amazon ECR 中扫描映像是否存在软件漏洞

步骤 5:更新部署配置

验证映像后,更新您的部署配置以从 Amazon ECR 中提取,并更新您的 CI/CD 构建管道以将新构建的映像推送到 ECR。这可确保将来的映像版本无需额外的手动副本即可使用。

Amazon ECS 任务定义

使用更新的图片 URI 创建任务定义的新版本:

{ "containerDefinitions": [ { "name": "web", "image": "111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25" } ] }

有关更多信息,请参阅 Amazon ECS 开发人员指南中的更新任务定义

亚马逊 EKS 或 Kubernetes 清单

更新 pod 规格中的image字段:

spec: containers: - name: web image: 111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/nginx:1.25

验证您的节点是否可以向 Amazon ECR 进行身份验证。如果AmazonEC2ContainerRegistryReadOnly托管策略已附加到节点 IAM 角色,则 Amazon EKS 节点默认使用 Amazon ECR 凭证帮助程序。

Dockerfiles

更新你的 Dockerfiles 中的FROM指令:

FROM 111122223333.dkr.ecr.us-east-1.amazonaws.com/base-images/python:3.11-slim

步骤 6:监控和验证

重新部署工作负载后,请验证所有图像现在是否都来自 Amazon ECR。

  • 检查仓库的 CloudWatch 指标。该RepositoryPullCount指标确认拉动正在发生。有关更多信息,请参阅 Amazon ECR 存储库指标

  • 查看 CloudTrail BatchGetImageGetDownloadUrlForLayer事件,确认您的工作负载是否来自预期的存储库。

  • (可选)设置生命周期策略以自动清理旧映像版本。有关更多信息,请参阅

注意事项

  • 不支持的上游注册表-Pull Through Cache 支持一组特定的上游注册表。对于不在该列表中的注册表(例如 jFrog Artifactory、Harbor 或 Sonatype Nexus),请使用 Docker CLI 或直接复制映像。skopeo

  • Large-scale 或跨分区传输-有关跨 Amazon 分区迁移(例如,awsaws-cn)或涉及数千张图像的传输,请参阅上的《数据传输中心指南》。 Amazon

  • Lambda- Lambda 要求容器镜像存储在 Amazon ECR 中,并且不能直接从第三方注册表中提取。在配置 Lambda 函数之前,使用选项 A 或选项 B 将图像复制到 ECR。

P@@ ull Through Cache-如果您的源注册表是支持的上游注册表之一,并且您希望 Amazon ECR 自动提取和缓存图像而不是执行一次性复制,请参阅。将上游注册表与 Amazon ECR 私有注册表同步