使用 docker buildx 建構多 CPU 架構鏡像
引言
在工作中,遇到了需要将應用程式打包成 Docker 鏡像并同時運作在不同的 CPU 架構(X86 和 ARM)的環境中。
ARM 架構與 X86 相比,ARM 低功耗、移動市場占比高,X86 高性能、伺服器市場占比高。
不同的 CPU 架構,對于運作相同的應用程式的 Docker 容器,需要分别在相應的 CPU 架構下編譯的 Docker 鏡像。
要建構多架構鏡像,首先想到的是每種 CPU 架構環境(實體環境或虛拟環境)下建構相應的鏡像。
但目前 docker 建構環境是 X86 的,沒有 ARM 環境,
或者要申請 ARM 實體機,或者要申請/建立 ARM 虛拟機,或者交叉編輯等等,聽上去都比較麻煩。
經過研究,發現 docker buildx 支援建構多架構鏡像,這使得建構多架構鏡像變得簡單。
這樣就可以在 X86 架構下建構 ARM 架構的鏡像。
接下來,開始實踐之旅吧。
環境
Docker Desktop(Mac)
Docker Engine 19.03+
實踐步驟
第一步,開啟 docker buildx
docker buildx 目前還是試驗功能,預設沒有開啟,需要在 Docker Desktop 的首選項中開啟它
Docker —>Preferences —>Command Line —> Enable experimental features
執行 docker buildx 指令,輸出截圖如下:
第二步,建構多架構鏡像,并推送到 Docker Hub
寫個簡單的 Dockerfile,僅做示範:
echo "FROM python:3.7-alpine”>Dockerfile
列出 builder:
$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
default * docker
default default running linux/amd64, linux/arm64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
我們目前使用的是預設的 builder,它基本上是舊的 builder。
讓我們建立一個新的 builder,它使我們能夠通路一些新的多架構結構功能。
建立 builder:
$ docker buildx create --use --name mybuilder
mybuilder
檢視 builder:
$ docker buildx inspect --bootstrap
[+] Building 18.8s (1/1) FINISHED
=> [internal] booting buildkit 18.8s
=> => pulling image moby/buildkit:buildx-stable-1 18.0s
=> => creating container buildx_buildkit_mybuilder0 0.7s
Name: mybuilder
Driver: docker-container
Nodes:
Name: mybuilder0
Endpoint: unix:///var/run/docker.sock
Status: running
Platforms: linux/amd64, linux/arm64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
建構多架構鏡像,并推送到 Docker Hub:
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t donhui/multiarch --push .
該 --platform 标志訓示 buildx 要為 Intel 64位、Arm 32位和 Arm 64位架構生成 Linux 鏡像。
該 --push 标志生成一個多架構清單,并将所有鏡像推送到 Docker Hub。
在 DockerHub 檢視該鏡像,latest tag 下有三個鏡像,當在不同的架構 pull 該 tag 時會根據其環境 pull 相應架構的鏡像:
思考與總結
實踐中不斷産生疑問,不斷思考,不斷求解,或許你也會有同樣的問題:
1、多架構鏡像對 docker 版本有何要求?
建構時要用到 docker buildx 指令,docker 版本需要 19.03+;
運作時 docker 版本不一定需要 19.03+,筆者使用 1.13.1 和 18.06.1 都可以 pull 多架構鏡像的。
2、所有 Dockerfile 都可以建構成多架構嗎?還是有什麼要求?
對 Dockerfile 沒有要求,任何 Dockerfile 無需修改。
3、鏡像建構後預設儲存在建構緩存中,如何将鏡像儲存在本地?
可以将 type 指定為 docker,但必須分别為不同的 CPU 架構建構不同的鏡像,不能合并成一個鏡像,如:
docker buildx build -t donghui/multiarch-armv7 --platform=linux/arm/v7 -o type=docker .
docker buildx build -t donghui/multiarch-arm64 --platform=linux/arm64 -o type=docker .
docker buildx build -t donghui/multiarch-amd64 --platform=linux/amd64 -o type=docker .
也可以将鏡像 push 到鏡像倉庫後,再進行 pull。
4、隻支援推送到 Docker Hub 嗎?如果要推送到私有鏡像倉庫,對私有鏡像倉庫有什麼要求?
也可以将鏡像推送到私有鏡像倉庫,但需要該鏡像倉庫支援多架構鏡像的功能。
如果要将多架構鏡像推送到 Harbor,需要 Harbor 的版本為 v2.0.0。
Harbor v2.0.0 于 2020/05/13 釋出,Harbor v2.0.0 完全支援多架構鏡像。
Harbor v2.0.0 更新日志:
https://github.com/goharbor/harbor/releases/tag/v2.0.0參考
Container 愛上ARM
https://www.jianshu.com/p/64f0da7a044d跨平台建構 Docker 鏡像新姿勢,x86、arm 一把梭
https://blog.csdn.net/alex_yangchuansheng/article/details/103146303Getting started with Docker for Arm on Linux
https://engineering.docker.com/2019/06/getting-started-with-docker-for-arm-on-linux/Multi-arch build and images, the simple way
https://www.docker.com/blog/multi-arch-build-and-images-the-simple-way/Building multi-platform images
https://github.com/docker/buildx#building-multi-platform-imagesBuilding Multi-Arch Images for Arm and x86 with Docker Desktop
https://www.docker.com/blog/multi-arch-images/原文位址
https://my.oschina.net/donhui/blog/4283243