准备给开源项目做一个镜像,由于当前使用的是 M1 型号的 Mac 电脑,打出来的镜像无法运行在 AMD 架构之上,但是在 dockerhub 上又见过一些比较大的项目的镜像,支持多平台,因此就了解了一波,本文记录一下实操过程。

在 docker 官方文档中,也有对这块儿内容的讲解,参考: Leverage multi-CPU architecture support (opens new window)

核心点是:Docker 在 19.03 版本引入了构建插件 buildx (opens new window) ,可以很轻松地构建多平台 Docker 镜像。

# 启用 buildx 插件

使用之前确保自己的 docker 版本不低于 19.03,通过如下方式查看自己的 docker 版本:

$ docker -v
Docker version 20.10.13, build a224086

1
2

启用 buildx 插件:

export DOCKER_CLI_EXPERIMENTAL=enabled

1

验证是否开启:

$ docker buildx version
github.com/docker/buildx v0.8.1 5fac64c2c49dae1320f2b51f1a899ca451935554

1
2

使用桌面版的 docker 已经提供 binfmt_misc 多架构支持,这意味着您可以为不同的 Linux 架构运行容器,例如 armmipsppc64le 甚至 s390x,因此不需要再单独配置。

# 从默认的构建器切换到多平台构建器

Docker 默认会使用不支持多 CPU 架构的构建器,我们需要手动切换。

先创建一个新的构建器:

$ docker buildx create --use --name mybuilder

1

然后启动构建器:

$ docker buildx inspect mybuilder --bootstrap
[+] Building 32.6s (1/1) FINISHED
 => [internal] booting buildkit                                                                                                           32.5s
 => => pulling image moby/buildkit:buildx-stable-1                                                                                        31.8s
 => => creating container buildx_buildkit_mybuilder0                                                                                       0.7s
Name:   mybuilder
Driver: docker-container

Nodes:
Name:      mybuilder0
Endpoint:  unix:///var/run/docker.sock
Status:    running
Platforms: linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6

1
2
3
4
5
6
7
8
9
10
11
12
13

查看当前使用的构建器支持的 CPU 架构:

$ docker buildx ls
NAME/NODE       DRIVER/ENDPOINT             STATUS  PLATFORMS
mybuilder *     docker-container
  mybuilder0    unix:///var/run/docker.sock running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
desktop-linux   docker
  desktop-linux desktop-linux               running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
default         docker
  default       default                     running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

1
2
3
4
5
6
7
8

申明

原创文章eryajf,未经授权,严禁转载,侵权必究!此乃文中随机水印,敬请读者谅解。

# 基于 Dockerfile 构建

我们准备好项目的 Dockerfile,并做好 dockerhub 的认证,然后开始构建镜像,并直接推送到 dockerhub。

$ docker buildx build -t eryajf/go-ldap-admin --platform=linux/arm64,linux/amd64 . --push

1

此时来到 dockerhub 中看这个镜像,也能看到多平台支持的标识了:

我们也可以通过命令行查看每个镜像的信息:

$ docker buildx imagetools inspect eryajf/go-ldap-admin
Name:      docker.io/eryajf/go-ldap-admin:latest
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest:    sha256:e70c93a079f64bf3b11beb5bb5c3365d521ab150ceaccc5c0318ccc94945aa48

Manifests:
  Name:      docker.io/eryajf/go-ldap-admin:latest@sha256:af9f6c43744850e8430124cfa2a3d7faaa998b31e0db500e8e005d7916e3bec2
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm64

  Name:      docker.io/eryajf/go-ldap-admin:latest@sha256:fcf385c734aaf1d7ee9ebc69925f457c6fae5c84df9beffb354b875b0cfc7409
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/amd64

1
2
3
4
5
6
7
8
9
10
11
12
13

当我们在使用并拉取这个镜像的时候,docker 会根据 CPU 架构拉取匹配的镜像。