准备编译环境
配置docker环境,开启跨架构特性
如果没有以下文件,则直接新建
sudo vi /etc/docker/daemon.json
在里面添加以下内容
{ "experimental": true }
重启docker服务,以加载更新配置
systemctl daemon-reload systemctl restart docker
检测是否成功开启,true
表示开启了
[root@]# docker version -f '{{.Server.Experimental}}' true
安装QEMU
运行以下命令,会从tonistiigi/binfmt容器中,安装qemu工具
[root@]# docker run --privileged --rm tonistiigi/binfmt --install all
快速测试
在amd64的机器上用docker运行arm64v8的容器,如果正常运行,则说明qemu环境已经成功启用
[root@]# docker run --rm arm64v8/alpine uname -a
WARNING: The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64) and no specific platform was requested Linux 869e16c62dd8 5.10.18-amd64-desktop #1 SMP Mon Mar 1 17:09:41 CST 2021 aarch64 Linux
进行多架构镜像构建
使用docker buildx一次构建多个架构
创建一个名为my-buildx的buildx实例,并启用
[root@]# docker buildx create --name my-buildx
[root@]# docker buildx use my-buildx
自行创建Dockerfile文件,以下示例文件用于创建jre17环境镜像
From buildpack-deps/sid-curl
RUN apt-get update && apt-get install -y openjdk-17-jre-headless && apt-get clean && rm -rf /var/lib/apt/lists/*
使用docker buildx build来构建多架构docker镜像, --platform可以指定要编译的架构类型,前提是From的镜像需要同时支持这些架构,否则会构建失败
docker buildx build --platform=linux/amd64,linux/arm64 -t .
如果想要在构建镜像完成后自动上传镜像,可以附加--push参数
docker buildx build --platform=linux/amd64,linux/arm64 -t . --push
使用docker manifest管理不同架构的镜像
实际上,正如我上面提到的,如果Dockerfile中From的镜像并不完全满足支持所有目标架构,则无法完成构建过程。
这时候,我们可以使用多个不同Dockerfile来编译不同架构的镜像,用manifest来把这些镜像打到一个相同的tag下面
创建以下文件
vi Dockerfile.jre-17-sid-curl
新增以下内容
From buildpack-deps/sid-curl RUN apt-get update && apt-get install -y openjdk-17-jre-headless && apt-get clean && rm -rf /var/lib/apt/lists/*
创建以下文件
vi Dockerfile.jre-17-riscv64-ubuntu
新增以下内容
From riscv64/ubuntu:23.04
RUN apt-get update && apt-get install -y openjdk-17-jre-headless && apt-get clean && rm -rf /var/lib/apt/lists/*
开始构建镜像
your_registry可以替换成实际的仓库地址,your_tag可以替换成实际的tag
docker build --platform=linux/amd64 -t your_registry:your_tag-amd64 -f Dockerfile.jre-17-sid-curl . docker build --platform=linux/riscv64 -t your_registry:your_tag-riscv64 -f Dockerfile.jre-17-riscv64-ubuntu .
上传镜像
docker push your_registry:your_tag-amd64 docker push your_registry:your_tag-riscv64
最后用docker manifest整合两个镜像到一个tag下面
docker manifest create your_registry:your_tag your_registry:your_tag-amd64 your_registry:your_tag-riscv64
上传manifest,这步需要在线执行
docker manifest push your_registry:your_tag