前言

大家在使用Docker的时候经常会遇到一个问题,就是受用机和本级不是同一架构。就比如小编使用的就是新版本的MacOS,使用了ARM架构,与目前仍占据主流的AMD64不同,所以没有办法很好的在AMD架构中使用。这时候就需要在ARM架构上打包成AMD64架构的Docker镜像。

解决方案

其实很简单,我们只需要使用Docker中的buildx插件即可。要想使用 buildx,首先要确保 Docker 版本不低于 19.03,同时还要通过设置环境变量 DOCKER_CLI_EXPERIMENTAL 来启用。可以通过下面的命令来为当前终端启用 buildx 插件:

1
export DOCKER_CLI_EXPERIMENTAL=enabled

验证是否开启:

1
docker buildx version

如果在某些系统上设置环境变量 DOCKER_CLI_EXPERIMENTAL 不生效(比如 Arch Linux),你可以选择从源代码编译:

1
2
3
export DOCKER_BUILDKIT=1
docker build --platform=local -o . git://github.com/docker/buildx
mkdir -p ~/.docker/cli-plugins && mv buildx ~/.docker/cli-plugins/docker-buildx

解决过程

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

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

先创建一个新的构建器:

1
docker buildx create --use --name mybuilder

启动构建器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker buildx inspect mybuilder --bootstrap

[+] Building 5.0s (1/1) FINISHED
=> [internal] booting buildkit 5.0s
=> => pulling image moby/buildkit:buildx-stable-1 4.4s
=> => creating container buildx_buildkit_mybuilder0 0.6s
Name: mybuilder
Driver: docker-container

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

查看支持架构:

1
docker buildx ls

结果如下:

1
2
3
4
5
6
moxin@moxindeMacBook-Pro ~ % docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
default * docker
default default running 20.10.17 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
desktop-linux docker
desktop-linux desktop-linux running 20.10.17 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

构建多平台镜像

下面的命令是将当前目录下的Dockerfile构建成一个支持arm、arm64、amd64的语句:

1
docker buildx build -t qsnctf/testdocker --platform=linux/arm,linux/arm64,linux/amd64 . --push

如果想将镜像保存到本地,你需要将type设置为Docker,但是不同环境就需要分开编译:

1
2
3
docker buildx build -t qsnctf/testdocker --platform=linux/arm -o type=docker .
docker buildx build -t qsnctf/testdocker --platform=linux/arm64 -o type=docker .
docker buildx build -t qsnctf/testdocker --platform=linux/amd64 -o type=docker .