使用 `docker buildx` 构建 linux/amd64 与 linux/arm64 镜像

解读

在国内面试中,这道题表面考“一条命令”,实则验证候选人是否具备多架构交付CI 适配国产化环境踩坑经验。
面试官常追问:

  1. 构建节点怎么来的?
  2. 构建缓存如何复用?
  3. 镜像体积如何压到最小?
  4. 推送到阿里云 ACR腾讯云 TCR为什么失败?
    回答必须体现“能落地、能排障、能省钱”。

知识点

  1. buildx 原理:基于 BuildKit,通过 QEMU 用户态模拟或远程原生节点实现跨架构构建。
  2. builder 实例docker buildx create --name multi --platform linux/amd64,linux/arm64;国产化服务器若已含鲲鹏/飞腾 CPU,可直接挂载原生 arm64 节点避免模拟性能损失。
  3. 缓存策略--cache-to type=registry,ref=acr.cn-shanghai.aliyuncs.com/xxx:cache,mode=max + --cache-from 实现跨构建缓存共享,显著降低带宽费用。
  4. 基础镜像选择:优先使用国内镜像源registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9,避免 Docker Hub 拉取限流。
  5. 最小化体积:多阶段构建 + COPY --link + RUN --mount=type=cache;最终镜像使用 distrolessalpine:3.18 并切换非 root 用户以通过安全扫描。
  6. 推送到云厂商仓库:提前 docker login --username=xxx registry.cn-hangzhou.aliyuncs.com,并在 buildx 命令中 --push 一次性完成多架构合并清单。
  7. 故障排查docker buildx ls 查看节点状态;docker buildx inspect --bootstrap 诊断 QEMU 注册表缺失;构建日志加 BUILDKIT_PROGRESS=plain 保留详细输出供国产化平台审计

答案

  1. 准备 builder
# 若本机已含 BuildKit,直接创建
docker buildx create --name multi \
  --platform linux/amd64,linux/arm64 \
  --use
# 国产化场景:把已有 arm64 机器加入
docker buildx create --name multi --append ssh://user@arm64-node
docker buildx inspect --bootstrap
  1. 编写支持多架构的 Dockerfile(示例 Go 应用)
# 第一阶段:编译
FROM --platform=$BUILDPLATFORM golang:1.21-alpine3.18 AS builder
ARG TARGETOS TARGETARCH
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache git ca-certificates
WORKDIR /src
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod go mod download
COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build \
  CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
  go build -ldflags="-s -w" -o app .

# 第二阶段:运行
FROM alpine:3.18
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
    apk add --no-cache ca-certificates tzdata && \
    adduser -D -u 1000 appuser
COPY --from=builder /src/app /usr/local/bin/app
USER 1000
ENTRYPOINT ["app"]
  1. 构建并推送
# 登录国内云厂商仓库
echo $ACR_PASSWORD | docker login --username=xxx registry.cn-hangzhou.aliyuncs.com --password-stdin

# 一次性构建双架构并推送
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t registry.cn-hangzhou.aliyuncs.com/xxx/app:1.0.0 \
  --build-arg http_proxy=http://your.corp.proxy:8080 \
  --build-arg https_proxy=http://your.corp.proxy:8080 \
  --cache-to type=registry,ref=registry.cn-hangzhou.aliyuncs.com/xxx/app:cache,mode=max \
  --cache-from type=registry,ref=registry.cn-hangzhou.aliyuncs.com/xxx/app:cache \
  --push \
  -f Dockerfile .
  1. 验证
docker buildx imagetools inspect registry.cn-hangzhou.aliyuncs.com/xxx/app:1.0.0
# 应显示两份 manifest:amd64 与 arm64

拓展思考

  1. 国产化替代:若客户环境禁用 Docker Hub,可提前同步基础镜像到私有 Harbor,并在 Dockerfile 中全量改写 FROM 路径;同时关闭 buildx 的 docker.io 回退:--builder-opt build-arg:REGISTRY_MIRRORS=https://harbor.local
  2. CI 集成:在阿里云 ACK-One华为云 CCE 的 Pipeline 里,使用 docker/setup-buildx-action@v2 并缓存到 OSS/ OBS,节省 60% 构建时间
  3. 安全合规:最终镜像需通过麒麟 V10 安全扫描,务必删除 apk 缓存与 go 符号表;使用 docker buildx build --sbom=true --provenance=mode=max 生成供应链 SBOM,满足信创验收。