
对于那些拥有ARM开发机(Apple M1),但有时需要在本地构建x86/amd64镜像以推送到注册中心的人来说,这是一个巧妙的Docker技巧。
当然,有一个CI/CD平台来做这件事可能是最理想的,但对于小程序或只是有时一般来说,知道这一点可能很方便。
如果你有一台闲置的Intel机器,你可以把它变成一个构建服务器。在上面安装Ubuntu之类的东西,并安装最新的Docker。在你的开发机器上,把你发布的SSH密钥复制到这个构建服务器上。
所以,现在你有了你的服务器,你想在x86/amd64平台上构建你的Docker镜像。通常情况下,你会运行下面这样的命令来定位该平台。
docker buildx build -f Dockerfile --platform linux/amd64 .
这将会起作用,但你会注意到的是,这是一个极其缓慢的过程。苹果公司的硅芯片很了不起,是我使用过的最快的机器。然而,当模拟x86指令来构建docker镜像时,它需要如此长的时间。我见过在更大和更复杂的项目中,这需要一个多小时。
只是作为一个例子。这里我们有一个非常简单的Ruby on Rails应用程序,没有什么活动部件。我正在使用像esbuild 和css-bundling ,但没有什么花哨的东西。在M1芯片上,构建该图像需要250多秒。
# Apple Silicon
[+] Building 316.4s (23/23) FINISHED
然而,在AMD 5900X服务器上,我有一个安装了Docker的虚拟机在上面运行。在那里运行完全相同的项目花费的时间要少得多。
# AMD 5900X
[+] Building 62.3s (24/24) FINISHED
所以,这里的主要问题是,我不想打断我建立图像或处理事情的正常过程。推送我的代码,ssh进入构建服务器,把它拉下来,然后构建图像,这将是一个痛苦的过程。这有很多步骤,但幸运的是,有一个更简单的方法可以做到这一点。
Docker的buildx构建命令有一个标志,我们可以指定一个特定的构建器。
因此,我们可以在我们的本地机器上创建这个构建器。这种创建的好处是,它是空闲的,所以你可以多次运行这个命令而不改变结果。我们要做的就是创建一个构建器配置文件,在本例中我将其命名为amd64_builder 。由于这个构建器是一个资源池,我为虚拟机起了一个名字。我还指定了我要构建的平台,然后传入我的构建器机器的SSH网址。
docker buildx create \
--name amd64_builder \
--node linux_amd64_builder \
--platform linux/amd64 \
ssh://USERNAME@IP_ADDRESS_OF_BUILDER
现在,我可以构建和推送镜像到注册表。我们将使用的神奇标志是--builder ,因为我们现在可以指定构建者的虚拟机。buildx命令的其余部分与我们预期的一样。
docker buildx build \
--builder amd64_builder \
--tag USERNAME/REPONAME:TAG \
--push .
在某些情况下,我已经看到这比M1芯片上的amd64模拟快了近10倍。如果你身边有一台闲置的英特尔/AMD机器,这可能是一次值得的冒险。