在 AWS ECR 上重新标记映像会创建新映像

Oma*_*ani 7 docker amazon-ecr

我在 AWS ECR 上有一个私有 Docker 存储库。

我正在尝试使用此处的说明使用新标签来标记现有图像https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-retag.html

例如,假设我有一个带有标签“1.5.0”的图像,现在我想添加标签“lts”,通过使用上面的方法来“batch-get-image”标签“1.5.0”,并且然后“put-image”和“image-tag”“lts”,该命令在存储库中创建一个带有标签“lts”的全新图像。原始图像“1.5.0”不受影响。

代码:

MANIFEST=$(aws ecr batch-get-image --region eu-west-1 --repository-name mynamespace/repo --image-ids imageTag='1.5.0' --query 'images[].imageManifest' --output text)
Run Code Online (Sandbox Code Playgroud)
aws ecr put-image --region eu-west-1 --repository-name mynamespace/repo --image-tag lts --image-manifest "$MANIFEST"
Run Code Online (Sandbox Code Playgroud)

上面的结果是两个独立的图像:

  • 1.5.0

我想要 1 张图片:

  • 1.5.0,lts

有什么想法我做错了吗?存储库设置已禁用不变性。

我宁愿避免docker pull, docker tag,docker push方法,因为这将在我的 CI 服务器(Github Actions)上以单独的工作流程运行,这docker pull将是一个非常浪费的命令。

use*_*000 2

问题是清单中的空白。

--output text将引入空白,不会产生与原始图像相同的 sha,因此它将发布一个新图像。

jq所以你想这样使用:

MANIFEST=$(aws ecr batch-get-image --repository-name amazonlinux --image-ids imageTag=latest --output json | jq --raw-output '.images[].imageManifest')
Run Code Online (Sandbox Code Playgroud)

(如此处所述)如何在 ECR 中重新标记图像?

无论您使用哪种语言,都必须管理空白。对我来说,要在 ruby​​ 中管理它,对我有用的是将其解析为 json。

另外,我学到的一件事是,您可以通过指定您期望的 sha 来保护自己免于无意中创建新图像。在下面的代码中,我

  • 按标签查找图像并获取imageDigestsha,
  • 使用该 sha 获取清单
  • 将摘要 sha清单传递给put-image命令

如果清单的 sha 与您提供的摘要 sha 不匹配,亚马逊将返回错误,从而允许命令失败,而不是创建您不需要的附加图像。

digest = `aws ecr batch-get-image --repository-name #{name} --image-ids=imageTag=#{tag} --output json | jq --raw-output '.images[0].imageId.imageDigest'`.strip

pre_manifest = `aws ecr batch-get-image --repository-name #{name} --image-ids=imageDigest=#{digest} --output json | jq '.images[0].imageManifest'`

manifest = JSON.parse(pre_manifest)

# run_command is a wrapper around a system call

run_command("aws ecr put-image --repository-name #{name} --image-tag latest --image-digest #{digest} --image-manifest '#{manifest}'")

Run Code Online (Sandbox Code Playgroud)