在M1上构建Docker很慢的原因及技巧

1,117 阅读3分钟

Docker Builds are slow on M1

对于那些拥有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应用程序,没有什么活动部件。我正在使用像esbuildcss-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机器,这可能是一次值得的冒险。