注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内容入下:
# 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 —— 从入门到实践 · 看云