如何使用Docker構(gòu)建多平臺鏡像?
目錄
?如何構(gòu)建多平臺鏡像?
?工作原理
?準(zhǔn)備構(gòu)建環(huán)境?
開啟Linux內(nèi)核對多處理器架構(gòu)的支持 創(chuàng)建使用"docker-container"驅(qū)動的Buildx實(shí)例
調(diào)整Dockerfile
調(diào)整構(gòu)建命令
在不同鏡像倉庫之間傳輸鏡像
如何構(gòu)建多平臺鏡像?
如果你還不了解什么是多平臺構(gòu)建,請先閱讀一下Docker構(gòu)建多平臺鏡像的文檔:
https://docs.docker.com/build/building/multi-platform/
官方文檔里給出了3種多平臺鏡像的構(gòu)建方式,本文推薦使用第3種方式,即Dockerfile多平臺構(gòu)建的方式。采用這種方式的好處是不用針對每種平臺準(zhǔn)備一份Dockerfile,只需要調(diào)整構(gòu)建鏡像的參數(shù)就能同時(shí)支持多平臺構(gòu)建。
工作原理
要讓Docker支持多平臺構(gòu)建,需要滿足以下幾個(gè)條件:
?Linux內(nèi)核開啟多處理器架構(gòu)支持
構(gòu)建時(shí)使用基于"docker-container"驅(qū)動的Buildx實(shí)例
使用"docker buildx build"命令構(gòu)建鏡像
構(gòu)建命令必須指定"–platform"參數(shù)
Dockerfile中,"FROM"指令必須設(shè)置"-platform=${TARGETPLATFORM}"
Docker構(gòu)建多平臺鏡像實(shí)際上是借助BuildKit來實(shí)現(xiàn)的,并且需要?jiǎng)?chuàng)建一個(gè)基于"docker-container"驅(qū)動的Buildx實(shí)例。創(chuàng)建實(shí)例時(shí),Docker會創(chuàng)建一個(gè)容器作為虛擬節(jié)點(diǎn),用來執(zhí)行構(gòu)建,并存放構(gòu)建后產(chǎn)生的鏡像。
當(dāng)同時(shí)指定了"amd64"和"arm64"平臺構(gòu)建鏡像時(shí),BuildKit會分別啟動兩個(gè)容器,一個(gè)容器構(gòu)建"amd64"架構(gòu)的鏡像,另一個(gè)容器構(gòu)建"arm64"架構(gòu)的鏡像。兩個(gè)容器的構(gòu)建過程相同,使用的Dockerfile內(nèi)容也相同。BuildKit構(gòu)建完兩個(gè)鏡像后,會創(chuàng)建一個(gè)Manifest List對象,然后把"amd64"和"arm64"的鏡像記錄到manifest中,接著用構(gòu)建時(shí)的"-–tag"參數(shù)作為manifest的名稱。如果把"--tag"指定的鏡像名推送到Registry,BuildKit會將Manifest對象、兩個(gè)架構(gòu)的鏡像都推到Registry。
需要注意,BuildKit創(chuàng)建的鏡像和Manifest都僅存在于Buildx實(shí)例中,在宿主機(jī)上是看不到這些鏡像的。
準(zhǔn)備構(gòu)建環(huán)境
構(gòu)建多平臺鏡像最難處理的地方在于準(zhǔn)備構(gòu)建環(huán)境
開啟Linux內(nèi)核對多處理器架構(gòu)的支持
Docker的官方文檔已經(jīng)給出具體方案,只需要執(zhí)行以下命令即可。但前提是Linux內(nèi)核版本必須>=4.8,如果不滿足條件,升級內(nèi)核的操作可自行谷歌
命令行
docker run --privileged --rm tonistiigi/binfmt --install all
執(zhí)行完成后,可以執(zhí)行以下命令進(jìn)行檢查
docker buildx ls
“平臺”中出現(xiàn)"linux/arm64"字樣即表示開啟成功,輸出內(nèi)容如下:
NAME/NODE ? ?DRIVER/ENDPOINT ? ? ? ? ? ? STATUS ?BUILDKIT PLATFORMS
default ? ? ?docker ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?default ? ?default ? ? ? ? ? ? ? ? ? ? running v0.11.6 ?linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/risCV64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
創(chuàng)建使用"docker-container"驅(qū)動的Buildx實(shí)例
Docker的官方文檔已給出具體方案,只需要執(zhí)行以下命令即可。
命令行?
docker buildx create --name mybuilder --driver docker-container --use
執(zhí)行完成后,可以使用以下命令進(jìn)行檢查
docker buildx ls
輸出內(nèi)容如下
NAME/NODE ? ?DRIVER/ENDPOINT ? ? ? ? ? ? STATUS ?BUILDKIT PLATFORMS
mybuilder * ?docker-container ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?mybuilder0 unix:///var/run/docker.sock running v0.11.6 ?linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/risCV64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
default ? ? ?docker ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?default ? ?default ? ? ? ? ? ? ? ? ? ? running v0.11.6 ?linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/risCV64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
調(diào)整Dockerfile
Dockerfile只需要加上"–platform=${TARGETPLATFORM}"參數(shù),示例:
Dockerfile
FROM --platform=${TARGETPLATFORM} ubuntu:20.04
調(diào)整構(gòu)建命令
多平臺構(gòu)建時(shí),不能直接使用"docker build"命令,而是使用"docker buildx build"命令。
這是因?yàn)?#34;docker build"每次僅支持構(gòu)建單一平臺的鏡像,而"docker buildx build"才支持單命令同時(shí)構(gòu)建多平臺鏡像。
完整的構(gòu)建命令如下:
docker buildx build \
?--platform linux/amd64,linux/arm64 \
?--tag "鏡像名稱"
如需構(gòu)建完成后自動推送鏡像,可以增加"–push"參數(shù):
docker buildx build \
?--platform linux/amd64,linux/arm64 \
?--push \
?--tag "鏡像名稱"
在不同鏡像倉庫之間傳輸鏡像
命令行
skopeo copy --all docker://源鏡像名 docker://目標(biāo)鏡像名
完成以上步驟,就可以使用Docker構(gòu)建多平臺鏡像啦!