4.6 KiB
9.3 构建多种系统架构支持的 Docker 镜像
Docker 镜像可以支持多种系统架构,这意味着你可以在 x86_64、arm64 等不同架构的机器上运行同一个镜像。这是通过一个名为 "manifest list"(或称为 "fat manifest")的文件来实现的。
Manifest List 是什么?
为了理解多架构镜像的原理,我们需要先了解 Manifest List 的概念。
Manifest list 是一个包含了多个指向不同架构镜像的 manifest 的文件。当你拉取一个支持多架构的镜像时,Docker 会自动根据你当前的系统架构选择并拉取对应的镜像。
例如,官方的 hello-world 镜像就支持多种架构。你可以使用 docker manifest inspect 命令来查看它的 manifest list:
$ docker manifest inspect hello-world
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 525,
"digest": "sha256:80852a401a974d9e923719a948cc5335a0a4435be8778b475844a7153a2382e5",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 525,
"digest": "sha256:3adea81344be1724b383d501736c3852939b33b3903d02474373700b25e5d6e3",
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v5"
}
},
// ... more architectures
]
}
使用 docker buildx 构建多架构镜像
docker buildx 是构建多架构镜像的最佳实践工具,它屏蔽了底层的复杂性,提供了一键构建多架构镜像的能力。
在 Docker 19.03+ 版本中,docker buildx 是推荐的用于构建多架构镜像的工具。它使用 BuildKit 作为后端,可以大大简化构建过程。
新建 builder 实例
首先,你需要创建一个新的 builder 实例,因为它支持同时为多个平台构建。
$ docker buildx create --name mybuilder --use
$ docker buildx inspect --bootstrap
构建和推送
使用 docker buildx build 命令并指定 --platform 参数,可以同时构建支持多种架构的镜像。--push 参数会将构建好的镜像和 manifest list 推送到 Docker 仓库。
## Dockerfile
FROM --platform=$TARGETPLATFORM alpine
RUN uname -a > /os.txt
CMD cat /os.txt
$ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t your-username/multi-arch-image . --push
构建完成后,你就可以在不同架构的机器上拉取并运行 your-username/multi-arch-image 这个镜像了。
架构相关的构建参数
在 Dockerfile 中,你可以使用一些预定义的构建参数来根据目标平台定制构建过程:
TARGETPLATFORM: 构建镜像的目标平台,例如linux/amd64。TARGETOS: 目标平台的操作系统,例如linux。TARGETARCH: 目标平台的架构,例如amd64。TARGETVARIANT: 目标平台的变种,例如v7。BUILDPLATFORM: 构建环境的平台。BUILDOS: 构建环境的操作系统。BUILDARCH: 构建环境的架构。BUILDVARIANT: 构建环境的变种。
例如,你可以这样编写 Dockerfile 来拷贝特定架构的二进制文件:
FROM scratch
ARG TARGETOS
ARG TARGETARCH
COPY bin/dist-${TARGETOS}-${TARGETARCH} /dist
ENTRYPOINT ["/dist"]
使用 docker manifest(底层工具)
除了 docker buildx,我们也可以直接操作 Manifest List 来手动组合不同架构的镜像。
docker manifest 是一个更底层的命令,可以用来创建、检查和推送 manifest list。虽然 docker buildx 在大多数情况下更方便,但了解 docker manifest 仍然有助于理解其工作原理。
创建 manifest list
运行以下命令:
## 首先,为每个架构构建并推送镜像
$ docker buildx build --platform linux/amd64 -t your-username/my-app:amd64 . --push
$ docker buildx build --platform linux/arm64 -t your-username/my-app:arm64 . --push
## 然后,创建一个 manifest list,将它们组合在一起
$ docker manifest create your-username/my-app:latest \
--amend your-username/my-app:amd64 \
--amend your-username/my-app:arm64
## 最后,推送 manifest list
$ docker manifest push your-username/my-app:latest
检查 manifest list
你可以使用 docker manifest inspect 来查看一个 manifest list 的详细信息,如上文所示。