iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0

昨天研究了 Image Manifest 的概念,提到了通常官方的 Docker Image 都有 Manifest、並提供多種架構的 image,

那既然官方的 image 可以,我們應該也可以為我們自己的 Image 建立 Manifest 吧!

因此今天延續昨天的內容,讓我們來繼續說說如何建置出支援多種架構的 image。


buildx 指令

buildx 是 Docker 官方提供的一個指令,可以讓我們用來建置多種 Image,

同時在開始前,需要注意一點,
根據我的實驗,以下的指令跟步驟只能在裝有 Docker Desktop 的電腦上使用,

原因值得研究,
但直觀地猜測,是因為 Docker Desktop 的底層由 VM 架構,讓我們的開發電腦擁有建立模擬其他 CPU 架構 Image 的能力,

以下範例如果是在 Local 執行的指令就不會加上 sudo

buildx ls

在我的 Mac M1 電腦上執行後 buildx ls 後這些資訊,
以我目前的理解,這些是這台電腦上支援的架構,

# M1 Mac
$ 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

而在一台 AMD64 架構的電腦上,可以看到內容有一些差別:

# AMD64 架構的伺服器
$ sudo docker buildx ls

NAME/NODE    DRIVER/ENDPOINT             STATUS  BUILDKIT PLATFORMS
mybuilder *  docker-container
  mybuilder0 unix:///var/run/docker.sock running v0.10.4  linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386
default      docker
  default    default                     running 20.10.18 linux/amd64, linux/386

buildx create

buildx create 指令是用來執行一個「builder」,用來模擬各種架構的特殊環境,

$ docker buildx create --name mybuilder --use --bootstrap


[+] Building 3.5s (1/1) FINISHED
 => [internal] booting buildkit                                                                    3.5s
 => => pulling image moby/buildkit:buildx-stable-1                                                 3.0s
 => => creating container buildx_buildkit_mybuilder0                                               0.5s
mybuilder

其中 --use 參數是用來指定為預設的 builder,--bootstrap 則是預先建立好需要的架構資料,
有興趣的讀者可以自己把這兩個參數拿掉,觀察看看有哪裡不同,

此時 Docker 會執行起一個特殊的 image,可以透過 docker ps 跟 docker images 來查看:

$ docker ps -a

CONTAINER ID   IMAGE                           COMMAND                  CREATED          STATUS          PORTS                    NAMES
5bd689a0fbe4   moby/buildkit:buildx-stable-1   "buildkitd"              23 seconds ago   Up 22 seconds                            buildx_buildkit_mybuilder0


$ docker images

REPOSITORY      TAG               IMAGE ID       CREATED       SIZE
moby/buildkit   buildx-stable-1   21bbfc679017   6 weeks ago   134MB

buildx build

接著就到了我們最重要的建置 image,同時會上傳到 Container Registry,
我們一樣拿 D5 的程式碼範例來用,並推到 Gitlab:

$ docker buildx build --push \
	--platform linux/amd64,linux/arm64 \
	--tag registry.gitlab.com/louis222220/2022-ithelp-docker-is-not-so-hard/hello-world-server:multi-arch .

[+] Building 29.0s (17/17) FINISHED
 => [internal] load build definition from Dockerfile                                               0.0s
 => => transferring dockerfile: 136B                                                               0.0s
 => [internal] load .dockerignore                                                                  0.0s
 => => transferring context: 2B                                                                    0.0s
 => [linux/amd64 internal] load metadata for docker.io/library/node:16-slim                        4.0s
 => [linux/arm64 internal] load metadata for docker.io/library/node:16-slim                        4.0s
 => [linux/amd64 2/5] WORKDIR /app                                                                 0.3s
 => [linux/amd64 3/5] COPY ./package*.json ./                                                      0.0s
 => [linux/amd64 4/5] RUN npm ci                                                                   7.7s
 => [linux/arm64 2/5] WORKDIR /app                                                                 0.0s
 => [linux/arm64 3/5] COPY ./package*.json ./                                                      0.0s
 => [linux/arm64 4/5] RUN npm ci                                                                   0.9s
 => [linux/arm64 5/5] COPY . .                                                                     0.0s
 => [linux/amd64 5/5] COPY . .                                                                     0.0s
 => exporting to image                                                                            11.1s
 => => exporting layers                                                                            0.2s
 => => pushing layers                                                                              9.1s
 => => pushing manifest for registry.gitlab.com/louis222220/2022-ithelp-docker-is-not-so-hard/hel  1.8s
 => [auth] louis222220/2022-ithelp-docker-is-not-so-hard/hello-world-server:pull,push token for r  0.0s

可以注意到我們用了 --platform 來指定要建置的 image 架構,

接著我們再用 Server 來查看 manifest:

# AMD64 架構的 server
$ sudo docker manifest inspect registry.gitlab.com/louis222220/2022-ithelp-docker-is-not-so-hard/hello-world-server:multi-arch

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 2200,
         "digest": "sha256:9becc34a5625c31a538ba232dc9d3c9d6efab9cafacacdd1536083a5a769ddb6",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 2200,
         "digest": "sha256:e45d73007b3998bba9e286bf0e896b05c57c90a7f24b8830cf7ea28d86456d8a",
         "platform": {
            "architecture": "arm64",
            "os": "linux"
         }
      }
   ]
}

可以看到成功建置多架構的 image,

最後當然還是要檢查一下,是否真的可以執行:

$ sudo docker run \
	-d -p 3000:3000 \
	registry.gitlab.com/louis222220/2022-ithelp-docker-is-not-so-hard/hello-world-server:multi-arch

multi-arch: Pulling from louis222220/2022-ithelp-docker-is-not-so-hard/hello-world-server
...
Digest: sha256:bbf7ea87a2d0e488f97b0549c9d2215ad03f5f6fe8a572d25af577a98457ea2c
Status: Downloaded newer image for registry.gitlab.com/louis222220/2022-ithelp-docker-is-not-so-hard/hello-world-server:multi-arch
d2983e7a83d17fae5cf36d564d05a603e1871f5caf75d42d5bbaeb9f7f474468


$ curl localhost:3000

{"hello":"world"}

Tada~ ?
完成,

那我們今天的教學就到這邊。


上一篇
D18 - 不同的 CPU 架構 與 Image manifest
下一篇
D20 - 團隊觀戰區爬蟲 v4 ft. Redis
系列文
其實沒有那麼難 — Docker30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言