Docker Buildx多平台镜像构建
Docker Buildx 构建 amd64、arm64 等多平台镜像的使用方法、缓存配置和 CI/CD 建议。
Docker Buildx 多平台镜像构建
Docker Buildx 是 Docker 提供的新一代构建工具,基于 BuildKit,可以构建多平台镜像、使用高级缓存、输出镜像清单,并更好地适配 CI/CD 构建场景。它常用于同时构建 linux/amd64 和 linux/arm64 镜像,满足 x86 服务器、ARM 服务器、Mac Apple Silicon 和云原生集群混合部署需求。
适用场景
- 同一个应用需要运行在 x86 和 ARM 节点上。
- Kubernetes 集群中同时存在
amd64和arm64节点。 - CI/CD 需要一次构建并推送多平台镜像。
- 本地 Apple Silicon 机器需要构建 Linux amd64 镜像。
- 希望使用远端缓存或 registry 缓存提升镜像构建速度。
查看 Buildx
检查 Docker 是否支持 buildx:
docker buildx version
查看当前 builder:
docker buildx ls
如果当前 builder 不支持多平台构建,可以创建一个新的 builder。
创建 Builder
创建并切换到新的 builder:
docker buildx create --name multi-platform-builder --use
初始化 builder:
docker buildx inspect --bootstrap
查看支持的平台:
docker buildx inspect
如果输出中包含 linux/amd64、linux/arm64 等平台,说明可以构建对应架构的镜像。
安装 QEMU 支持
在非目标架构机器上构建多平台镜像时,通常需要 QEMU 模拟支持。
docker run --privileged --rm tonistiigi/binfmt --install all
再次确认 builder 支持的平台:
docker buildx inspect --bootstrap
追加原生架构构建节点
如果有条件准备两台不同架构的构建机,推荐让 amd64 机器只负责 linux/amd64,arm64 机器只负责 linux/arm64。这种方式属于原生架构构建,通常比 QEMU 模拟更快,也更接近最终运行环境。
示例环境:
| 节点 | 架构 | 访问地址 | 负责平台 |
|---|---|---|---|
build-amd64 | amd64 | ssh://builder@10.0.0.11 | linux/amd64 |
build-arm64 | arm64 | ssh://builder@10.0.0.12 | linux/arm64 |
前置要求:
- 两台机器都已经安装 Docker。
- 当前机器可以通过 SSH 免密登录两台构建机。
- 登录用户有权限访问远端 Docker。
- 两台机器都可以访问源码依赖和镜像仓库。
先验证 SSH 和远端 Docker:
ssh builder@10.0.0.11 docker version
ssh builder@10.0.0.12 docker version
创建 amd64 构建节点:
docker buildx create \
--name native-multi-builder \
--node build-amd64 \
--platform linux/amd64 \
ssh://builder@10.0.0.11
追加 arm64 构建节点:
docker buildx create \
--name native-multi-builder \
--append \
--node build-arm64 \
--platform linux/arm64 \
ssh://builder@10.0.0.12
切换到这个 builder:
docker buildx use native-multi-builder
初始化并查看节点:
docker buildx inspect --bootstrap
正常情况下可以看到两个节点,每个节点对应自己的平台:
Name: native-multi-builder
Driver: docker-container
Nodes:
Name: build-amd64
Endpoint: ssh://builder@10.0.0.11
Platforms: linux/amd64
Name: build-arm64
Endpoint: ssh://builder@10.0.0.12
Platforms: linux/arm64
使用该 builder 构建多平台镜像:
docker buildx build \
--builder native-multi-builder \
--platform linux/amd64,linux/arm64 \
-t registry.example.com/ops/demo-api:1.0.0 \
--push \
.
构建时,Buildx 会把 linux/amd64 的构建任务分配到 amd64 节点,把 linux/arm64 的构建任务分配到 arm64 节点,最后在镜像仓库中生成同一个多平台镜像清单。
构建单平台镜像
构建当前平台镜像并加载到本地 Docker:
docker buildx build \
--platform linux/amd64 \
-t registry.example.com/ops/demo-api:1.0.0 \
--load \
.
--load 适合单平台镜像,会把构建结果加载到本地 Docker 镜像列表中。
查看本地镜像:
docker images registry.example.com/ops/demo-api
构建并推送多平台镜像
多平台镜像不能直接用 --load 加载到本地 Docker,通常需要直接推送到镜像仓库。
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t registry.example.com/ops/demo-api:1.0.0 \
--push \
.
构建完成后,镜像仓库中会存在一个多平台镜像清单。不同架构的节点拉取同一个 tag 时,会自动选择对应架构。
查看镜像清单:
docker buildx imagetools inspect registry.example.com/ops/demo-api:1.0.0
同时打多个 Tag
发布时通常会同时打版本号和环境 tag。
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t registry.example.com/ops/demo-api:1.0.0 \
-t registry.example.com/ops/demo-api:stable \
--push \
.
使用构建参数
Dockerfile 中可以声明构建参数:
ARG APP_VERSION
ARG BUILD_DATE
LABEL org.opencontainers.image.version="${APP_VERSION}"
LABEL org.opencontainers.image.created="${BUILD_DATE}"
构建时传入参数:
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg APP_VERSION=1.0.0 \
--build-arg BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-t registry.example.com/ops/demo-api:1.0.0 \
--push \
.
Dockerfile 多平台变量
BuildKit 会提供一些常用平台变量:
| 变量 | 说明 |
|---|---|
BUILDPLATFORM | 执行构建的机器平台 |
TARGETPLATFORM | 目标镜像平台 |
TARGETOS | 目标操作系统 |
TARGETARCH | 目标 CPU 架构 |
TARGETVARIANT | 架构变体,例如 arm/v7 |
示例:
FROM --platform=$BUILDPLATFORM golang:1.22-alpine AS builder
ARG TARGETOS
ARG TARGETARCH
WORKDIR /src
COPY . .
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /out/app ./cmd/app
FROM alpine:3.20
COPY --from=builder /out/app /usr/local/bin/app
ENTRYPOINT ["app"]
这种方式适合 Go、Rust 等可以交叉编译的语言,通常比 QEMU 模拟构建更快。
使用缓存加速构建
使用 registry 缓存:
docker buildx build \
--platform linux/amd64,linux/arm64 \
--cache-from type=registry,ref=registry.example.com/ops/demo-api:buildcache \
--cache-to type=registry,ref=registry.example.com/ops/demo-api:buildcache,mode=max \
-t registry.example.com/ops/demo-api:1.0.0 \
--push \
.
CI/CD 中推荐使用远端缓存,避免每次流水线都从零开始构建。
GitLab CI 示例
build:image:
stage: build
image: docker:27
services:
- docker:27-dind
variables:
DOCKER_TLS_CERTDIR: ""
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- docker buildx create --use --name ci-builder
- docker buildx inspect --bootstrap
script:
- docker buildx build
--platform linux/amd64,linux/arm64
--cache-from type=registry,ref="$CI_REGISTRY_IMAGE:buildcache"
--cache-to type=registry,ref="$CI_REGISTRY_IMAGE:buildcache",mode=max
-t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
-t "$CI_REGISTRY_IMAGE:latest"
--push
.
常用命令
| 命令 | 说明 |
|---|---|
docker buildx version | 查看 buildx 版本 |
docker buildx ls | 查看 builder 列表 |
docker buildx create --use | 创建并切换 builder |
docker buildx inspect --bootstrap | 初始化并查看 builder |
docker buildx build --platform linux/amd64 . | 构建指定平台镜像 |
docker buildx build --push ... | 构建并推送镜像 |
docker buildx build --load ... | 构建单平台镜像并加载到本地 |
docker buildx imagetools inspect IMAGE | 查看多平台镜像清单 |
docker buildx rm NAME | 删除 builder |
常见问题
multiple platforms feature is currently not supported for docker driver
当前 builder 使用的是默认 docker driver,不适合多平台输出。创建一个 docker-container driver 的 builder:
docker buildx create --name multi-platform-builder --driver docker-container --use
docker buildx inspect --bootstrap
多平台构建后本地看不到镜像
使用 --push 构建多平台镜像时,镜像会直接推送到仓库,不会出现在本地 docker images 中。
如果只想本地测试单平台镜像,使用:
docker buildx build --platform linux/amd64 -t demo-api:test --load .
exec format error
通常是镜像架构和运行节点架构不匹配。检查镜像支持的平台:
docker buildx imagetools inspect registry.example.com/ops/demo-api:1.0.0
检查节点架构:
uname -m
kubectl get nodes -o wide
构建很慢
常见原因:
- 使用 QEMU 模拟非本机架构。
- 没有配置远端缓存。
- Dockerfile 中依赖安装层没有充分复用。
- 每次构建都复制了过多上下文文件。
建议添加 .dockerignore,并把依赖安装层放在源码复制之前。
.git
node_modules
dist
.venv
*.log