一、场景描述
一次构建多处部署的镜像分发显著提高了应用的交付效率。对于需要在不同平台部署应用的情况,利用 docker buildx 构建跨平台的镜像是一种快捷高效的解决方案。
通常,常见做法是为每个平台单独构建一个版本。但当用于开发的平台与部署的目标平台不同时,实现这一目标并不容易。例如,在 x86 架构上开发一个应用程序,然后将其部署到 ARM 平台的机器上,通常需要准备 ARM 平台的基础设施用于开发和编译。
二、使用Buildx
默认的 docker build 命令无法实现跨平台构建任务,因此我们需要安装 buildx 插件来扩展其功能。Docker Buildx 提供了一种更灵活、高效且支持多平台构建的方法,适用于各种复杂的构建场景。它可以通过简单的命令行参数来扩展 Docker 构建的功能,使得容器镜像的构建变得更加便捷和高效。
在 Linux 环境中,QEMU 提供了一个称为用户态模式(User mode)的模拟模式。通过在 Linux 内核中注册一个二进制转换处理程序,QEMU 在程序运行时会动态地翻译目标架构的二进制文件,以便在当前系统的 CPU 架构上运行。这种模式的最终效果就是,我们可以在本地环境中仿真运行目标 CPU 架构的二进制文件。
借助 QEMU 的用户态模式,我们能够创建轻量级的虚拟机环境(如 chroot 或容器),在这个环境中进行编译工作,与在本地环境中进行编译没有本质区别,操作简单高效。事实上,这个特性也被广泛地应用于 Docker 镜像的跨平台构建。
通过利用用户态模式,我们能够在不同 CPU 架构之间灵活切换,为软件开发和部署提供了极大的便利性和灵活性。这种技术不仅在开发过程中有着广泛的应用,也是在容器技术中实现跨平台构建的重要基础。
2、Docker Buildx功能
多平台构建:
Buildx 允许你在单个命令中构建多个架构的容器镜像,从而支持在不同的 CPU 架构上运行。这对于跨平台开发和部署非常有用,特别是在混合架构的环境中。
构建缓存:
Buildx 支持本地
实验性功能:
Buildx 提供了对一些实验性功能的支持,比如使用 --platform
选项指定目标平台、使用 --build-arg BUILDKIT_INLINE_CACHE=1
开启内联缓存等。
并发构建:
Buildx 允许同时在多个节点上构建多个镜像,从而提高构建效率。
外部构建器:
通过与外部构建器(如 QEMU)结合使用,Buildx 可以支持在一个架构上构建另一个架构的镜像。
镜像导出:
Buildx 可以将构建的镜像导出为 tar 文件,方便在没有 Docker 环境的地方使用。
3、Docker Buildx使用
3.1:启用Docker Buildx
macOS 或 Windows 系统的 Docker Desktop,以及 Linux 发行版通过 deb 或者 rpm 包所安装的 docker 内置了 buildx
,不需要另行安装。
- 查看buildx是否可用
docker buildx version
如果你的 docker 没有 buildx 命令,可以下载二进制包进行安装:
- 首先从 Docker buildx 项目的 release 页面找到适合自己平台的二进制文件。
- 将下载的二进制文件下载到你的本地机器上,并确保文件名为 docker-buildx。
- 将 docker-buildx 二进制文件移动到 Docker 的插件目录
~/.docker/cli-plugins
。如果该目录不存在,可以先创建它。
mv docker-buildx ~/.docker/cli-plugins/
- 确保二进制文件具有执行权限。
chmod +x ~/.docker/cli-plugins/docker-buildx
4、启用 binfmt_misc
Docker for Linux 不支持构建 arm 架构镜像,我们可以运行一个新的容器让其支持该特性。如果你使用的是 Docker 桌面版(MacOS 和 Windows),默认已经启用了 binfmt_misc
,可以跳过这一步。
注意:Linux 内核版本需要 4.x 以上,特别是 CentOS7 系统,默认是3.10
[root@DevOps ~]# docker run --rm --privileged tonistiigi/binfmt:latest --install all
# 验证是 binfmt_misc 否开启:
[root@DevOps ~]# ls -al /proc/sys/fs/binfmt_misc
- 验证是否启用了相应的处理器
[root@DevOps ~]# cat /proc/sys/fs/binfmt_misc/qemu-arm
# 这表示 binfmt_misc 对象(在这里是 qemu-arm)是启用的
enabled
# 这是指定用于解释目标架构二进制文件的解释器。这里使用的是/usr/bin/qemu-arm
interpreter /usr/bin/qemu-arm
# 这是一组标志,它们指示了如何处理目标二进制文件。
flags: OCF
# 这个字段指示了在目标文件的哪个偏移量开始执行解释器。
offset 0
# 这个字段描述了目标文件的特征码,也就是一个标志序列,用于识别文件的格式。
magic 7f454c4601010100000000000000000002002800
# 这个字段定义了哪些部分是需要匹配的,哪些部分是通配符。
mask ffffffffffffff00fffffffffffffffffeffffff
5、切换多平台构建器
由于 Docker 默认的构建器实例不支持同时指定多个 --platform
,因此我们需要首先手动创建一个新的构建器实例并进行相应的替换。
5.1:创建新的Buildx构建器
注意:如果你是私有仓库,并且是http没有证书的情况下创建构建器实例时,需要指定–driver-opt network=host 和 –config /etc/buildkit/buildkitd.toml 两个参数,而且需要在Docker的daemon.json中添加”insecure-registries”: [“私有仓库地址地址或者域名”]
- 创建
/etc/buildkit/buildkitd.toml
配置文件,并填写下面的配置内容
[root@DevOps ~]# vim /etc/buildkit/buildkitd.toml
debug = true
# insecure-entitlements allows insecure entitlements, disabled by default.
insecure-entitlements = [ "network.host", "security.insecure" ]
# optionally mirror configuration can be done by defining it as a registry.
[registry."私有仓库地址IP或者域名"]
http = true
insecure = true
- 创建一个名为 my-builder 的新构建器,并将其设置为当前活动构建器
[root@DevOps ~]# docker buildx create --name my-builder --use --driver-opt network=host --config /etc/buildkit/buildkitd.toml
上面指令介绍:
docker buildx create
: 这是创建 Docker Buildx 构建器的命令。--name my-builder
: 这个选项用于指定构建器的名称,这里构建器被命名为 my-builder。--use
: 这个选项表示在创建后立即使用新创建的构建器。--driver-opt network=host
: 这是一个构建器驱动选项,它在构建器后台运行的时候将使用宿主机的网络命名空间。这样构建器就可以访问宿主机上的网络资源。--config /etc/buildkit/buildkitd.toml
: 这个选项用于指定构建器的配置文件路径。在这里,它指定了配置文件为/etc/buildkit/buildkitd.toml
。
5.2:检查当前部署的构建器
[root@DevOps ~]# docker buildx inspect
5.3:启动新的Buildx构建器
[root@DevOps ~]# docker buildx inspect my-builder --bootstrap
5.4:检查当前使用的构建器
- 查看当前使用的构建器及构建器支持的 CPU 架构
[root@DevOps ~]# docker buildx ls
三、构建多平台镜像
1、创建Dockerfile
- 创建一个最简单的容器应用来进行操作说明
[root@DevOps ~]# vim Dockerfile
# 通过 --platform=$TARGETPLATFORM指定平台的Alpine 镜像作为基础
FROM --platform=$TARGETPLATFORM alpine
# 运行 uname 命令并将输出写入 os.txt 文件
RUN uname -a > /os.txt
# 设置容器启动时默认执行的命令
CMD cat /os.txt
2、构建镜像并推送
- 推送之前,先登入私有镜像仓库
[root@DevOps ~]# docker login <私有镜像仓库>
Username: 用户
Password: 密码
Login Succeeded
执行构建,使用 – -push 参数推送到镜像仓库
[root@DevOps ~]# docker buildx build --platform linux/arm64,linux/amd64 -t 私有仓库地址/public/REPOSITORY[:TAG] --push .
查看私有镜像仓库项目下是否有多个不通架构的镜像
3、测试多平台镜像
运行结束后可以通过 docker buildx imagetools 探查已推送到远程仓库的镜像:
[root@DevOps ~]# docker buildx imagetools inspect 私有仓库地址/public/REPOSITORY[:TAG]
由于我们在本机已经启用了 binfmt_misc,现在可以在本地系统上运行任何 CPU 架构的 Docker 镜像了。这意味着我们可以在本地直接测试这些镜像,确保它们没有问题。
这里可以直接拉取不同CPU架构镜像的sha256 值拉取
[root@DevOps ~]# docker run -it --rm 私有仓库地址/public/demo:v1.0@sha256:xxx
必须 注册 为本站用户, 登录 后才可以发表评论!