使用远程节点构建多架构 Docker 镜像
用 docker buildx 构建多架构镜像时,默认方案依赖 QEMU 模拟异构指令集,性能只有原生的 1/5 甚至 1/10,还时常撞上莫名其妙的编译失败。其实 BuildKit 原生支持另一条路:把不同架构的构建任务分发给对应的节点并行执行,本机与 ARM64 服务器各司其职,速度与稳定性都会大幅提升。本文记录完整的配置过程。
QEMU 模拟的瓶颈
buildx 默认的多架构构建,会在本地启动一个 QEMU 虚拟机来模拟目标架构。当本机是 x86、目标是 ARM64(或反过来)时,问题便暴露出来:
- 性能损失巨大:模拟执行的开销可能让构建速度退化 5~10 倍;
- 兼容性隐患:跨架构模拟并不总是成熟可靠,尤其是 ARM 模拟 x86 的场景,代码时常会以各种诡异的方式编译失败。
如果手头有一台不同架构的服务器,更优雅的做法是:按架构类型把构建任务分发给各自的原生节点,从根源上绕开模拟。
准备
假设本机是 AMD64(下文统一以 amd64 指代),另需一台 ARM64 服务器:
- 本机与远程服务器均已安装 Docker;
- 本机的 SSH 公钥已写入远程服务器,可免密登录。
没有真实的 ARM64 服务器也无妨,用虚拟机或 LXC 容器代替即可,原理完全一致。
创建构建器
核心思路是创建一个多节点构建器实例,让每个节点各自优先负责一种架构。
先创建构建器,同时指定本地节点 node_amd64:
docker buildx create \
--name multi_node_builder \
--node node_amd64 \
--platform linux/amd64--platform 声明该节点优先构建的架构。接着用 --append 把远程节点追加进来:
docker buildx create \
--name multi_node_builder \
--append \
--node node_arm64 \
--platform linux/arm64,linux/arm64/v8,linux/arm/v7,linux/arm/v6,linux/arm/v5 \
ssh://root@192.168.1.200几点说明:
ssh://root@192.168.1.200中的 IP 仅为示例,替换为自己的远程服务器地址;linux/arm64与linux/arm64/v8指同一架构;arm/v5到arm/v7则各不相同。这里全部明确列出,是为了覆盖 Debian(最低支持arm/v5)与 Alpine(最低支持arm/v6)等基础镜像。
启用与验证
docker buildx use multi_node_builder
docker buildx inspect --bootstrapinspect --bootstrap 会在两个节点上各部署一个 moby/buildkit 容器。
查看构建器列表:
docker buildx ls输出类似:
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
multi_node_builder* docker-container
\_ node_amd64 \_ unix:///var/run/docker.sock running v0.14.1 linux/amd64*, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386
\_ node_arm64 \_ ssh://root@192.168.1.200 running v0.14.1 linux/arm64*, linux/arm/v7*, linux/arm/v6*, linux/arm/v5*, linux/amd64, linux/386
default docker
\_ default \_ default running v0.11.7 linux/amd64, linux/386multi_node_builder后的星号表示它是当前默认构建器;- 各节点
PLATFORMS中带星号的是创建时指定的优先架构。BuildKit 还会自动检测出节点额外支持的架构,但优先级靠后,不会喧宾夺主。
实战:双节点并行构建
找一个包含 Dockerfile 的项目,同时指定两种架构:
docker buildx build . --platform=linux/amd64,linux/arm64/v8 -t multiarch/blog --load构建期间分别在本地与远程服务器上观察 htop,会看到两个节点各自满载、并行推进,且构建的都是各自的原生架构——没有任何 QEMU 模拟开销。
小结
按架构分发构建任务,是多架构镜像构建体验最好的方案之一。如果手上本就有异构服务器,强烈推荐切换过去;个人用户专门购置 ARM64 服务器来构建则未必划算,继续用 QEMU 等待也完全可行——遇到的问题大多能解决,只是慢。