问题描述
有一种众所周知的方法可以将 docker 镜像从一个容器注册表复制到另一个容器注册表。如果原始注册中心是 dockerhub,典型的工作流程是这样的:
docker pull <image:tag>
docker tag <image:tag> <new-reg-url/uid/image:tag>
docker push <new-reg-url/uid/image:tag>
现在,在处理具有多架构层的图像时,您如何处理上述问题?
根据此 link 中的信息,您可以依靠 buildx
来构建多架构图像,并且在此过程中,您还可以将这些图像上传到您希望的任何存储库,但是 如何无需先构建图像即可执行此操作?
看起来 buildx
cli 不必要地 (?) 将上传过程与构建过程耦合在一起。有什么建议吗?
谢谢!
解决方法
虽然 docker pull ...; docker tag ...; docker push ...
语法是在注册表之间移动图像的简单方法,但它有几个缺点。首先,如您所见,它将多平台映像取消引用到单个平台。第二个是它将所有层拉到 docker 引擎,即使远程注册表已经有这些层,这对于总是需要拉每一层的临时 CI 工作者来说是一个糟糕的方法。
为此,我更喜欢直接与注册服务器对话,而不是与 docker 引擎本身对话。您不需要引擎的功能来运行图像,您只需要注册表 API。 Docker 已经记录了最初的 registry API,OCI 最近在 distribution-spec 上发布了 1.0,这应该会让我们得到一些标准化。
有各种基于这些规范的工具,从 docker 引擎本身和 containerd,到 skopeo、google 的起重机,我也一直在研究 regclient。使用 regclient 的 regctl 命令执行此操作如下所示:
regctl image copy <source_image:tag> <target_image:tag>
结果是各个层、映像配置、清单和多平台清单列表将在注册表之间复制,但仅限于目标注册表中尚不存在的层。