前置条件
- Docker >= 19.03: 自该 Docker 版本包含 buildx。
- Linux kernel >= 4.8: 推荐使用Ubuntu 18.04 以上的 TLS 发行版, iso镜像地址自该Linux内核版本 binfmt_misc 支持 fix-binary (F) flag。fix_binary 标志允许内核在容器或chroot内使用binfmt_misc注册二进制格式处理程序(将其它平台可执行文件的处理程序注册进来),当 Linux 遇到无法识别的可执行文件(其它平台的可执行文件格式)时,它会检查“用户空间应用程序”是否存在能处理该执行文件的处理程序,如果有,就将可执行文件传递给该程序处理。
- binfmt_misc file system mounted: 需要挂载binfmt_misc文件系统,以便用户空间工具可以控制此内核功能,即注册和启用处理程序。
- 如果是使用的 Docker Desktop,Docker Desktop >= 2.1.0
搭建过程
- 启用buildx
- 开启实验特性
- 查看实验特性是否开启
docker info |grep Experimental
- 如果没有开启,需要在/etc/docker/daemon.json中添加以下配置
$vim /etc/docker/daemon.json
{ "experimental": true }
- systemctl daemon-reload
- systemctl restart docker
如果还是不能运行buildx,应该不是通过 DEB or RPM方式安装,需要手动安装buildx
- 安装buildx
- 为文件赋予执行权限
chmod +x ~/.docker/cli-plugins/docker-buildx
- 下载最新版本的二进制文件,将其复制到~/.docker/cli-plugins文件夹中并重命名为 docker-buildx
下载地址:https://github.com/docker/buildx
mv ./docker-buildx ~/.docker/cli-plugins
- 配置 binfmt_misc
如果使用 Docker Desktop(MacOS 和 Windows),因为默认配置了
binfmt_misc
,可以跳过这一步。如果使用 Linux 发行版操作系统需要自行安装配置
binfmt_misc
,以便能够非原生的其它平台的镜像。QEMU 和 binfmt_misc 支持工具可以通过宿主机或者Docker 容器镜像安装。使用Docker镜像安装配置能让事情变得更加简单。安装命令如下
docker run --privileged --rm tonistiigi/binfmt --install all
执行完后,我们验证下是否注册成功了。成功注册后,
/proc/sys/fs/binfmt_misc
目录中会有多个qemu-
前缀的文件。查看/proc/sys/fs/binfmt_misc/qemu-aarch64
文件内容,可以看到 falgs 标志为OCF
,说明这个处理程序是通过 (F)标志注册的,能够正常的结合 buildx 完成跨平台构建。QEMU 是一个很棒的开源项目,它可以模拟多种平台。将 QEMU 和 Docker 结合起来使用能使得我们更容易的构建跨平台的容器镜像。集成 QEMU依赖于 Linux 内核功能 。Linux 内核中的
binfmt_misc
功能可以使得内核识别任意类型的可以执行文件格式,并传递到特定的用户空间应用程序和虚拟机。当 Linux 遇到一种无法识别的可执行文件格式(比如说其它平台的可执行文件格式)时,它会检查有没有配置任何“用户空间应用程序”用于处理它。如果检测到了,就将可执行文件传递给该应用程序。为此,我们需要在内核当中注册其它平台的可执行文件格式。
- 编写测试Dockerfile
FROM --platform=$TARGETPLATFORM alpine RUN uname -a > /os.txt CMD cat /os.txt
- 使用buildx构建
因为 Docker 默认的 builder 是不支持多平台构建的,为了使用多平台构建功能,我们需要新建一个 builder,并设置当前 builder 为新建的。
# 镜像设置参考:https://www.kancloud.cn/docker_practice/docker_practice/2002053 # 新建同时切换 builder,由于国内拉取镜像较缓慢,为builder实例设置镜像 docker buildx create --use --name=mybuilder --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master # 只新建,然后再切换 builder docker buildx create --name mybuilder --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master docker buildx use mybuilder
我们可以通过
docker buildx ls
查看当前节点上的 builder 有哪些
- 登录dockerHub
docker login
- 构建镜像并推送至dockerhub
参考:https://www.kancloud.cn/docker_practice/docker_practice/2002053
docker buildx build --platform linux/amd64,linux/arm64 -t username/test-for-buildx -f DockerFile . --push
注意
- 其中username替换为自己的 Docker Hub 用户名
其他命令记录
查看镜像支持的平台信息 docker buildx imagetools inspect hellozf/test-for-buildx 查看builder实例信息 docker buildx ls 删除builder实例 docker buildx rm 实例名 加载到本地( 无法一次加载多个平台的镜像到本地仓库,所以一个一个进行了加载 ) docker buildx build -t username/test-for-buildx --platform linux/amd64 -f DockerFile . --load docker buildx build -t username/test-for-buildx --platform linux/arm64 -f DockerFile . --load
参考
https://github.com/docker/buildx
https://www.kancloud.cn/docker_practice/docker_practice/2002053
https://www.wenjiangs.com/doc/qk4gvwo76e
https://segmentfault.com/a/1190000038662022
https://zhuanlan.zhihu.com/p/511273048
https://blog.csdn.net/Canger_/article/details/122239139