使用 buildx 构建多平台 Docker 镜像
作者:互联网
文章目录
背景
回顾一下当前跨 CPU 架构编译程序的不同方法。
-
方法一:直接在目标硬件上编译
-
方法二:模拟目标硬件
-
方法三:通过 binfmt_misc 模拟目标硬件的用户空间
-
方法四:使用交叉编译器
-
新方案:
=>使用buildx构建多平台 Docker 镜像(无需修改dockerfile)
快速开始
1.查看buildx插件(要求docker大于19.03)
20.10.7是默认支持的
docker buildx version
github.com/docker/buildx v0.5.1-docker 11057da37336192bfc57d81e02359ba7ba848e4a
//如果提示docker: 'buildx' is not a docker command. 需要看下docker版本
2.Docker for Linux 不支持构建 arm
架构镜像,我们可以运行一个新的容器让其支持该特性
启用 binfmt_misc
//可以通过运行一个特权 Docker 容器来更方便的设置启用 binfmt_misc
docker run --rm --privileged tonistiigi/binfmt:latest --install all
//查看支持的处理器
ls -al /proc/sys/fs/binfmt_misc/
-rw-r--r-- 1 root root 0 Nov 6 08:10 qemu-aarch64
-rw-r--r-- 1 root root 0 Nov 6 08:10 qemu-arm
-rw-r--r-- 1 root root 0 Nov 6 08:10 qemu-mips64
-rw-r--r-- 1 root root 0 Nov 6 08:10 qemu-mips64el
-rw-r--r-- 1 root root 0 Nov 6 08:10 qemu-ppc64le
-rw-r--r-- 1 root root 0 Nov 6 08:10 qemu-riscv64
-rw-r--r-- 1 root root 0 Nov 6 08:10 qemu-s390x
//验证是否启用了指定的处理器 enabled即启用成功
cat /proc/sys/fs/binfmt_misc/qemu-aarch64
enabled
interpreter /usr/bin/qemu-aarch64
flags: OCF
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff
3.从默认的构建器切换到多平台构建器
由于 Docker 默认的 builder
实例不支持同时指定多个 --platform
,我们必须首先创建一个新的 builder
实例
Docker 默认会使用不支持多 CPU 架构的构建器,我们需要手动切换。
#由于 Docker 默认的 builder 实例不支持同时指定多个 --platform,我们必须首先创建一个新的 builder 实例。
#同时由于国内拉取镜像较缓慢,我们可以使用配置了 镜像加速地址 的 dockerpracticesig/buildkit:master 镜像替换官方镜像。
# 创建适用于国内环境的构建器
docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master
docker buildx inspect mybuilder --bootstrap
#查看构建器
docker buildx ls
#切换构建器
docker buildx use mybuilder-cn
4.可以使用 buildx 构建一个支持 arm、arm64 和 amd64 多架构的 Docker 镜像了
当前目录下新建一个dockerfile
FROM --platform=$TARGETPLATFORM alpine
RUN uname -a > /os.txt
CMD cat /os.txt
5.本地生成镜像
#本地保存,只能为每个架构生成一个镜像,不能合并成一个镜像
docker buildx build -t myname/hello-arm --platform=linux/arm -o type=docker .
docker buildx build -t myname/hello-arm64 --platform=linux/arm64 -o type=docker .
docker buildx build -t myname/hello-amd64 --platform=linux/amd64 -o type=docker .
# 查看镜像信息
docker buildx imagetools inspect myname/hello-arch
#运行
docker run -it --rm myname/hello-arm64
docker save -o hello-arm64.tar myname/hello-arm64
docker load -i hello-arm64.tar
架构相关变量
Dockerfile
支持如下架构相关的变量
TARGETPLATFORM
构建镜像的目标平台,例如 linux/amd64
, linux/arm/v7
, windows/amd64
。
TARGETOS
TARGETPLATFORM` 的 OS 类型,例如 `linux`, `windows
TARGETARCH
TARGETPLATFORM` 的架构类型,例如 `amd64`, `arm
TARGETVARIANT
TARGETPLATFORM` 的变种,该变量可能为空,例如 `v7
BUILDPLATFORM
构建镜像主机平台,例如 linux/amd64
BUILDOS
BUILDPLATFORM` 的 OS 类型,例如 `linux
BUILDARCH
BUILDPLATFORM` 的架构类型,例如 `amd64
BUILDVARIANT
BUILDPLATFORM` 的变种,该变量可能为空,例如 `v7
使用举例
例如我们要构建支持 linux/arm/v7
和 linux/amd64
两种架构的镜像。假设已经生成了两个平台对应的二进制文件:
bin/dist-linux-arm
bin/dist-linux-amd64
那么 Dockerfile
可以这样书写:
FROM scratch
# 使用变量必须申明
ARG TARGETOS
ARG TARGETARCH
COPY bin/dist-${TARGETOS}-${TARGETARCH} /dist
ENTRYPOINT ["dist"]
原理分析
可以使用 buildx 构建一个支持 arm、arm64 和 amd64 多架构的 Docker 镜像了,同时将其推送到 Docker Hub:
就可以通过 docker pull mirailabs/hello-arch
拉取刚刚创建的镜像了,Docker 将会根据你的 CPU 架构拉取匹配的镜像。
docker buildx build -t xxx/hello-arch --platform=linux/arm,linux/arm64,linux/amd64 . --push
背后的原理也很简单,
buildx 会通过 QEMU
和 binfmt_misc
分别为 3 个不同的 CPU 架构(arm,arm64 和 amd64)构建 3 个不同的镜像。
构建完成后,就会创建一个 manifest list,其中包含了指向这 3 个镜像的指针。
如果想将构建好的镜像保存在本地,可以将 type
指定为 docker
,但必须分别为不同的 CPU 架构构建不同的镜像,不能合并成一个镜像,即:
docker buildx build -t xxx/hello-arm --platform=linux/arm -o type=docker .
docker buildx build -t xxx/hello-arm64 --platform=linux/arm64 -o type=docker .
docker buildx build -t xxx/hello-amd64 --platform=linux/amd64 -o type=docker .
总结
使用 buildx
,我们无需对 Dockerfile 进行任何修改,就可以创建支持多种 CPU 架构的 Docker 镜像,然后将其推送到 Docker Hub。任何安装了 Docker 的系统都可以拉取到与它的 CPU 架构相对应的镜像。
未来 buildx 可能会成为 docker build
命令的一部分,最终所有上面提到的功能都会变成默认的功能,下沉到基础设施中交叉编译程序的做法将会变成远古时代的愚蠢行为。
参考
具体使用:
https://github.com/docker/buildx
参考:
https://fuckcloudnative.io/posts/multiarch-docker-with-buildx/
https://docker-practice.github.io/zh-cn/buildx/multi-arch-images.html
https://www.kancloud.cn/docker_practice/docker_practice/2002051
docker从入门到实践 :https://github.com/yeasy/docker_practice
标签:amd64,--,buildx,linux,镜像,Docker,docker 来源: https://blog.csdn.net/Edu_enth/article/details/121175964