1、需求背景#
在平时工作中,时常会碰到多架构镜像,或者是需要根据AMD的镜像重新构建一个ARM架构的镜像。但是目前ARM的主机常常是在内网环境,在处理构建和本地测试时不能及时处理,需要等待资源。
所以根据以上问题,本文记录在自己电脑X86机器上如何实现以下两种需求
1、在X86机器上构建ARM架构镜像;
2、在X86机器上运行ARM架构镜像;
主要问题在于指令集兼容性问题,所以需要引入QEMU用户态仿真和Docker Buildx(BuildKit引擎)
2、准备工作#
基础环境
— 操作系统: RockyLinux
— 内核版本: 6.12.0-55.12.1.el10_0.x86_64
— Docker: 28.1.0
2.1、启用QEMU仿真支持#
(1)、需要安装并注册QEMU的用户态二进制文件到内核中,最简单的方法是运行一个特殊的Docker容器来完成注册
# 运行此容器会自动在内核中注册各种架构的解释器
[root@localhost ~]# docker run --privileged --rm tonistiigi/binfmt --install all
Unable to find image 'tonistiigi/binfmt:latest' locally
latest: Pulling from tonistiigi/binfmt
4b3e935ac1b8: Pull complete
cba9db6f3ddf: Pull complete
Digest: sha256:d3b963f787999e6c0219a48dba02978769286ff61a5f4d26245cb6a6e5567ea3
Status: Downloaded newer image for tonistiigi/binfmt:latest
installing: s390x OK
installing: ppc64le OK
installing: arm64 OK
installing: arm OK
installing: riscv64 OK
installing: mips64le OK
installing: mips64 OK
installing: loong64 OK
{
"supported": [
"linux/amd64",
"linux/amd64/v2",
"linux/amd64/v3",
"linux/amd64/v4",
"linux/arm64",
"linux/riscv64",
"linux/ppc64le",
"linux/s390x",
"linux/386",
"linux/mips64le",
"linux/mips64",
"linux/loong64",
"linux/arm/v7",
"linux/arm/v6"
],
"emulators": [
"qemu-aarch64",
"qemu-arm",
"qemu-loongarch64",
"qemu-mips64",
"qemu-mips64el",
"qemu-ppc64le",
"qemu-riscv64",
"qemu-s390x"
]
}shell(2)、检验方式,查看/proc/sys/fs/binfmt_misc/是否有qemu-aarch64文件
[root@localhost ~]# ls /proc/sys/fs/binfmt_misc/
qemu-aarch64 qemu-arm qemu-loongarch64 qemu-mips64 qemu-mips64el qemu-ppc64le qemu-riscv64 qemu-s390x register status
[root@localhost ~]# cat /proc/sys/fs/binfmt_misc/qemu-aarch64
enabled
interpreter /usr/bin/qemu-aarch64
flags: POCF
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffffshell2.2、启用Docker Buildx#
buildx是Docker的一个插件,支持构建多架构镜像,但是默认没有安装(新版Docker中是一个独立的二进制文件)。
2.2.1、安装Docker Buildx插件#
(1)、通过DNF/YUM安装
dnf install docker-buildx-plugin -yshell(2)、手动安装
# 创建插件目录
mkdir -p ~/.docker/cli-plugins/
# 下载最新版 (以v0.33.0为例,请根据实际情况调整)
curl -SL https://github.com/docker/buildx/releases/download/v0.33.0/buildx-v0.33.0.linux-amd64 -o ~/.docker/cli-plugins/docker-buildx
# 赋予执行权限
chmod +x ~/.docker/cli-plugins/docker-buildx
# 验证
docker buildx versionshell2.2.2、创建并启动多架构构建器(Builder)#
一般Docker使用默认构建器,只支持宿主机架构,但是可以通过创建一个BuildKit容器作为构建驱动
docker buildx create --name multiarch --use --platform linux/amd64,linux/arm64
# 或 docker buildx create --name multiarch --driver docker-container --use
# 启动并初始化该构建器
docker buildx inspect --bootstrapshelldocker buildx create: 创建实例
—name multiarch: 命名为multiarch
—use: 立即切换新的构建器
—platform linux/amd64,linux/arm64: 指定该构建器可以支持哪些目标平台
但是在本文中,因为一开始创建了QEMU仿真支持,当前默认的default构建器已经支持多架构构建
[root@localhost ~]# docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
default* docker
\_ default \_ default running v0.21.0 linux/amd64 (+4), linux/arm64, linux/arm (+2), linux/ppc64le, (6 more)
shell#添加代理方式,docker buildx插件和docker的代理不通用,如果需要拉取docker hub的镜像,需要添加为你自己的代理端口
docker buildx create --name image_buildx --driver-opt env.http_proxy=127.0.0.1:7890 --driver-opt env.https_proxy=127.0.0.1:7890 --useplaintext3、场景验证#
3.1、场景一:在x86上Build ARM镜像#
利用docker buildx,可以直接构建并推送ARM镜像,或者将其保存到本地
# 构建 arm64 镜像并直接推送到仓库
docker buildx build --platform linux/arm64 -t your-repo/your-app:latest --push .
# 或者构建并导出到本地 docker images (注意:--load 不支持多架构同时导出,只能单选)
docker buildx build --platform linux/arm64 -t your-app:arm64 --load .shell3.2、场景二:在x86上Run ARM镜像#
只要完成了上述QEMU 注册,运行ARM镜像对此来说与运行原生镜像几乎没有区别。Docker会自动识别镜像架构并调用qemu-aarch64
docker run --rm --platform linux/arm64 arm64v8/alpine uname -mshell4、 常见问题#
- 性能损耗:由于是指令集模拟,跨架构运行镜像的速度会比原生慢2~10倍,不建议用于生产环境的高负载任务。
- 构建失败:若构建过程中报错
exec format error,通常是因为binfmt未正确注册或在重启后失效,需重新运行tonistiigi/binfmt容器。 - 多架构镜像查看:可以使用
docker manifest inspect <image_name>查看远程镜像包含的所有架构信息。