Docker 构建多平台镜像
类别: multi-platform 标签: Docker buildx目录
多平台构建器
当前构建器实例是驱动程序 docker-container
,可以同时指定多个平台。在这种情况下,它会构建一个清单列表,其中包含所有指定架构的镜像。在构建的时候可以并行构建多个架构的镜像。
docker run
当您在使用此镜像时 docker service
,Docker 会根据节点的平台选择正确的镜像。
有个缺点:必须发布到 Docker Hub 或者私有仓库,因为 Docker 不支持多架构的本地镜像。
查看构建器
docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
default docker
default default running v0.11.6+616c3f613b54 linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64, linux/arm/v7, linux/arm/v6, linux/amd64, linux/amd64/v2
desktop-linux * docker
desktop-linux desktop-linux running v0.11.6+616c3f613b54 linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64, linux/arm/v7, linux/arm/v6, linux/amd64, linux/amd64/v2
创建一个新的构建器并使用它
docker buildx create --name mybuilder --driver docker-container --bootstrap --use
查看构建器
docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
mybuilder * docker-container
mybuilder0 desktop-linux running v0.9.3 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64, linux/arm/v7, linux/arm/v6
default docker
default default running v0.11.6+616c3f613b54 linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64, linux/arm/v7, linux/arm/v6, linux/amd64, linux/amd64/v2
desktop-linux docker
desktop-linux desktop-linux running v0.11.6+616c3f613b54 linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64, linux/arm/v7, linux/arm/v6, linux/amd64, linux/amd64/v2
切换到默认构建器
docker buildx use default
删除构建器
docker buildx rm mybuilder
检查当前构建器实例
docker buildx inspect mybuilder
Name: mybuilder
Driver: docker-container
Last Activity: 2023-10-12 06:35:08 +0000 UTC
Nodes:
Name: mybuilder0
Endpoint: desktop-linux
Status: running
Buildkit: v0.9.3
Platforms: linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64, linux/arm/v7, linux/arm/v6
Labels:
org.mobyproject.buildkit.worker.executor: oci
org.mobyproject.buildkit.worker.hostname: 6e176585c465
org.mobyproject.buildkit.worker.snapshotter: overlayfs
GC Policy rule#0:
All: false
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
Keep Duration: 48h0m0s
Keep Bytes: 488.3MiB
GC Policy rule#1:
All: false
Keep Duration: 1440h0m0s
Keep Bytes: 17.7GiB
GC Policy rule#2:
All: false
Keep Bytes: 17.7GiB
GC Policy rule#3:
All: true
Keep Bytes: 17.7GiB
docker buildx inspect default
Name: default
Driver: docker
Nodes:
Name: default
Endpoint: default
Status: running
Buildkit: v0.11.6+616c3f613b54
Platforms: linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64, linux/arm/v7, linux/arm/v6, linux/amd64, linux/amd64/v2
Labels:
org.mobyproject.buildkit.worker.moby.host-gateway-ip: 192.168.65.254
GC Policy rule#0:
All: false
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
Keep Duration: 172.8µs
Keep Bytes: 2.764GiB
GC Policy rule#1:
All: false
Keep Duration: 5.184ms
Keep Bytes: 20GiB
GC Policy rule#2:
All: false
Keep Bytes: 20GiB
GC Policy rule#3:
All: true
Keep Bytes: 20GiB
安装 Emulators
使用 tonistiigi/binfmt 安装
docker run --privileged --rm tonistiigi/binfmt --install linux/arm64,linux/amd64
installing: arm64 cannot register "/usr/bin/qemu-aarch64" to /proc/sys/fs/binfmt_misc/register: write /proc/sys/fs/binfmt_misc/register: no such file or directory
installing: amd64 OK
{
"supported": [
"linux/arm64",
"linux/amd64",
"linux/riscv64",
"linux/ppc64le",
"linux/s390x",
"linux/386",
"linux/mips64",
"linux/arm/v7",
"linux/arm/v6"
],
"emulators": [
"qemu-arm",
"qemu-i386",
"qemu-mips64",
"qemu-ppc64le",
"qemu-riscv64",
"qemu-s390x",
"qemu-x86_64",
"rosetta"
]
}
卸载 Emulators
docker run --privileged --rm tonistiigi/binfmt --uninstall "qemu-*"
构建多平台镜像
Dockerfile
FROM python:3.10-slim
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=l,sharing=locked \
apt update && apt install -y git
构建
docker buildx build --platform linux/amd64,linux/arm64 -t <username>/<image>:latest --push .
-
Docker ID, Docker Hub 上的仓库名 - –platform 创建 amd64, arm64 架构的 Linux 映像。
- –push 生成一个多架构清单并将所有图像推送到 Docker Hub。
- –load 生成一个单架构清单并将所有图像加载到本地镜像库。不支持多架构的本地镜像,如:linux/amd64,linux/arm64
查看镜像
docker buildx imagetools inspect wangjunjian/test:apt
Name: docker.io/wangjunjian/test:apt
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest: sha256:82d7b9c3ecdcc37468a4a314950ae4993b9c6790f61c4cfcef04f77f1b4fd096
Manifests:
Name: docker.io/wangjunjian/test:apt@sha256:469670d4c09ab6540cb64ce011cc1d4771426108f1784ba7a6c4f755b2dfe146
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm64
Name: docker.io/wangjunjian/test:apt@sha256:e43f743ae58e7ef9fc740d50e301a1caac34632a7e47561c5312b4b1869832a0
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/amd64
运行不同架构的镜像
arm64
docker run --rm docker.io/wangjunjian/test:apt@sha256:469670d4c09ab6540cb64ce011cc1d4771426108f1784ba7a6c4f755b2dfe146 uname -m
aarch64
amd64
docker run --rm docker.io/wangjunjian/test:apt@sha256:e43f743ae58e7ef9fc740d50e301a1caac34632a7e47561c5312b4b1869832a0 uname -m
x86_64
查看系统和架构
docker image inspect wangjunjian/test:apt --format '/'
linux/arm64
默认构建器
默认的 docker 驱动程序目前不支持多平台功能。 请切换到不同的驱动程序(例如“docker buildx create –use”)⬆
切换默认构建器
docker buildx use desktop-linux
分别创建不同架构的镜像
amd64
docker buildx build --platform linux/amd64 -t wangjunjian/apt:amd64 .
docker push wangjunjian/apt:amd64
arm64
docker buildx build --platform linux/arm64 -t wangjunjian/apt:arm64 .
docker push wangjunjian/apt:arm64
创建清单列表并推送到 Docker Hub
docker manifest create wangjunjian/apt:latest wangjunjian/apt:amd64 wangjunjian/apt:arm64
docker manifest push wangjunjian/apt:latest
也可以不创建清单列表,直接推送。合并清单列表的好处是多个架构使用同一个镜像名,而不是不同架构使用不同的镜像名。
参考资料
- Multi-platform images
- Faster Multi-Platform Builds: Dockerfile Cross-Compilation Guide
- How to Build Multi-Arch Docker Images
- Docker Build architecture
- Dockerfile 参考
- buildx
- Binfmt
- BuildKit
- Building Multi-Arch Images for Arm and x86 with Docker Desktop
- Docker: Exporting Image for Multiple Architectures
- Relation between linux/arm64 and linux/arm64/v8: are these aliases for each other?
- Docker Buildx 版本更新引起的镜像血案
- Dockerfile RUN command (shell form) fails for multi-arch builds #2437
- Building Multi-Architecture Docker Images With Buildx
- How to build x86 (and others!) Docker images on an M1 Mac
- docker buildx prune
- Docker之磁盘清理
- Docker container driver
- Frequently asked questions for Mac