>

适用场景:手头有 x86 的 VPS/电脑 + ARM 的树莓派/N100 盒子/NAS,同一个镜像要在不同架构上跑;不想每次 docker build 都要换机器,想自动化出 multi-arch;还想自建私有仓库 + 安全扫描 + 签名
> 核心栈:Docker Buildx + QEMU + GitHub Actions / Drone + Harbor(或 GHCR/ZOT)+ Trivy + Cosign
> 达成目标:Git Push → 自动构建 linux/amd64 + linux/arm64 + linux/arm/v7 + linux/riscv64 → 推私有仓库 → 扫描 CVE → 签名 → 各节点 docker pull 直接跑


0. 架构与流程总览

+----------+       +---------------+       +------------------------+
| Git Push | ----> | CI (Actions/  | ----> | buildx (QEMU 模拟)     |
|          |       | Drone/Woodpecker)     | 构建多架构镜像         |
+----------+       +---------------+       +-----------+------------+
                                                        |
                                                        v
                                        +-------------------------------+
                                        |  Harbor / GHCR / ZOT 私有仓库 |
                                        |  - 多架构 manifest list      |
                                        |  - Trivy CVE 扫描            |
                                        |  - Cosign 签名验证           |
                                        +----------------+--------------+
                                                         |
                            +----------------------------+-------------+
                            |                    |                     |
                     x86_64 节点           arm64 节点          riscv64 节点
                     docker pull          docker pull          docker pull
                      自动选架构           自动选架构           自动选架构
>

关键认知:多架构镜像的本质是 manifest list(清单)——一个 tag 下挂多个架构的 image manifest,客户端 docker pull 时自动按本机架构选层。


1. buildx 本地多架构构建(零 CI 起步)

1.1 安装 & 启用

# Docker 新版自带 buildx 插件
docker buildx version

# 创建构建器,启用 QEMU 跨架构模拟
docker run --rm --privileged tonistiigi/binfmt --install all
docker buildx create --name multiarch --driver docker-container --use
docker buildx inspect --bootstrap

# 验证支持的架构
docker buildx ls
# 应看到: linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6, linux/riscv64, linux/ppc64le, linux/s390x...

1.2 构建并推送多架构镜像

# 单条命令出多架构(以你自己项目为例)
docker buildx build \
  --platform linux/amd64,linux/arm64,linux/arm/v7 \
  --tag registry.example.com/myapp:latest \
  --tag registry.example.com/myapp:v1.2.3 \
  --push \
  .

1.3 只看不推(本地调试)

# 构建到本地 buildx 缓存(不推远程)
docker buildx build --platform linux/arm64 --load -t myapp:arm64 .
# 注意: --load 只能单架构;多架构必须 --push 到仓库

2. Dockerfile 多架构最佳实践

2.1 用 TARGETARCH 构建参数自动切架构

# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM golang:1.22-alpine AS builder
ARG TARGETOS TARGETARCH
WORKDIR /src
COPY . .
# 交叉编译:在 x86 上出 arm64 二进制(快!无需 QEMU 完整模拟运行)
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="-s -w" -o /app .

FROM --platform=$TARGETPLATFORM alpine:3.20
COPY --from=builder /app /usr/local/bin/app
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/app"]
>

--platform=$BUILDPLATFORM(构建阶段跑在构建机架构)+ $TARGETOS/$TARGETARCH(交叉编译到目标架构),比 QEMU 完整模拟运行快 10-100 倍。

2.2 原生编译 vs QEMU 模拟(选型)

语言/场景推荐方式说明
Go / Rust / C(静态编译)交叉编译(GOARCH / --target)快、无 QEMU 依赖
Python / Node / Java(解释/JIT)QEMU 模拟(默认)用官方多架构 base 镜像即可
需要原生依赖(C 库、系统包)官方多架构 base(debian/alpine/ubuntu 全架构)拉取对应架构层
C/C++ 大项目(Qt/OpenCV)各架构原生 Runner(真实 arm64 机器跑)最稳,配 GitHub 新 arm64 runner

2.3 避免的错误

# ❌ 硬编码架构
FROM amd64/alpine:3.20        # 只出 x86

# ❌ 用未声明多架构的 base
FROM some/tiny-image:latest   # 可能只有 amd64

# ✅ 用官方或明确多架构的镜像
FROM alpine:3.20              # 官方 manifest list 含 amd64/arm64/arm/v7...

3. GitHub Actions 自动化多架构构建

# .github/workflows/build-multiarch.yml
name: Build Multi-Arch

on:
  push:
    tags: ['v*']          # 打 tag 才构建
  workflow_dispatch:       # 手动触发

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha

      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/amd64,linux/arm64,linux/arm/v7
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
>

缓存加速:cache-from/to: type=gha 用 GitHub Action 缓存层,重复构建秒级;mode=max 缓存所有阶段。


4. 私有仓库落地:Harbor(企业级首选)

4.1 Docker Compose 部署 Harbor

# harbor.yml(下载官方安装包自带模板,改关键项)
version: "3.8"
services:
  nginx:
    image: goharbor/nginx-photon:v2.11.0
    container_name: nginx
    restart: always
    ports:
      - "80:80"
      - "443:443"
      - "4443:4443"      # Notary
    volumes:
      - ./common/config/nginx:/etc/nginx:z
      - /data/harbor:/harbor
    depends_on:
      - portal
      - core
      - registry
    networks:
      - harbor

  core:
    image: goharbor/harbor-core:v2.11.0
    container_name: harbor-core
    restart: always
    env_file: ./common/config/core/env
    volumes:
      - /data/harbor/data:/data:z
      - /data/harbor/secret:/etc/harbor:z
    networks:
      - harbor

  registry:
    image: goharbor/registry-photon:v2.11.0
    container_name: registry
    restart: always
    volumes:
      - /data/harbor/registry:/storage:z
      - ./common/config/registry:/etc/registry:z
    networks:
      - harbor

  # ... (portal, jobservice, log, redis, database, trivy-adapter, chartmuseum 等)

networks:
  harbor:
    external: false
# 官方一键安装
wget https://github.com/goharbor/harbor/releases/download/v2.11.0/harbor-online-installer-v2.11.0.tgz
tar xzvf harbor-online-installer-v2.11.0.tgz
cd harbor
cp harbor.yml.tmpl harbor.yml
vim harbor.yml   # 改 hostname、密码、数据目录、https 证书
sudo ./install.sh --with-trivy --with-notary --with-chartmuseum

4.2 Harbor 核心功能(企业级 vs GHCR)

功能HarborGHCRDocker Hub
镜像存储✅ 私有/内网✅ 私有/公开⚠️ 免费版私有仓库受限
CVE 扫描✅ Trivy 内置,可阻断漏洞镜像✅ Dependabot 关联⚠️ Docker Scout 收费
签名验证✅ Notary/Cosign 集成✅ Sigstore(beta)⚠️ 有限
GC 清理策略✅ 按 tag/保留策略自动清理❌ 手动❌ 手动
项目/权限隔离✅ 项目级 RBAC、配额⚠️ 组织级⚠️ 组织级
复制/同步✅ 规则引擎(推/拉、过滤)❌❌
Helm Chart 托管✅ ChartMuseum/Oci✅ OCI❌
审计日志✅ 完整审计✅ 基础⚠️ 基础
部署形态私有/内网/离线SaaSSaaS

4.3 Trivy 扫描 + 签名验证(在 Harbor 里配置)

# 1. 扫描:创建项目时勾选「自动扫描」,或用 CLI 手动
trivy image --scanners vuln,misconfig,secret,license \
  --severity HIGH,CRITICAL \
  registry.example.com/myapp:v1.2.3

# 2. 签名:Harbor 支持 Cosign,构建时签名
cosign sign --key cosign.key registry.example.com/myapp:v1.2.3

# 3. Harbor 策略:阻止「高危漏洞」或「未签名」镜像被拉取
#   项目 → 配置 → 漏洞级别策略 → 高危阻断 pull

4.4 客户端配置(各节点)

# 登录(内网/自签证书)
docker login registry.example.com

# 自签证书需加到各节点信任
mkdir -p /etc/docker/certs.d/registry.example.com
cp ca.crt /etc/docker/certs.d/registry.example.com/ca.crt
systemctl restart docker

# 拉取(自动选本机架构)
docker pull registry.example.com/myapp:latest

5. 轻量替代方案(看团队规模)

工具定位特点适用
ZOT极简 OCI 仓库(Go 单二进制)无依赖、OCI 原生、Helm Chart、签名、webhook个人/小团队、边缘
Registry:2 + UIDocker 官方仓库最小可用,无扫描/配额最简内网
Nexus / Artifactory全功能制品库Maven/npm/PyPI/Docker 全支持大型企业、多语言
GitLab Registry随 GitLab 自带零额外部署、CI 集成深已用 GitLab 的团队
Gitea + GHCRGitea Actions + 包仓库轻量、Git+CI+包一体已用 Gitea 的个人/团队

6. 从 Docker Compose 迁移到 manifest list(GHCR 示例)

# 1. 构建多架构并推 GHCR
docker buildx build --platform linux/amd64,linux/arm64 \
  -t ghcr.io/username/myapp:latest --push .

# 2. 本机拉取验证
docker pull ghcr.io/username/myapp:latest
docker image inspect ghcr.io/username/myapp:latest --format '{{.Architecture}}'

# 3. 看 manifest list
docker buildx imagetools inspect ghcr.io/username/myapp:latest
# 输出:
#   Manifest List:
#     Platform: linux/amd64
#     Platform: linux/arm64

7. 常见坑 & 避坑指南

现象原因修正
构建 arm64 时 exec format errorQEMU 未注册 / 缺 binfmtdocker run --privileged tonistiigi/binfmt --install all
--load 多架构失败--load 只支持单架构到本地 docker多架构必须 --push 到仓库,或 --output type=oci,dest=x.tar
交叉编译 Go 出错缺 CGO_ENABLED=0、静态链接Go 加 CGO_ENABLED=0;Rust 用 --target + cross-rs
Node/Python arm64 构建慢QEMU 模拟运行用官方多架构 base,或 arm64 真实 Runner
GHCR 拉取慢默认 docker.io 源被墙/慢配镜像加速 ghcr.io 或改 registry-mirrors
Harbor 自签证书不信任各节点无 CA分发 CA 到 /etc/docker/certs.d/
推上去了但拉下来是错架构客户端缓存 / manifest 混docker buildx imagetools inspect 检查 manifest list
镜像太大构建层冗余多阶段构建、--platform=$BUILDPLATFORM 构建阶段只跑编译工具

8. 一键部署脚本(构建 + 推 + 扫 + 签)

#!/usr/bin/env bash
# build-release.sh —— 本地一键出多架构 + 推 GHCR + 扫描 + 签名
set -euo pipefail

IMAGE="ghcr.io/yourname/myapp"
VERSION="${1:-$(date +%Y%m%d%H%M)}"
PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"

echo ">>> 构建多架构镜像 $IMAGE:$VERSION"
docker buildx build \
  --platform "$PLATFORMS" \
  --tag "$IMAGE:$VERSION" \
  --tag "$IMAGE:latest" \
  --push .

echo ">>> CVE 扫描"
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image --severity HIGH,CRITICAL "$IMAGE:$VERSION"

echo ">>> 签名"
cosign sign --key cosign.key "$IMAGE:$VERSION"

echo ">>> 验证清单"
docker buildx imagetools inspect "$IMAGE:$VERSION"

echo "✅ 完成!各节点执行: docker pull $IMAGE:latest"

(完)

— 感谢阅读 —

一起交流

分享你的思考,让讨论更进一步。