10.3 使用 buildx 建立多種系統架構支援的 Docker 映象

Docker 映象可以支援多種系統架構,這意味著你可以在 x86_64arm64 等不同架構的機器上執行同一個映象。這是透過一個名為 『manifest list』 (或稱為 『fat manifest』) 的檔案來實現的。

10.3.1 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
   ]
}

10.3.2 使用 docker buildx 建立多架構映象

docker buildx 是建立多架構映象的最佳實踐工具,它遮蔽了底層的複雜性,提供了一鍵建立多架構映象的能力。

在 Docker 19.03+ 版本中,docker buildx 是推薦的用於建立多架構映象的工具。它使用 BuildKit 作為後端,可以大大簡化建立過程(Docker 23+ 預設啟用 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"]

10.3.3 使用 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 的詳細訊息,如上文所示。

第 86 页,共 196 页
使用 mdPress 构建