将远程标记添加到Docker图像

b1payxdu  于 2022-11-22  发布在  Docker
关注(0)|答案(6)|浏览(196)

在一个私人注册表(myregistry.com)上,假设我有一个标记为“v1.2.3”的图像,然后我通过以下方式推送它:
docker push myregistry.com/myimage:v1.2.3
如果我想关联另一个标记,比如“staging”,并将该标记推送到我的注册表中,我可以:

docker tag myregistry.com/myimage:v1.2.3 myregistry.com/myimage:staging
docker push myregistry.com/myimage:staging

虽然这样做是可行的,但第二个docker push仍然会遍历每个图像,试图推送它(尽管跳过了上传)。

d4so4syb

d4so4syb1#

正如您所说,docker tag ...; docker push ...是为图像添加标签并共享它的最佳方式。
在您给出的特定示例中,两个标签都在同一个存储库(myregistry.com/myimage)中。在这种情况下,您可以只使用docker push myregistry.com/myimage,默认情况下,docker守护进程将同时为存储库推送 * 所有 * 标签,为共享层保存层的迭代。
您也可以使用相同的过程(docker tag ...; docker push ...)在存储库之间标记图像,例如:

docker tag myregistry.com/myimage:v1.2.3 otherregistry.com/theirimage:v2
docker push otherregistry.com/theirimage
h79rfbju

h79rfbju2#

您可以使用docker buildx imagetools create来实现这一点

docker buildx imagetools create myregistry.com/myimage:v1.2.3 --tag myregistry.com/myimage:staging

这将简单地下载myregistry.com/myimage:v1.2.3的映像清单,并将其重新标记(和推送)为myregistry.com/myimage:staging
注:当您“重新标记”时(例如,当您的映像是为linux/arm 64和linux/amd 64构建的),这也将保留多平台清单列表。其中,传统的Docker拉/推策略将仅保留您从中执行拉/推操作的系统的平台/体系结构的映像清单。

zsbz8rwp

zsbz8rwp3#

提取/标记/推送方法会花费时间与网络成本,您只需使用以下选项远程标记您得映像:
仅对于更改TAG,答案https://stackoverflow.com/a/38362476/8430173有效,但我也想更改存储库名称
非常感谢this,我也更改了repoName!
(by他X1 E2 F1 X项目的帮助):
1-获取清单(在v2方案中)
2-在新的存储库中发布每一层摘要
3-后配置层
4-将整个清单放入新存储库

详细信息:

1- GET来自reg:5000/v2/{oldRepo}/manifests/{oldtag}的清单,其中包含accept标头:application/vnd.docker.distribution.manifest.v2+json
**2-**每层:开机自检reg:5000/v2/{newRepo}/blobs/uploads/?mount={layer.digest}&from={oldRepoNameWithaoutTag}
3个开机自检reg:5000/v2/{newRepo}/blobs/uploads/?mount={config.digest}&from={oldRepoNameWithaoutTag}
4- PUT带有content-type标题的reg:5000/v2/{newRepo}/manifests/{newTag}:步骤1响应中的application/vnd.docker.distribution.manifest.v2+jsonbody
**5-**享受!

6yt4nkrj

6yt4nkrj4#

对于单平台映像,可以使用

docker pull repo:oldtag
docker tag repo:oldtag repo:newtag
docker push repo:newtag

然而,也有一些缺点。
1.即使不需要在本地运行图像,也可以拉取所有层。
1.您正在取消多平台映像对本地平台的引用。
这可以通过curl来完成,特别是当您在同一个仓库中时(当您跨仓库时,您还需要复制所有的blob)。
1.你需要接受所有可能的媒体类型,跟踪你收到的媒体类型,并在将清单推回注册表时使用相同的媒体类型。我至少熟悉6种媒体类型:

  • 带符号和不带符号的Docker模式v1
  • Docker模式v2中公共清单和清单列表
  • OCI图像和索引

1.如果您跨存储库访问,则需要解析包含的blob的清单,对于Docker清单列表和OCI索引,这可能是递归的。您可以执行服务器端blob挂载以避免拉入和推送blob,但这将取决于服务器支持。我们还将看到匿名blob挂载进入注册表。即使您不知道该注册表上的源存储库,它也允许blob挂载(对于每个人都可以使用基于Docker Hub的官方Docker映像的映像推送到云注册表,这很有用)。
1.授权变得复杂,尤其是在命令之间需要请求和维护不记名令牌的情况下。
我推荐的解决方案是使用一个工具来为您处理注册表API。我一直在为此开发我自己的工具regclient,还有其他类似的项目,如Google的起重机和RedHat的skopeo。它们都应该处理媒体类型,在需要时复制blob,以及可能使curl命令复杂化的授权问题。
以regclient的regctl命令为例,您可以运行:

regctl image copy repo:oldtag repo:newtag
tktrz96b

tktrz96b5#

新的 * 实验性 * manifest Docker commands有一个更简单的方法。它只需要下载和上传一个镜像的清单文件(JSON概述)。下面的命令已经在GitLab注册表中测试过了。首先在前面的某个阶段构建并推送一个Docker镜像:

docker build -t registry.gitlab.com/<group>/<project>/<image-name>:<tag-a> .
docker push registry.gitlab.com/<group>/<project>/<image-name>:<tag-a>

然后在图像还没有被拉出的稍后阶段:

docker manifest create registry.gitlab.com/<group>/<project>/<image-name>:<tag-b> \
    registry.gitlab.com/<group>/<project>/<image-name>:<tag-a>
docker manifest push registry.gitlab.com/<group>/<project>/<image-name>:<tag-b>

然后您可以使用新标签提取图像。第一步似乎不适用于公共Docker Hub图像,但欢迎您提出任何建议。此外,要查看清单本身,请运行:

docker manifest inspect registry.gitlab.com/<group>/<project>/<image-name>:<tag-a>
mqxuamgl

mqxuamgl6#

使用google's crane,您只需

crane tag myregistry.com/myimage:v1.2.3 staging

它可以处理Docker映像和OCI映像,不会在本地下载映像,甚至可以跳过层验证,因为它们肯定已经在存储库中。
它甚至提供了一个码头形象:gcr.io/go-containerregistry/crane
请注意,还有其他类似的工具,如regctlskopeo

相关问题