注1:构建的镜像会推送到Docker Hub(docker官方仓库),所以需要在Docker Hub网站注册个人账号,以下使用的cf2021docker均为个人docker账号id。

注2:QEMU通过binfmt_misc在主机上注册二进制文件来模拟不同操作系统,前提:

centos内核>=4.8

binfmt-support>=2.1.7.

docker>=19.03+

step1:新建 builder 实例
Docker for Linux 不支持构建 arm 架构镜像,我们可以运行一个新的容器让其支持该特性,Docker 桌面版无需进行此项设置。这里是通过QUME支持多CPU架构。QUME安装命令:
(1) 安装所有支持类型
$ docker run --rm --privileged tonistiigi/binfmt:latest --install all


docker run 命令会从指定的镜像创建一个新的容器,并运行该容器。

--rm 选项表示在容器退出后自动删除容器;

--privileged 选项表示运行以特权模式运行容器(容器可以访问宿主机的所有设备);tonistiigi/binfmt:latest 是要运行的 Docker 镜像,latest 是镜像的标签;

--install all 是传递给容器的命令行参数。


(2) 安装指定类型
docker run --rm --privileged tonistiigi/binfmt:latest --install linux/arm64,linux/arm


卸载指定QUME:docker run --privileged --rm tonistiigi/binfmt --uninstall qemu-aarch64 

卸载所有QUME:docker run --privileged --rm tonistiigi/binfmt --uninstall qemu-*


        由于 Docker 默认的 builder 实例不支持同时指定多个 --platform,我们必须首先创建一个新的 builder 实例。
        同时由于国内拉取镜像较缓慢,我们可以使用配置了 镜像加速地址 的 dockerpracticesig/buildkit:master 镜像替换官方镜像。

# 适用于国内环境(我用的)
$ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master


# 适用于腾讯云环境(腾讯云主机、coding.net 持续集成)
$ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master-tencent

备注:

        Buildx 命令中的--driver和--driver-opt是用来指定buildx驱动的,可以通过docker buildx create --help来查看各自的作用。常用的有两种驱动:docker 与 docker-container:
        1)–driver docker,表示使用绑定到 dockerd 的 BuildKit 工具来进行构建操作。但是,由于绑定到 dockerd 的 Buildkit 库使用不同的存储组件,所以该驱动未支持某些特性。比如说,--platform只能指定一个参数,不支持多平台同时构建。
        2)–driver docker-container,表示使用容器运行 BuildKit 工具,在此容器中执行构建任务。而该构建方式产生的镜像,无法直接通过 docker images 查看,需要指定 –output 选项来导出。

step2:docker buildx use mybuilder-cn (step1中已经指定了--use, step2不用执行了)

step3:我的Dockerfile在f:/test,就在此目录下执行,默认根据Dockerfile构建镜像
docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t cf2021docker/hello . --push

这步需要注意:如果是在linux上,需要先执行:
docker login --username xxx --password xxxx
这样,个人登陆信息会被记录到/home/admin/.docker/config.json  的auths字段。不同用户登陆,这个字段信息会被替换成最新的登陆信息。如果没有登陆,授权信息有可能不是自己的,当执行buildx build xxx --push 时会报“failed with status: 401 Unauthorized”。 

Dockerfile内容入下: 

docker war包配置文件 docker build from_docker

# TARGETPLATFORM 是架构变量,指构建镜像主机平台,例如 linux/amd64,系统会自动匹配当前主机平台参数
FROM --platform=$TARGETPLATFORM alpine

# 执行uname -a命令,并把命令的输出结果写入目录文件/os.txt
RUN uname -a > /os.txt

# 查看os.txt的文件内容
CMD cat /os.txt

step4:在不同架构下加载镜像
(1)先检查下,列出每个镜像的 digests: 
docker buildx imagetools inspect cf2021docker/hello

或者登陆docker.hub网站,看看自己的账号下cf2021docker/hello镜像是否已存在。

(2)在鲲鹏华为云上测试

[admin@hadoop2 ~]$  docker run -it --rm cf2021docker/hello
 Unable to find image 'cf2021docker/hello:latest' locally
 latest: Pulling from cf2021docker/hello
 9b3977197b4f: Pull complete 
 4fdaf3797dc8: Pull complete 
 Digest: sha256:8b83cfa443096d7755ab9736916f677683877474e988fa17aabdfac64b366c39
 Status: Downloaded newer image for cf2021docker/hello:latest
 Linux buildkitsandbox 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 aarch64 Linux

案例参考:使用 buildx 构建多种系统架构支持的 Docker 镜像 · Docker —— 从入门到实践 · 看云