建指南:讀懂 samples/builder 的 docker buildx bake 流水線)
Istio 示例鏡像構(gòu)建指南讀懂 samples/builder 的 docker buildx bake 流水線【免費(fèi)下載鏈接】istioConnect, secure, control, and observe services.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/is/istioIstio 倉(cāng)庫(kù)的許多示例bookinfo、helloworld、tcp-echo 等都需要隨發(fā)布流程打制成容器鏡像。本指南聚焦 samples/builder/README.md 及其背后真正起作用的 samples/builder/docker-bake.hcl講清這套集中式鏡像構(gòu)建邏輯如何運(yùn)作、如何用一條docker buildx bake命令構(gòu)建并推送全部或部分示例鏡像、如何覆蓋鏡像倉(cāng)庫(kù)與目標(biāo)平臺(tái)以及官方鏡像與示例鏡像更新時(shí)應(yīng)當(dāng)遵守的版本維護(hù)流程。讀完你既能直接在本地復(fù)現(xiàn)構(gòu)建也能理解 HCL 矩陣配置與多階段構(gòu)建源碼之間的配合關(guān)系。目錄定位為什么需要一個(gè)集中的 sample builderIstio 倉(cāng)庫(kù)根目錄下有大量示例應(yīng)用目錄每個(gè)示例自身通常帶有 Dockerfile 與對(duì)應(yīng)的 K8s YAML。長(zhǎng)久以來(lái)鏡像構(gòu)建邏輯分散在各示例目錄里容易重復(fù)、不一致。samples/builder目錄的存在就是為了把各種示例的鏡像構(gòu)建邏輯集中起來(lái)consolidate things便于統(tǒng)一維護(hù)版本、統(tǒng)一打 multi-arch 標(biāo)簽并推送到統(tǒng)一的鏡像倉(cāng)庫(kù)。需要留意 README 給出的兩個(gè)邊界條件仍有一些鏡像使用各自目錄內(nèi)的構(gòu)建配置因此samples/builder覆蓋范圍并不完整——例如多數(shù)傳統(tǒng)示例仍使用各目錄獨(dú)立的鏡像打包與 CI 流程本目錄當(dāng)前采用Docker Buildx BakeHCL作為唯一構(gòu)建入口構(gòu)建邏輯真正落在 docker-bake.hcl 這一個(gè)文件中README.md只是操作說(shuō)明。構(gòu)建配置核心讀透 docker-bake.hcldocker-bake.hcl 全部 45 行定義了整套鏡像矩陣從文件結(jié)構(gòu)可以拆分出三個(gè)層次。1. 可變變量可在命令行覆蓋variable HUB { default localhost:5000 } variable PLATFORMS { default linux/amd64,linux/arm64 }HUB鏡像倉(cāng)庫(kù)地址前綴默認(rèn)localhost:5000即默認(rèn)推送到本機(jī)運(yùn)行的 registryPLATFORMS目標(biāo)平臺(tái)列表默認(rèn)同時(shí)構(gòu)建linux/amd64與linux/arm64兩種架構(gòu)。兩個(gè)變量在 bake 時(shí)都可以通過(guò)--set或環(huán)境方式覆蓋詳見(jiàn)下文構(gòu)建與推送一節(jié)。2. 鏡像清單 images當(dāng)前清單包含三組鏡像其中 helloworld 的 v1/v2 共享同一份源碼../helloworld/src僅通過(guò)構(gòu)建參數(shù)service_version區(qū)分images [ { name tcp-echo-server source ../tcp-echo/src tags [1.3, latest] }, { name examples-helloworld-v1 source ../helloworld/src args { service_version v1 } tags [1.0, latest] }, { name examples-helloworld-v2 source ../helloworld/src args { service_version v2 } tags [1.0, latest] }, ]每個(gè)條目包含四個(gè)字段其作用分別是字段含義當(dāng)前取值示例name鏡像名不含倉(cāng)庫(kù)前綴tcp-echo-server、examples-helloworld-v1/v2source構(gòu)建上下文相對(duì) docker-bake.hcl 的路徑../tcp-echo/src、../helloworld/srcargs傳給 Dockerfile 的ARG構(gòu)建參數(shù)service_version v1tags版本標(biāo)簽列表除語(yǔ)義化版本外通常帶latest[1.3, latest]source字段體現(xiàn)了本倉(cāng)庫(kù)真實(shí)的目錄布局三個(gè)鏡像的實(shí)際構(gòu)建上下文分別指向 samples/tcp-echo/src 與 samples/helloworld/src說(shuō)明 builder 目錄本身只是編排層鏡像源碼仍留在各自的示例目錄中。3. default target矩陣展開(kāi)生成最終 targettarget default { matrix { item images } name item.name context ${item.source} tags [ for x in setproduct([HUB], item.tags) : join(/${item.name}:, x) ] args lookup(item, args, {}) platforms split(,, lookup(item, platforms, PLATFORMS)) }這段 HCL 的關(guān)鍵機(jī)制如下matrix.item images把上面的鏡像清單作為矩陣輸入Buildx 會(huì)為清單中每一項(xiàng)自動(dòng)生成一個(gè)獨(dú)立的 bake targettarget 名稱(chēng)即item.namecontext ${item.source}每個(gè) target 使用各自聲明的構(gòu)建上下文目錄標(biāo)簽的生成使用setproduct將[HUB]與該項(xiàng)的tags做笛卡爾積再用join(/${item.name}:, x)拼出完整標(biāo)簽例如默認(rèn)HUB下 tcp-echo-server 會(huì)被打上localhost:5000/tcp-echo-server:1.3localhost:5000/tcp-echo-server:latestlookup(item, args, {})與lookup(item, platforms, PLATFORMS)表示當(dāng)某個(gè)條目未顯式聲明對(duì)應(yīng)字段時(shí)分別回落為無(wú)構(gòu)建參數(shù)與全局PLATFORMS默認(rèn)值。這一設(shè)計(jì)使后續(xù)新增鏡像只需向images清單追加一個(gè)條目即可自動(dòng)獲得矩陣構(gòu)建、多架構(gòu)支持與統(tǒng)一打標(biāo)簽?zāi)芰o(wú)需復(fù)制粘貼 target。鏡像背后的源碼兩個(gè)示例的構(gòu)建上下文集中構(gòu)建并不代表鏡像實(shí)現(xiàn)集中最終成果由各示例目錄中的 Dockerfile 與程序源碼決定理解它們有助于排查構(gòu)建失敗或按需裁剪鏡像。helloworldPython 構(gòu)建期參數(shù)區(qū)分版本samples/helloworld/src/Dockerfile 基于python:3.12.1-slim將app.py與固定哈希的requirements.txt拷貝進(jìn)/opt/microservices安裝依賴(lài)并額外裝入curl作為可選的客戶(hù)端工具。其中與 bake 矩陣對(duì)接的關(guān)鍵行ARG service_version ENV SERVICE_VERSION${service_version:-v1} CMD [gunicorn, -b, [::]:5000, app:app, -k, gevent]同一份源碼通過(guò)service_version這一個(gè) ARG 產(chǎn)出 v1/v2 兩個(gè)鏡像鏡像運(yùn)行后會(huì)根據(jù)該環(huán)境變量返回不同版本的響應(yīng)——這正是 helloworld 示例用于演示金絲雀發(fā)布把流量在 v1/v2 間灰度切分的基礎(chǔ)默認(rèn)監(jiān)聽(tīng)[::]:5000TCP6若在 K8s Pod 中需要強(qiáng)制 IPv4可在 Deployment 的 command 中覆蓋為[gunicorn, -b, [0.0.0.0]:5000, app:app, -k, gevent]。tcp-echo多階段構(gòu)建產(chǎn)出精簡(jiǎn)靜態(tài)鏡像samples/tcp-echo/src/Dockerfile 使用經(jīng)典的兩階段構(gòu)建第一階段基于golang:1.22編譯第二階段從scratch起步僅拷貝靜態(tài)二進(jìn)制FROM golang:1.22 AS builder WORKDIR /go/src/istio.io/tcp-echo-server/ COPY main.go . RUN CGO_ENABLED0 GOOSlinux go build -ldflags -extldflags -static -s -w -o tcp-echo main.go FROM scratch COPY --frombuilder /go/src/istio.io/tcp-echo-server/tcp-echo . ENTRYPOINT [ /bin/tcp-echo ] CMD [ 9000, hello ]CGO_ENABLED0關(guān)閉 CGO 并靜態(tài)鏈接保證產(chǎn)物能在無(wú) glibc 的scratch中運(yùn)行鏡像體積最小化從 samples/tcp-echo/src/main.go 可見(jiàn)程序邏輯通過(guò)命令行接收逗號(hào)分隔的端口列表與響應(yīng)前綴每收到一行輸入就回顯prefix 原始數(shù)據(jù)Dockerfile 的默認(rèn)CMD對(duì)應(yīng)監(jiān)聽(tīng) 9000 端口、前綴為 hello該行為與 tcp-echo 示例 YAML 的用途完全匹配——它是 Istio 官方向?qū)е醒菔?TCP 流量路由v1/v2 端口分流的主要樣例。構(gòu)建與推送示例鏡像本地測(cè)試README 中給出的核心命令是docker buildx bake --push該命令會(huì)構(gòu)建全部鏡像并推送。完整的行為由 docker-bake.hcl 決定包括默認(rèn)推送目標(biāo)為localhost:5000因此你需要在構(gòu)建機(jī)上先運(yùn)行一個(gè)本地 registry例如docker run -d -p 5000:5000 --name registry registry:2才能讓--push成功默認(rèn)同時(shí)構(gòu)建linux/amd64,linux/arm64需要 docker buildx 已配置好支持多架構(gòu)的 builder如docker-containerdriver否則會(huì)退回單平臺(tái)或報(bào)錯(cuò)。兩個(gè)默認(rèn)值都可以覆蓋# 推送到其它本地/私有倉(cāng)庫(kù) HUBmyregistry.example.com:5000 docker buildx bake --push # 僅構(gòu)建單一架構(gòu)加快本地迭代 HUBlocalhost:5000 PLATFORMSlinux/amd64 docker buildx bake --push從 docker-bake.hcl 的實(shí)現(xiàn)看HUB與PLATFORMS是通過(guò) HCL 變量注入的tags展開(kāi)時(shí)引用[HUB]platforms展開(kāi)時(shí)把PLATFORMS按逗號(hào)切分因此在 bake 命令前以VARvalue形式賦值即可覆蓋 HCL 中的 default。只構(gòu)建部分鏡像并非每次都需要全量構(gòu)建可以顯式點(diǎn)名部分 targetdocker buildx bake --push examples-helloworld-v1 tcp-echo-server由于defaulttarget 采用矩陣展開(kāi)target 名就等于 images 清單里的name字段因此上例只構(gòu)建并推送 helloworld v1 與 tcp-echo-server 兩個(gè)鏡像適合在修改了某個(gè)示例源碼后做定向驗(yàn)證避免把整個(gè)矩陣重新跑一遍。更新示例鏡像版本的流程當(dāng)示例源碼或依賴(lài)發(fā)生變化、需要發(fā)布新鏡像時(shí)README 明確了兩個(gè)動(dòng)作二者缺一不可在 docker-bake.hcl 的tags配置中遞增版本。以 tcp-echo-server 為例當(dāng)前標(biāo)簽為[1.3, latest]若本次要發(fā)新版本應(yīng)改為[1.4, latest]這類(lèi)新版本號(hào)同時(shí)保持latest指向最新構(gòu)建同步更新引用該鏡像的示例 YAML。倉(cāng)庫(kù)中 Deployment 等編排文件里硬編碼了鏡像地址與 tag例如 samples/helloworld/helloworld.yaml 中寫(xiě)有image: registry.istio.io/release/examples-helloworld-v1:1.0第 36 行與 v2 對(duì)應(yīng)的:1.0第 65 行。這些 tag 必須與 docker-bake.hcl 中聲明的 tag 保持一致否則發(fā)布到鏡像倉(cāng)庫(kù)的新版本不會(huì)被示例默認(rèn)引用。本質(zhì)上tags列表與 K8s YAML 的image:字段共同構(gòu)成鏡像發(fā)布約定二者需要成對(duì)更新這也是 README 特別提醒更新鏡像時(shí)還要更新示例 YAML的原因。構(gòu)建官方發(fā)布鏡像的注意事項(xiàng)官方發(fā)布流程與本地測(cè)試流程的唯一差別是倉(cāng)庫(kù)前綴HUBregistry.istio.io/release docker buildx bake --push此時(shí)所有鏡像將被推送至 Istio 官方發(fā)布倉(cāng)庫(kù)例如 helloworld v1 會(huì)被打上registry.istio.io/release/examples-helloworld-v1:1.0之類(lèi)的完整標(biāo)簽與上面提到的示例 YAML 引用地址對(duì)應(yīng)。README 特別強(qiáng)調(diào)了一個(gè)操作紀(jì)律每個(gè)鏡像最好只在官方倉(cāng)庫(kù)發(fā)布一次以避免意外覆蓋已經(jīng)存在的既有鏡像。原因在于一旦某個(gè) tag尤其latest被發(fā)布后續(xù)任何非預(yù)期的重新構(gòu)建都可能向該 tag 推送內(nèi)容不同、無(wú)法追溯的鏡像破壞可復(fù)現(xiàn)性與供應(yīng)鏈可審計(jì)性。因此執(zhí)行官方構(gòu)建前應(yīng)仔細(xì)核對(duì)tags確認(rèn)版本號(hào)確實(shí)需要新增/變更再對(duì)目標(biāo)鏡像執(zhí)行一次構(gòu)建。局限性與適用前提在使用這套構(gòu)建方案時(shí)請(qǐng)記住以下事實(shí)約束均來(lái)自倉(cāng)庫(kù)現(xiàn)狀samples/builder目前管理的鏡像只有 helloworldv1/v2與 tcp-echo-server 三類(lèi)bookinfo、httpbin、sleep 等其它示例鏡像仍由各自目錄內(nèi)的 Dockerfile 與構(gòu)建腳本維護(hù)不在本 bake 矩陣內(nèi)全部構(gòu)建邏輯基于 Docker Buildx BakeHCL因此環(huán)境需要具備較新的 Docker 與 buildx 插件且--push依賴(lài)已運(yùn)行的 registry若在離線或受限網(wǎng)絡(luò)環(huán)境構(gòu)建需要注意 helloworld 基礎(chǔ)鏡像與 pip 依賴(lài)的拉取requirements.txt 采用--require-hashes固定哈希安裝tcp-echo 則依賴(lài) Go 工具鏈鏡像。相關(guān)文件速查構(gòu)建編排入口samples/builder/README.md、samples/builder/docker-bake.hclhelloworld 鏡像上下文samples/helloworld/src/Dockerfile、samples/helloworld/src/app.py、samples/helloworld/helloworld.yamltcp-echo 鏡像上下文samples/tcp-echo/src/Dockerfile、samples/tcp-echo/src/main.go、samples/tcp-echo/tcp-echo.yaml掌握 samples/builder/docker-bake.hcl 的矩陣寫(xiě)法后為倉(cāng)庫(kù)新增一個(gè)示例鏡像的成本極低只需向images清單追加一條帶name、source、tags的記錄如需版本差異化再加argsdefaulttarget 就會(huì)自動(dòng)完成多架構(gòu)構(gòu)建、倉(cāng)庫(kù)前綴拼接與打標(biāo)簽工作再用文中命令執(zhí)行構(gòu)建推送、并按版本 示例 YAML成對(duì)更新的流程完成發(fā)布即可?!久赓M(fèi)下載鏈接】istioConnect, secure, control, and observe services.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/is/istio創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考