docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > Docker多架构镜像构建

Docker多架构镜像构建全过程

作者:techzhi

文章介绍了如何使用DockerBuildx工具实现一次构建同时支持ARM64和AMD64平台的Docker镜像,并详细描述了构建过程、技术方案和问题排查,最终,通过脚本使用指南和常见问题解答,帮助用户更好地理解和使用该工具

一、背景与需求

1.1 原有方案

项目原有两个独立的构建脚本:

脚本用途构建命令
docker_build_arm.sh构建 ARM 镜像docker build
docker_build_x86.sh构建 x86 镜像docker build --platform linux/amd64

痛点

1.2 目标方案

实现一个统一的构建脚本 docker_build.sh,支持:

二、技术方案

2.1 核心技术:Docker Buildx

Docker Buildx 是 Docker 官方的多架构构建工具,基于 BuildKit 实现。

架构原理

                         ┌─ linux/amd64 镜像层
registration_info:v1.0 ──┤
                         └─ linux/arm64 镜像层

一个镜像 tag 包含多架构 manifest,部署时 Docker 自动选择对应架构。

2.2 构建策略

场景Driver说明
单架构构建docker (默认)使用本地 Docker daemon,可利用本地镜像缓存
多架构构建docker-container在独立 BuildKit 容器中构建,支持跨架构

2.3 输出格式

模式格式导入方式
单架构导出Docker tardocker load < image.tar
多架构导出OCI tardocker load < image.tar
推送仓库Registrydocker pull registry/image:tag

三、实施过程

3.1 环境要求

# 检查 Docker 版本(需要 19.03+)
docker version
# 实际版本: 29.1.4

# 检查 Buildx 是否可用
docker buildx version
# 实际版本: v0.30.1

3.2 创建构建脚本

创建 docker_build.sh,主要功能:

# 参数解析
--push              # 推送到私有仓库
--save              # 导出为离线 tar 包
--registry <addr>   # 私有仓库地址(默认: 192.168.50.32)
--platform <p>      # 目标平台: amd64, arm64, all(默认: all)
--version <ver>     # 镜像版本(默认: 时间戳)
--skip-build        # 跳过 Maven 构建

3.3 安装 QEMU 模拟器

在 x86 机器上构建 ARM 镜像需要 QEMU:

# 安装 ARM64 QEMU 模拟器
docker run --rm --privileged tonistiigi/binfmt --install arm64

# 验证支持的架构
# 输出: linux/amd64, linux/arm64, ...

四、问题排查与解决

4.1 问题一:单架构构建时 docker driver 不支持导出

现象

ERROR: Docker exporter is not supported for the docker driver.

原因

docker buildx build --output type=docker,dest=file.tar

在使用默认 docker driver 时不支持直接导出到文件。

解决方案

单架构导出时改用传统的 docker build + docker save 方式:

# 单架构构建
docker build --platform linux/amd64 -t image:tag .
docker save -o image.tar image:tag

4.2 问题二:跨架构构建报 exec format error

现象

exec /bin/sh: exec format error

原因

在 x86 机器上构建 ARM 镜像时,需要 QEMU 模拟器来执行 ARM 二进制文件。

解决方案

# 安装 QEMU
docker run --rm --privileged tonistiigi/binfmt --install arm64

4.3 问题三:Buildx 无法访问 Docker Hub(核心问题)

现象

ERROR: failed to do request: Head "https://registry-1.docker.io/v2/...":
dial tcp xxx:443: i/o timeout

原因分析

构建方式Driver网络环境镜像缓存
docker builddocker宿主机网络使用宿主机缓存
docker buildx (多架构)docker-container独立容器网络独立缓存,需重新拉取

关键区别:

验证步骤

# 检查宿主机是否能访问 Docker Hub
curl -s --connect-timeout 5 https://registry-1.docker.io/v2/
# 返回 UNAUTHORIZED 说明可以连接

# 查看宿主机镜像加速器配置
cat /etc/docker/daemon.json
# 已配置: docker.1ms.run, docker.xuanyuan.me

解决方案

步骤一:创建 BuildKit 配置文件

mkdir -p ~/.docker/buildx

cat > ~/.docker/buildx/buildkitd.toml << 'EOF'
[registry."docker.io"]
  mirrors = ["docker.1ms.run", "docker.xuanyuan.me"]
EOF

步骤二:创建使用该配置的 Builder

# 删除旧的 builder
docker buildx rm multiarch 2>/dev/null || true

# 创建新的 builder,关键参数:
# --driver-opt network=host  使用宿主机网络
# --config                   指定 buildkit 配置文件
docker buildx create \
  --name multiarch \
  --driver docker-container \
  --driver-opt network=host \
  --config ~/.docker/buildx/buildkitd.toml \
  --use

# 启动并验证
docker buildx inspect --bootstrap

验证配置生效

File#buildkitd.toml:
 > [registry]
 >   [registry."docker.io"]
 >     mirrors = ["docker.1ms.run", "docker.xuanyuan.me"]

五、最终测试结果

测试场景命令结果输出
单架构 AMD64--save --platform amd64✅ 成功*_amd64.tar (300M)
单架构 ARM64--save --platform arm64✅ 成功*_arm64.tar (324M)
多架构--save✅ 成功*_multiarch.tar (258M)

六、脚本使用指南

6.1 基本用法

# 查看帮助
./docker_build.sh --help

6.2 导出离线 tar 包

# 导出多架构包(ARM64 + AMD64)
./docker_build.sh --save

# 导出指定版本
./docker_build.sh --save --version 1.2.0

# 只导出 x86 架构
./docker_build.sh --save --platform amd64

# 只导出 ARM 架构
./docker_build.sh --save --platform arm64

# 跳过 Maven 构建(jar 包已存在时)
./docker_build.sh --save --skip-build

6.3 推送到私有仓库

# 推送到默认仓库 (192.168.50.32)
./docker_build.sh --push

# 推送到指定仓库
./docker_build.sh --push --registry 10.0.0.100

# 指定版本推送
./docker_build.sh --push --version 1.2.0

6.4 输出文件说明

命令输出文件格式
--saveimages/registration_info_<版本>_multiarch.tarOCI
--save --platform amd64images/registration_info_<版本>_amd64.tarDocker
--save --platform arm64images/registration_info_<版本>_arm64.tarDocker

6.5 目标机器导入

# 导入镜像
docker load < registration_info_<版本>_multiarch.tar

# 查看导入的镜像
docker images | grep registration_info

七、常见问题 FAQ

Q1: 首次运行多架构构建很慢?

首次运行需要:

后续构建会使用缓存,速度会快很多。

Q2: 如何更新镜像加速器地址?

编辑配置文件:

vim ~/.docker/buildx/buildkitd.toml

然后重建 builder:

docker buildx rm multiarch
# 下次运行脚本会自动重建

Q3: 如何清理构建缓存?

# 清理 buildx 缓存
docker buildx prune

# 清理所有缓存(谨慎使用)
docker buildx prune -a

Q4: 多架构包比单架构包小?

是的,OCI 格式的多架构包使用了更高效的压缩和层去重,所以可能比两个单架构包加起来更小。

八、相关文件

文件说明
docker_build.sh多架构构建脚本
docker_build_arm.sh原 ARM 构建脚本(保留)
docker_build_x86.sh原 x86 构建脚本(保留)
~/.docker/buildx/buildkitd.tomlBuildKit 镜像加速器配置
Dockerfile镜像构建文件

参考资料:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文