我在 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 张图片:
有什么想法我做错了吗?存储库设置已禁用不变性。
我宁愿避免docker pull, docker tag,docker push方法,因为这将在我的 CI 服务器(Github Actions)上以单独的工作流程运行,这docker pull将是一个非常浪费的命令。
问题是清单中的空白。
--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,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)