騰訊云多平臺(tái)容器鏡像構(gòu)建(下)

來(lái)源: 騰訊云原生
作者:孔礬建
時(shí)間:2020-12-29
17368
要了解容器鏡像是如何支持多平臺(tái)的,那我們需要仔細(xì)聊聊 Manifest。使用過(guò)容器技術(shù)的同學(xué)都知道,我們運(yùn)行容器所使用的鏡像是由多層構(gòu)成的,而這些層的清單和其它容器信息共同存放在 Manifest 當(dāng)中。

NTllNTc5Ny5qcGVn.jpg

創(chuàng)建Manifest List

我們使用docker manifest子命令管理manifest list。其中,docker manifest create子命令用于在本地創(chuàng)建一個(gè)manifest list。該命令需要指定待manifest list地址和一系列的manifests。例如需要?jiǎng)?chuàng)建包含amd64和arm64兩個(gè)平臺(tái)鏡像的manifest list,則命令如:

docker manifest create kofj/multi-demo kofj/multi-demo:amd64 kofj/multi-demo:arm64

docker manifest create命令的詳細(xì)幫助信息如下所示:

# docker manifest create --help

Usage: docker manifest create MANIFEST_LIST MANIFEST [MANIFEST...]

Create a local manifest list for annotating and pushing to a registry

Options:

  -a, --amend      Amend an existing manifest list

      --insecure   Allow communication with an insecure registry

我們按照上述方法創(chuàng)建出來(lái)的manifest list中并沒(méi)有說(shuō)明其中的manifest是什么操作系統(tǒng)和平臺(tái)的,docker manifest annotate命令用于注釋創(chuàng)建出來(lái)的manifest list。例如注釋某個(gè)manifest是linxu系統(tǒng)arm64平臺(tái)的,則命令:

docker manifest annotate kofj/multi-demo kofj/multi-demo:arm64--os linux--arch arm64

docker manifest annotate命令的詳細(xì)幫助信息如下所示:

# docker manifest annotate --help

Usage: docker manifest annotate [OPTIONS] MANIFEST_LIST MANIFEST

Add additional information to a local image manifest

Options:

      --arch string           Set architecture

      --os string             Set operating system

      --os-features strings   Set operating system feature

      --variant string        Set architecture variant

注意:

1.創(chuàng)建manifest list清單的過(guò)程中會(huì)檢查遠(yuǎn)端倉(cāng)庫(kù)中manifests是否存在,所以我們必修提前推送鏡像到遠(yuǎn)端。如果遠(yuǎn)端倉(cāng)庫(kù)是不安全的,在創(chuàng)建的過(guò)程中需要添加參數(shù)--inseure。

2.使用docker manifest annotate注釋manifest list的時(shí)候不需要使用--insecure。

為了方便使用,我們可以使用下述代碼段-06的腳本創(chuàng)建manifest list。

//代碼段-06

#!/bin/bash

IMAGE?=kofj/multi-demo

NOCOLOR:='33[0m'

RED:='33[0;31m'

GREEN:='33[0;32m'

LINUX_ARCH?=amd64 arm64 riscv64

IMAGES=$(foreach arch,$(LINUX_ARCH),$(IMAGE):$(arch))

echo${GREEN}Create manifest for${RED}(${LINUX_ARCH})${NOCOLOR};

docker manifest create${IMAGE}${IMAGES}

for arch in${LINUX_ARCH};do

echo${GREEN}Annotate manifest${RED}linux/$$arch${NOCOLOR};

echo===================;

docker manifest annotate${IMAGE}${IMAGE}:$$arch--os linux--arch$$arch;

done

推送manifest list

當(dāng)我們完成manifest list的創(chuàng)建工作后,它還是存儲(chǔ)在本地的。這時(shí)候,還需要推送到遠(yuǎn)端的鏡像倉(cāng)庫(kù)。與推送普通鏡像不同,推送manifest list需要使用docker manifest push命令進(jìn)行。如果我們要推送kofj/multi-demo這個(gè)manifest list,則命令如:

docker manifest push kofj/multi-demo

使用docker manifest push命令可以通過(guò)附加--purge選項(xiàng)在推送完成后刪除存儲(chǔ)在本地的manifest list;當(dāng)我們的目標(biāo)倉(cāng)庫(kù)沒(méi)有使用或者使用了非可信TLS證書(shū)的時(shí)候,則需要使用--insecure選項(xiàng)。

buildx自動(dòng)構(gòu)建

軟件依賴(lài)

·Docker19.03:自該Docker版本包含buildx。

·Linux kernel4.8:自該Linux內(nèi)核版本binfmt_misc支持fix-binary(F)flag。fix_binary標(biāo)志允許內(nèi)核在容器或chroot內(nèi)使用binfmt_misc注冊(cè)的二進(jìn)制格式處理程序,即使該處理程序二進(jìn)制文件不是該容器或chroot內(nèi)可見(jiàn)的文件系統(tǒng)的一部分。

·binfmt_misc file system mounted:需要掛載binfmt_misc文件系統(tǒng),以便用戶(hù)空間工具可以控制此內(nèi)核功能,即注冊(cè)和啟用處理程序。

·Docker Desktop2.1.0 如果是使用的Docker Desktop。

1609208399(1).png

1609208439(1).png

配置Buildx

buildx從19.03開(kāi)始與Docker CE捆綁發(fā)布,但是需要我們?cè)贒ocker CLI上啟用實(shí)驗(yàn)性功能開(kāi)開(kāi)啟??梢酝ㄟ^(guò)兩種方式啟用它:

1.將"experimental":"enabled”添加到Docker CLI的配置文件~/.docker/config.json。

2.另外一種方法時(shí)設(shè)置環(huán)境變量DOCKER_CLI_EXPERIMENTAL=enabled。

使用Docker Desktop的同學(xué)可以通過(guò)UI菜單Preferences→Command Line進(jìn)入Docker CLI配置界面,通過(guò)Switch開(kāi)關(guān)Enable experimental features啟用實(shí)驗(yàn)性功能。

640 (1).png

如果需要使用最新版本的buildx,可以從https://github.com/docker/buildx/releases/latest下載最新的二進(jìn)制發(fā)行版,并將其復(fù)制到~/.docker/cli-plugins文件夾中,重命名為docker-buildx,然后更改執(zhí)行權(quán)限:

chmod+x~/.docker/cli-plugins/docker-buildx

最后讓我們驗(yàn)證buildx是否已經(jīng)可用了:

$docker buildx version

github.com/docker/buildx v0.3.1-tp-docker 6db68d029599c6710a32aa7adcba8e5a344795a7

配置binfmt_misc

QEMU是一個(gè)很棒的開(kāi)源項(xiàng)目,它可以模擬很多平臺(tái)。將QEMU和Docker結(jié)合起來(lái)使用能使得我們更容易的構(gòu)建跨平臺(tái)的容器鏡像。集成QEMU依賴(lài)于Linux內(nèi)核功能。Linux內(nèi)核中的binfmt_misc功能可以使得內(nèi)核識(shí)別任意類(lèi)型的可以執(zhí)行文件格式,并傳遞到特定的用戶(hù)空間應(yīng)用程序和虛擬機(jī)(https://zh.wikipedia.org/wiki/Binfmt_misc)。當(dāng)Linux遇到一種無(wú)法識(shí)別的可執(zhí)行文件格式(比如說(shuō)其它平臺(tái)的可執(zhí)行文件格式)時(shí),它會(huì)檢查有沒(méi)有配置任何“用戶(hù)空間應(yīng)用程序”用于處理它。如果檢測(cè)到了,就將可執(zhí)行文件傳遞給該應(yīng)用程序。

為此,我們需要在內(nèi)核當(dāng)中注冊(cè)其它平臺(tái)的可執(zhí)行文件格式。

對(duì)于使用Docker Desktop(MacOS和Windows上都是)的同學(xué),因?yàn)槟J(rèn)配置了binfmt_misc,可以跳過(guò)這一步。而使用Linux發(fā)行版操作系統(tǒng)的同學(xué)則需要自行安裝配置binfmt_misc,以便能夠非原生的其它平臺(tái)的鏡像。

要在宿主機(jī)上執(zhí)行其它CPU平臺(tái)的指令,需要安裝QEMU模擬器。因?yàn)槌绦驁?zhí)行時(shí)會(huì)在當(dāng)前程序可見(jiàn)的文件系統(tǒng)中查找動(dòng)態(tài)庫(kù),而在容器或chroot環(huán)境中注冊(cè)的處理程序在其它的cgroup namespace中可能無(wú)法找到,所以需要靜態(tài)編譯連接的QEMU。同時(shí),我們需要安裝一個(gè)包含足夠新的update-binfmts二進(jìn)制文件的包,以便能夠支持fix-binary(F)標(biāo)志,并在注冊(cè)QEMU模擬器時(shí)實(shí)際使用,這樣才能結(jié)合buildx一起鏡像跨平臺(tái)構(gòu)建。

QEMU和binfmt_misc支持工具可以通過(guò)宿主機(jī)或者Docker容器鏡像安裝。但是,使用Docker鏡像安裝配置能讓事情變得更加簡(jiǎn)單。鏡像docker/binfmt中包含QEMU二進(jìn)制文件和在binfmt_misc中注冊(cè)QEMU的安裝腳本。

docker run--privileged docker/binfmt:66f9012c56a8316f9244ffd7622d7c21c1f6f28d

執(zhí)行完后,我們驗(yàn)證下是否注冊(cè)成功了。成功注冊(cè)后,/proc/sys/fs/binfmt_misc目錄中會(huì)有多個(gè)qemu-前綴的文件。查看/proc/sys/fs/binfmt_misc/qemu-aarch64文件內(nèi)容,可以看到falgs標(biāo)志為OCF,說(shuō)明這個(gè)處理程序是通過(guò)(F)標(biāo)志注冊(cè)的,能夠正常的結(jié)合buildx完成跨平臺(tái)構(gòu)建。

root kofj-hk~ls-al/proc/sys/fs/binfmt_misc

total 0

drwxr-xr-x 2 root root 0 Oct 12 20:19.

dr-xr-xr-x 1 root root 0 Oct 12 20:19..

-rw-r--r--1 root root 0 Oct 12 20:19 python2.7

-rw-r--r--1 root root 0 Oct 12 20:19 python3.6

-rw-r--r--1 root root 0 Oct 12 20:21 qemu-aarch64

-rw-r--r--1 root root 0 Oct 12 20:21 qemu-arm

-rw-r--r--1 root root 0 Oct 12 20:21 qemu-ppc64le

-rw-r--r--1 root root 0 Oct 12 20:21 qemu-s390x

--w-------1 root root 0 Oct 12 20:19 register

-rw-r--r--1 root root 0 Oct 12 20:19 status

root kofj-hk~cat/proc/sys/fs/binfmt_misc/qemu-aarch64

enabled

interpreter/usr/bin/qemu-aarch64

flags:OCF

offset 0

magic 7f454c460201010000000000000000000200b7

mask ffffffffffffff00fffffffffffffffffeffff

使用buildx構(gòu)建

前置依賴(lài)注備好后,我們終于可以使用buildx構(gòu)建多平臺(tái)鏡像了。與其它方案不同的是,使用buildx可以讓我們不必改動(dòng)dockerfile。

Buildx始終使用BuildKit引擎構(gòu)建鏡像,不需要配置環(huán)境變量DOCKER_BUILDKIT=1。BuildKit可以很好的用于多個(gè)平臺(tái)的構(gòu)建,而不僅適用于我們當(dāng)前構(gòu)建鏡像時(shí)所使用的平臺(tái)和操作系統(tǒng)。進(jìn)行構(gòu)建時(shí),使用--platform標(biāo)志可以用于指定構(gòu)建輸出的目標(biāo)平臺(tái)(例如linux/amd64,linux/arm64,linux/riscv64)。

首先,我們先準(zhǔn)備好Dockerfile文件:

FROM golang:1.14 as builder

COPY./src

WORKDIR/src

RUN ls-al&&go build-a-tags netgo-ldflags'-w'-mod=vendor-v-o/src/bin/webapp/src/cmd/main.go

#Final image

FROM ubuntu:18.04

LABEL authors="Fanjian Kong"

COPY--from=builder/src/bin/webapp/app/

WORKDIR/app

CMD["/app/webapp"]

然后,讓我們嘗試下運(yùn)行buildx。

root kofj-hk~docker buildx build--platform linux/amd64,linux/arm64,linux/arm-t harbor-community.tencentcloudcr.com/multi-arch/demo:2020-10-12.--push

error:auto-push is currently not implemented for docker driver,please create a new builder instance

居然報(bào)錯(cuò)error:auto-push is currently not implemented for docker driver,please create a new builder instance了!別擔(dān)心,這是因?yàn)镈ocker默認(rèn)的builder是不支持多平臺(tái)構(gòu)建的。我們可以通過(guò)docker buildx ls查看當(dāng)前節(jié)點(diǎn)上的builder有哪些。

root kofj-hk~docker buildx ls

NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS

default*docker

default default running linux/amd64,linux/386

為了使用多平臺(tái)構(gòu)建功能,我們需要新建一個(gè)builder,并設(shè)置當(dāng)前builder為新建的。

#新建同時(shí)切換builder

docker buildx create--use--name mybuilder

#只新建,然后再切換builder

docker buildx create--name mybuilder

docker buildx use mybuilder

現(xiàn)在,讓我們?cè)俅螆?zhí)行buildx,看著一切向著期待的方向發(fā)展了。

注意事項(xiàng)

注意1:到目前位置,buildx支持linux/amd64,linux/386,linux/arm/v7,linux/arm/v6,linux/arm64,linux/ppc64le,linux/s390x。所以docker/binfmt鏡像僅注冊(cè)了arm、ppc64le和s390x的處理程序。如果你需要構(gòu)建、運(yùn)行RISC-V平臺(tái)的容器鏡像,建議使用multiarch/qemu-user-static鏡像鏡像配置。

docker run--rm--privileged multiarch/qemu-user-static--reset-p yes

注意2:在軟件依賴(lài)中我們提到需要Linux內(nèi)核版本>=4.8.0;如果在內(nèi)核版本為3.10.0的系統(tǒng)(比如CentOS)上運(yùn)行docker/binfmt,會(huì)出現(xiàn)報(bào)錯(cuò)Cannot write to/proc/sys/fs/binfmt_misc/register:write/proc/sys/fs/binfmt_misc/register:invalid argument,這是由于內(nèi)核不支持(F)標(biāo)志造成的。出現(xiàn)這種情況,建議您升級(jí)系統(tǒng)內(nèi)核或者換使用較高版本內(nèi)核的Linux發(fā)行版。

640 (2).png

小結(jié)

多年前,大規(guī)模部署應(yīng)用程序是一項(xiàng)非常耗費(fèi)人力、財(cái)力、時(shí)間,還需要大量技能和技巧的事務(wù),工程師們還需要應(yīng)對(duì)應(yīng)用程序所運(yùn)行的每一臺(tái)服務(wù)器的環(huán)境差異。這對(duì)大公司而言是個(gè)極其沉重的負(fù)擔(dān),小公司更是無(wú)力應(yīng)對(duì)。

正如多年前人們無(wú)法想象大規(guī)模部署復(fù)雜的應(yīng)用程序只需要一個(gè)kubectl create命令,不久前我們也不會(huì)想到構(gòu)建多平臺(tái)的容器鏡像只需要一個(gè)docker buildx build。但是,我們還有更加廣闊的想象空間,自動(dòng)化流程、更多平臺(tái)的支持、更智能簡(jiǎn)單的工具,你能想到的都有可能在不久的將來(lái)變成現(xiàn)實(shí)。

技術(shù)的發(fā)展進(jìn)步,不斷降低了生產(chǎn)活動(dòng)中社會(huì)平均勞動(dòng)時(shí)間,提升了生產(chǎn)力,能夠釋放勞動(dòng)者去做更多有益的探索。讓我們不斷學(xué)習(xí)、擁抱、應(yīng)用新技術(shù),在時(shí)代的浪潮中勇往直前。

可執(zhí)行方案回顧

1.確保使用的Linux發(fā)行版內(nèi)核>=4.8.0(推薦使用Ubuntu 18.04以上的TLS發(fā)行版),且Docker>=19.03;

2.啟用Docker CLI實(shí)驗(yàn)性功能:export DOCKER_CLI_EXPERIMENTAL=enabled;

3.配置其它平臺(tái)的模擬器:docker run--privileged docker/binfmt:66f9012c56a8316f9244ffd7622d7c21c1f6f28d;

4.新建Docker builder實(shí)例支持多平臺(tái)構(gòu)建:docker buildx create--use--name mybuilder;

5.在項(xiàng)目目錄中執(zhí)行構(gòu)建:docker buildx build--platform linux/amd64,linux/arm64,linux/arm-t harbor-community.tencentcloudcr.com/${YOUR_NAMESPACE}/multi-arch:2020-10-12.--push。

6.相關(guān)演示代碼、腳本可以在https://github.com/kofj/multi-arch-demo.git獲取。

推廣時(shí)間

目前,騰訊云容器鏡像服務(wù)TCR已完成公測(cè)進(jìn)入商業(yè)化階段。我們也已經(jīng)對(duì)部分用戶(hù)開(kāi)放了Multi Arch鏡像和OCI云原生制品支持。如果您對(duì)該功能感興趣,歡迎聯(lián)系客服開(kāi)通。

640 (3).png

立即登錄,閱讀全文
版權(quán)說(shuō)明:
本文內(nèi)容來(lái)自于騰訊云原生,本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個(gè)人觀點(diǎn),不代表快出海對(duì)觀點(diǎn)贊同或支持。如有侵權(quán),請(qǐng)聯(lián)系管理員(zzx@kchuhai.com)刪除!
相關(guān)文章
騰訊云數(shù)據(jù)庫(kù)PostgreSQL全面支持PG 17
騰訊云數(shù)據(jù)庫(kù)PostgreSQL全面支持PG 17
即日起,騰訊云PostgreSQL全面支持PostgreSQL 17.0。所有用戶(hù)可使用大版本升級(jí)能力升級(jí)至最新的PostgreSQL 17.0進(jìn)行體驗(yàn),也可以在產(chǎn)品購(gòu)買(mǎi)頁(yè)直接購(gòu)買(mǎi)。
騰訊云
云服務(wù)
2024-12-152024-12-15
高可用這個(gè)問(wèn)題,加機(jī)器就能解決?
高可用這個(gè)問(wèn)題,加機(jī)器就能解決?
互聯(lián)網(wǎng)服務(wù)的可用性問(wèn)題是困擾企業(yè)IT人員的達(dá)摩克利斯之劍:防于未然,體現(xiàn)不出價(jià)值。已然發(fā)生,又面臨P0危機(jī)。就更別提穩(wěn)定性建設(shè)背后顯性的IT預(yù)算問(wèn)題與隱性的人員成本問(wèn)題。
騰訊云
云服務(wù)
2024-11-252024-11-25
TDSQL TDStore引擎版替換HBase:在歷史庫(kù)場(chǎng)景中的成本與性能優(yōu)勢(shì)
TDSQL TDStore引擎版替換HBase:在歷史庫(kù)場(chǎng)景中的成本與性能優(yōu)勢(shì)
HBase憑借其高可用性、高擴(kuò)展性和強(qiáng)一致性,以及在廉價(jià)PC服務(wù)器上的低部署成本,廣泛應(yīng)用于大規(guī)模數(shù)據(jù)分析。
騰訊云
云服務(wù)
2024-11-042024-11-04
復(fù)雜查詢(xún)性能弱,只讀分析引擎來(lái)幫忙
復(fù)雜查詢(xún)性能弱,只讀分析引擎來(lái)幫忙
隨著當(dāng)今業(yè)務(wù)的高速發(fā)展,復(fù)雜多表關(guān)聯(lián)的場(chǎng)景越來(lái)越普遍。但基于行式存儲(chǔ)的數(shù)據(jù)庫(kù)在進(jìn)行復(fù)雜查詢(xún)時(shí)性能相對(duì)較弱。
騰訊云
云服務(wù)
2024-11-022024-11-02
優(yōu)質(zhì)服務(wù)商推薦
更多
掃碼登錄
打開(kāi)掃一掃, 關(guān)注公眾號(hào)后即可登錄/注冊(cè)
加載中
二維碼已失效 請(qǐng)重試
刷新
賬號(hào)登錄/注冊(cè)
小程序
快出海小程序
公眾號(hào)
快出海公眾號(hào)
商務(wù)合作
商務(wù)合作
投稿采訪
投稿采訪
出海管家
出海管家