使用 `docker buildx` 构建 linux/amd64 与 linux/arm64 镜像
解读
在国内面试中,这道题表面考“一条命令”,实则验证候选人是否具备多架构交付、CI 适配与国产化环境踩坑经验。
面试官常追问:
- 构建节点怎么来的?
- 构建缓存如何复用?
- 镜像体积如何压到最小?
- 推送到阿里云 ACR或腾讯云 TCR为什么失败?
回答必须体现“能落地、能排障、能省钱”。
知识点
- buildx 原理:基于 BuildKit,通过 QEMU 用户态模拟或远程原生节点实现跨架构构建。
- builder 实例:
docker buildx create --name multi --platform linux/amd64,linux/arm64;国产化服务器若已含鲲鹏/飞腾 CPU,可直接挂载原生 arm64 节点避免模拟性能损失。 - 缓存策略:
--cache-to type=registry,ref=acr.cn-shanghai.aliyuncs.com/xxx:cache,mode=max+--cache-from实现跨构建缓存共享,显著降低带宽费用。 - 基础镜像选择:优先使用国内镜像源如
registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9,避免 Docker Hub 拉取限流。 - 最小化体积:多阶段构建 +
COPY --link+RUN --mount=type=cache;最终镜像使用distroless或alpine:3.18并切换非 root 用户以通过安全扫描。 - 推送到云厂商仓库:提前
docker login --username=xxx registry.cn-hangzhou.aliyuncs.com,并在 buildx 命令中--push一次性完成多架构合并清单。 - 故障排查:
docker buildx ls查看节点状态;docker buildx inspect --bootstrap诊断 QEMU 注册表缺失;构建日志加BUILDKIT_PROGRESS=plain保留详细输出供国产化平台审计。
答案
- 准备 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
- 编写支持多架构的 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"]
- 构建并推送
# 登录国内云厂商仓库
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 .
- 验证
docker buildx imagetools inspect registry.cn-hangzhou.aliyuncs.com/xxx/app:1.0.0
# 应显示两份 manifest:amd64 与 arm64
拓展思考
- 国产化替代:若客户环境禁用 Docker Hub,可提前同步基础镜像到私有 Harbor,并在 Dockerfile 中全量改写
FROM路径;同时关闭 buildx 的docker.io回退:--builder-opt build-arg:REGISTRY_MIRRORS=https://harbor.local。 - CI 集成:在阿里云 ACK-One 或华为云 CCE 的 Pipeline 里,使用
docker/setup-buildx-action@v2并缓存到 OSS/ OBS,节省 60% 构建时间。 - 安全合规:最终镜像需通过麒麟 V10 安全扫描,务必删除
apk缓存与 go 符号表;使用docker buildx build --sbom=true --provenance=mode=max生成供应链 SBOM,满足信创验收。