構建多架構鏡像的最佳實踐
在雲時代,容器化已經成爲一種事實,把軟件產品打包、構建成 Docker 鏡像是最基本、最關鍵的一步。在信創的大背景下,雲環境中會存在 x86、arm 等不同的架構,所以在構建鏡像時需要構建出多種架構的鏡像,以適配不同架構的服務器。
在拉取 Docker 鏡像時,會根據當前環境的架構自動拉取對應架構的鏡像,如:在 x86 環境下拉取的鏡像爲 x86 架構的鏡像,在 arm 環境下拉取的鏡像爲 arm 架構的鏡像。(前提是,該鏡像是多架構的鏡像)
本文將針對基於 Docker Buildx 來構建多架構的鏡像展開說明(一次構建多架構的鏡像)。
1、buildx 安裝
Docker Buildx 是一個 CLI 插件,它擴展了 Docker 命令,完全支持 Moby BuildKit 構建器工具包提供的功能。它提供與 docker build
相同的用戶體驗,具有許多新功能,例如創建作用域構建器實例和同時針對多個節點進行構建。
-
- 下載 buildx 二進制文件。
在 Github Release 頁面 (https://github.com/docker/buildx/releases/latest) 下載最新的 buildx 二進制文件。
根據您的操作系統選擇對應的二進制文件。
-
-
- buildx 複製到 Docker 對應目錄。
重命名下載的 buildx 二進制文件,並將其複製到您操作系統對應的目錄:
例如,我的 MacOS:
```
xcbeyond@xcbeyonddeMacBook-Pro ~ % mv ~/Downloads/buildx-v0.7.1.darwin-arm64 ~/.docker/cli-plugins/docker-buildx
xcbeyond@xcbeyonddeMacBook-Pro ~ % chmod +x ~/.docker/cli-plugins/docker-buildx
```
注意:需對 buildx 二進制文件賦予權限,執行 `chmod +x`。
-
- 檢查 buildx。
執行
docker buildx version
:xcbeyond@xcbeyonddeMacBook-Pro ~ % docker buildx version github.com/docker/buildx v0.7.1 05846896d149da05f3d6fd1e7770da187b52a247
2、開啓 binfmt_misc 來運行非本地架構的 Docker 鏡像
如果您使用的是 Mac 或者 Windows 版本 Docker 桌面版,則可以跳過這個步驟,因爲 binfmt_misc 默認開啓。
如果使用的是其它平臺,可使用 tonistiigi/binfmt 鏡像進行安裝:
docker run --privileged --rm tonistiigi/binfmt --install all
3、將默認 Docker 構建器切換爲多架構構建器
默認情況下,Docker 會使用默認構建器,是不支持多架構構建。
爲了構建多架構的鏡像,需要創建新的支持多架構的構建器,需執行 docker buildx create --use
:
xcbeyond@xcbeyonddeMacBook-Pro % docker buildx create --use --name mybuilder
mybuilder
查看新的多架構構建器是否生效,需執行 docker buildx ls
:
xcbeyond@xcbeyonddeMacBook-Pro % docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
mybuilder * docker-container
mybuilder0 unix:///var/run/docker.sock inactive
desktop-linux docker
desktop-linux desktop-linux running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
default docker
default default running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
4、構建多架構鏡像
- 編寫測試程序。
爲方便測試,用 Golang 寫了一個簡單的程序,並輸出當前程序運行環境的架構信息:
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Printf("the current platform architecture is %s.\n", runtime.GOARCH)
}
- 編寫 Dockerfile。
編寫該程序的 Dockerfile(https://xcbeyond.cn/blog/containers/build-multi-platform-images-best-practices/Dockerfile):
FROM xcbeyond/go-builder:1.16
LABEL maintainer xcbeyond
WORKDIR /app
COPY multi-arch-test.go /app
RUN go build -o multi-arch-test /app/multi-arch-test.go
CMD ["./multi-arch-test"]
- 構建多架構鏡像。
通過命令 docker buildx build -t <image-name> --platform=linux/arm64,linux/amd64 . --push
,構建一個支持 arm64 和 amd64 架構的多架構鏡像,並推送至 Docker Hub:
(參數 --push
會自動將鏡像推送到 Docker Hub,本地並不會保留該鏡像。如果不想推送,則可去掉該參數。)
xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker buildx build -t xcbeyond/multi-arch-test --platform=linux/arm64,linux/amd64 . --push
[+] Building 3105.4s (19/19) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 222B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [linux/amd64 internal] load metadata for docker.io/xcbeyond/go-builder:1.16 5.2s
=> [linux/arm64 internal] load metadata for docker.io/xcbeyond/go-builder:1.16 4.9s
=> [auth] xcbeyond/go-builder:pull token for registry-1.docker.io 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 40B 0.0s
=> [linux/amd64 1/4] FROM docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc 2323.9s
=> => resolve docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc 0.0s
=> => sha256:6e1d20a8313edd44a36cb9198f4d11ac5eedb41d1faf5e8a33c5a0a5a25d2b92 85.80MB / 85.80MB 2318.7s
=> => sha256:6494e4811622b31c027ccac322ca463937fd805f569a93e6f15c01aade718793 54.57MB / 54.57MB 27.3s
=> => sha256:5b59121a0c3517cfd68aba8a3955cbb40ca12dd56db3317e3a17cf56131ca915 129.08MB / 129.08MB 77.1s
=> => sha256:cb5b7ae361722f070eca53f35823ed21baa85d61d5d95cd5a95ab53d740cdd56 10.87MB / 10.87MB 96.5s
=> => sha256:9b829c73b52b92b97d5c07a54fb0f3e921995a296c714b53a32ae67d19231fcd 5.15MB / 5.15MB 5.2s
=> => sha256:0e29546d541cdbd309281d21a73a9d1db78665c1b95b74f32b009e0b77a6e1e3 54.92MB / 54.92MB 61.0s
=> => extracting sha256:0e29546d541cdbd309281d21a73a9d1db78665c1b95b74f32b009e0b77a6e1e3 1.5s
=> => extracting sha256:9b829c73b52b92b97d5c07a54fb0f3e921995a296c714b53a32ae67d19231fcd 0.1s
=> => extracting sha256:cb5b7ae361722f070eca53f35823ed21baa85d61d5d95cd5a95ab53d740cdd56 0.3s
=> => extracting sha256:6494e4811622b31c027ccac322ca463937fd805f569a93e6f15c01aade718793 1.6s
=> => extracting sha256:6e1d20a8313edd44a36cb9198f4d11ac5eedb41d1faf5e8a33c5a0a5a25d2b92 1.9s
=> => extracting sha256:5b59121a0c3517cfd68aba8a3955cbb40ca12dd56db3317e3a17cf56131ca915 3.3s
=> => extracting sha256:2db41f0db9d9d9a1f49978ec31e8d187f491767e9b377f5ee121827c407e015e 0.0s
=> [linux/arm64 1/4] FROM docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc 2187.3s
=> => resolve docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc 0.0s
=> => sha256:221ff675cd357b3b345da24f781791fc9b91066d687f9e928993aab31618d13d 99.63MB / 99.63MB 54.3s
=> => sha256:627b3401fb617535edd16e96bd5941ecea7fe10ce6087bd47707602cfc396c2b 81.01MB / 81.01MB 472.1s
=> => sha256:841dd868500b6685b6cda93c97ea76e817b427d7a10bf73e9d03356fac199ffd 54.67MB / 54.67MB 2084.9s
=> => sha256:aa9c5b49b9db3dd2553e8ae6c2081b77274ec0a8b1f9903b0e5ac83900642098 10.66MB / 10.66MB 6.2s
=> => sha256:ac9d381bd1e98fa8759f80ff42db63c8fce4ac9407b2e7c8e0f031ed9f96432b 5.14MB / 5.14MB 6.8s
=> => sha256:94a23d3cb5be24659b25f17537307e7f568d665244f6a383c1c6e51e31080749 53.60MB / 53.60MB 22.7s
=> => extracting sha256:94a23d3cb5be24659b25f17537307e7f568d665244f6a383c1c6e51e31080749 1.5s
=> => extracting sha256:ac9d381bd1e98fa8759f80ff42db63c8fce4ac9407b2e7c8e0f031ed9f96432b 0.1s
=> => extracting sha256:aa9c5b49b9db3dd2553e8ae6c2081b77274ec0a8b1f9903b0e5ac83900642098 0.2s
=> => extracting sha256:841dd868500b6685b6cda93c97ea76e817b427d7a10bf73e9d03356fac199ffd 1.5s
=> => extracting sha256:627b3401fb617535edd16e96bd5941ecea7fe10ce6087bd47707602cfc396c2b 1.7s
=> => extracting sha256:221ff675cd357b3b345da24f781791fc9b91066d687f9e928993aab31618d13d 2.7s
=> => extracting sha256:10c716f05a00666c190fb40f99503dc83b2886de744ab9b3dc6c5d37d01f6e49 0.0s
=> [auth] xcbeyond/go-builder:pull token for registry-1.docker.io 0.0s
=> [linux/arm64 2/4] WORKDIR /app 0.1s
=> [linux/arm64 3/4] COPY multi-arch-test.go /app 0.0s
=> [linux/arm64 4/4] RUN go build -o multi-arch-test /app/multi-arch-test.go 0.3s
=> [linux/amd64 2/4] WORKDIR /app 0.2s
=> [linux/amd64 3/4] COPY multi-arch-test.go /app 0.0s
=> [linux/amd64 4/4] RUN go build -o multi-arch-test /app/multi-arch-test.go 1.5s
=> exporting to image 774.4s
=> => exporting layers 10.5s
=> => exporting manifest sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2 0.0s
=> => exporting config sha256:628f504898973d1d935ffd37993d1db5fdc4715c5d58467db2c6531d3d7d3181 0.0s
=> => exporting manifest sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd 0.0s
=> => exporting config sha256:47e7af533f821be5ba256919303e0de3b39990109a419a98dbfddc6c82086822 0.0s
=> => exporting manifest list sha256:8417543ebc47e6040a67a392d6ee9de05735ed464e48b22fcc3bdf66ce22224b 0.0s
=> => pushing layers 761.8s
=> => pushing manifest for docker.io/xcbeyond/multi-arch-test:latest@sha256:8417543ebc47e6040a67a392d6ee9de05735ed464e48b22fcc3bdf66ce22224b 2.0s
=> [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io 0.0s
=> [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io 0.0s
=> [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io 0.0s
5、測試多架構鏡像
將構建的多架構鏡像 xcbeyond/multi-arch-test:latest 進行測試,以確保能夠正常運行,並使用對應架構鏡像能夠輸出匹配的架構信息。
-
- 查看每個架構鏡像的信息。
執行命令
docker manifest inspect
,可查看該鏡像清單,並能得知該鏡像對應架構的鏡像 SHA 值:xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker manifest inspect xcbeyond/multi-arch-test:latest { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", "manifests": [ { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 2419, "digest": "sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2", "platform": { "architecture": "arm64", "os": "linux" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 2420, "digest": "sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd", "platform": { "architecture": "amd64", "os": "linux" } } ] }
也可以直接在 Docker Hub 上直接看到該鏡像支持的多架構信息:
-
-
2. 根據不同架構鏡像的 SHA 值,來逐一運行該鏡像,並查看其輸出結果。
分別執行
docker run --rm
命令:arm 架構的鏡像:
xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker run --rm xcbeyond/multi-arch-test:latest@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2 Unable to find image 'xcbeyond/multi-arch-test:latest@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2' locally docker.io/xcbeyond/multi-arch-test@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2: Pulling from xcbeyond/multi-arch-test 94a23d3cb5be: Pull complete ac9d381bd1e9: Pull complete aa9c5b49b9db: Pull complete 841dd868500b: Pull complete 627b3401fb61: Pull complete 221ff675cd35: Pull complete 10c716f05a00: Pull complete 15bae122089f: Pull complete d764b5be0a55: Pull complete 34bfa57028a2: Pull complete Digest: sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2 Status: Downloaded newer image for xcbeyond/multi-arch-test@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2 the current platform architecture is arm64.
x86 架構的鏡像:
xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker run --rm xcbeyond/multi-arch-test:latest@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd Unable to find image 'xcbeyond/multi-arch-test:latest@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd' locally docker.io/xcbeyond/multi-arch-test@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd: Pulling from xcbeyond/multi-arch-test 0e29546d541c: Pull complete 9b829c73b52b: Pull complete cb5b7ae36172: Pull complete 6494e4811622: Pull complete 6e1d20a8313e: Pull complete 5b59121a0c35: Pull complete 2db41f0db9d9: Pull complete f708bf6a9dc8: Pull complete cb0d69b97354: Pull complete a8f5aa83ecfb: Pull complete Digest: sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd Status: Downloaded newer image for xcbeyond/multi-arch-test@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd the current platform architecture is amd64.
上面的輸出結果,和我們的期望一致:多架構的鏡像構建成功,並能在各自架構環境下運行。
6、總結
多架構鏡像是基於 Docker Buildx 構建的,目前 buildx 還需額外安裝,未來 buildx 很可能成爲 docker build 命令的一部分,無需額外安裝,畢竟多架構鏡像已在各種場景中應用廣泛起來了。
參考文章:
-
https://docs.docker.com/buildx/working-with-buildx/
-
https://www.youtube.com/watch?v=hWSHtHasJUI
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Vfywvroi1F2q_0g2sR8_BA