如何将多架构 docker 镜像复制到不同的容器注册表?

问题描述

有一种众所周知的方法可以将 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>

结果是各个层、映像配置、清单和多平台清单列表将在注册表之间复制,但仅限于目标注册表中尚不存在的层。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...