使用 Docker Buildx 构建多种系统架构镜像

1. 工具说明

  • 安装 Docker >= 19.03: 该 Docker 版本包含 buildx 。
  • 安装 buildx: https://github.com/docker/buildx#in
  • linux kernel >= 4.8: 自该 Linux 内核版本 binfmt_misc 支持 fix-binary (F) flag 。fix_binary 标志允许内核在容器或 chroot 内使用 binfmt_misc 注册的二进制格式处理程序,即使该处理程序二进制文件不是该容器或 chroot 内可见的文件系统的一部分 。
Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 Moby BuildKit 提供的功能 。提供了与 docker build 相同的用户体验,并增加了许多新功能 。
 
BuildKit 是下一代的镜像构建组件,主要特点有很多,本文主要使用其可以编译多种系统架构的特性 。
 
网址:
https://github.com/moby/buildkit
 
需要注意的是,该功能仅适用于 Docker v19.03+ 版本 。
 
本文将讲解如何使用 Buildx 构建多种系统架构的镜像 。
 
在开始之前,已经默认你在 Linux 系统(各大发行版)下安装好了 64 位的 Docker 。
 
在写本文时,使用的 Docker 版本号是 19.03.11 。
 
root@i-3uavns2y:~#dockerversionClient:DockerEngine-CommunityVersion:19.03.11APIversion:1.40Goversion:go1.13.10Gitcommit:42e35e61f3Built:MonJun109:13:482020OS/Arch:linux/amd64Experimental:trueServer:DockerEngine-CommunityEngine:Version:19.03.11APIversion:1.40(minimumversion1.12)Goversion:go1.13.10Gitcommit:42e35e61f3Built:MonJun109:12:262020OS/Arch:linux/amd64Experimental:falsecontainerd:Version:1.2.13GitCommit:7ad184331fa3e55e52b890ea95e65ba581ae3429runc:Version:1.0.0-rc10GitCommit:dc9208a3303feef5b3839f4323d9beb36df0a9dddocker-init:Version:0.18.0GitCommit:fec3683root@i-3uavns2y:~#uname-aLinuxi-3uavns2y4.15.0-55-generic#60-UbuntuSMPTueJul218:22:20UTC2019x86_64x86_64x86_64GNU/Linux 
2. 运行原理 
Buildx 本质上调用了 buildkit 的 api,构建是在 buildkit 的环境中进行的 。是否支持多架构,取决于 buildkit 的环境,如果需要 buildkit 支持多架构,需要在宿主机执行(当然这个不是必须的,按构建的需求进行控制)
 
BuildKit 旨在为多个平台进行构建,而不仅适用于调用构建的用户碰巧运行的体系结构和操作系统 。
调用构建时,您可以设置--platform 标志以指定构建输出的目标平台(例如 linux/amd64,linux/arm64、 或 darwin/amd64) 。
 
当当前构建器实例由 docker-container 或 kubernetes 驱动程序支持时,您可以一起指定多个平台 。在这种情况下,它会构建一个清单列表,其中包含所有指定架构的类型 。当你在 docker run or 中使用这个镜像时 docker service,Docker 会根据节点的平台选择正确的镜像 。
 
您可以使用 Buildx 和 Dockerfiles 支持的三种不同策略构建多平台镜像:
  • 1 在内核中使用 QEMU 仿真支持
  • 2 使用相同的构建器实例在多个本机节点上构建
  • 3 使用 Dockerfile 中的一个阶段交叉编译到不同的架构
如果您的节点已经支持 QEMU,那么 QEMU 是最简单的入门方式(例如,如果您使用的是 Docker Desktop) 。它不需要对 Dockerfile 进行任何更改,并且 BuildKit 会自动检测可用的二级架构 。当 BuildKit 需要为不同的架构运行二进制文件时,它会通过在 binfmt_misc 处理程序中注册的二进制文件自动加载它 。
 
要使 binfmt


    推荐阅读