兩個小技巧提升Docker鏡像構建性能,效率翻倍!

閱讀:545 2023-11-03 22:48:28

和大多數公司一樣,我們為產品中使用的所有組件構建Docker鏡像。隨著時間的推移,其中一些鏡像變得越來越大,同時持續集成(CI)構建也變得越來越長。我的目標是讓CI構建時間不超過5分鐘。

生產力下降的原因如下:

  • 開發人員需要等待構建完成,從而浪費時間。
  • 開發人員開始著手新任務,并需要稍后返回。這需要進行更多的上下文切換,通常也會導致效率低下。

在本文中,我們應用了兩個小的改進,使得構建時間大幅度提高。在介紹兩個改進之前,首先確保你已經遵循了編寫Dockerfile的最佳實踐,例如:

  • 盡量減少層數
  • 使用多階段構建
  • 使用最小基礎鏡像
  • ……

Buildkit和Buildx

讓我們解釋一下Buildkit和Buildx,因為這兩個術語經常被互換使用,但它們并不是完全相同的。在撰寫本文之前,我也沒有完全理解兩者之間的區別。

Buildkit

Buildkit是改進后的后端,用于取代傳統的Docker構建器。從2018年開始,它與Docker一起打包,并在docker引擎23.0中成為默認構建器。

Buildkit提供了許多實用的功能:

  • 緩存能力改進
  • 不同層并行構建
  • 延遲拉取基礎鏡像(≥ Buildkit 0.9)

使用Buildkit時,你應該會注意到docker build命令的輸出看起來更干凈、更有結構。

在Docker版本低于23.0的情況下,使用Buildkit的典型方法是按照以下方式設置Buildkit參數:

復制
`--build-arg BUILDKIT_INLINE_CACHE=1`
  • 1.
 

這將啟用內聯緩存,可以顯著加快構建過程。但是,這在Docker版本低于23.0的情況下不可用。

復制
DOCKER_BUILDKIT=1 docker build --platform linux/amd64 . -t someImage:someVersion
DOCKER_BUILDKIT=1 docker push someImage:someVersion
  • 1.
  • 2.
 

Buildx

Buildx是Docker的一個插件,它讓你能夠充分利用Buildkit在Docker中的能力。它之所以被創建,是因為Buildkit支持許多新的配置選項,這些選項無法以向后兼容的方式全部集成到docker build命令中。

除了構建鏡像之外,Buildx還支持管理多個構建器。這在持續集成中非常有用,可以定義范圍明確且具有不同配置的環境,因為它們不會修改共享的Docker守護進程。

可以按照以下步驟開始使用Buildx:

復制
docker buildx create --bootstrap --name builder
docker buildx use builder
  • 1.
  • 2.
 

一、從遠程緩存中受益

加快構建速度的第一個方法是將鏡像緩存在遠程注冊表中。這樣,即使在不同的機器上執行構建時(例如CI中的常見情況),仍然可以從構建緩存中受益。大多數人在構建新版本的鏡像之前會拉取最新版本的鏡像。這樣做的好處是可以緩存未更改的層,但代價是最初需要拉取完整的鏡像。拉取完整鏡像可能需要一些時間,而且也不能保證可以重用這些層。使用以下命令進行說明:

復制
docker pull someImage:latest || true docker build --platform linux/amd64 . \ -t someImage:someVersion \ -f Dockerfile \ --cache-from someImage:latest
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
 

使用 Buildx,可以將緩存信息存儲在遠程位置(例如容器注冊表、blob 存儲等)。構建器會檢查給定的層是否已經存在,如果存在,它將重用該層而不是重新創建它。甚至無需將層拉取到本地即可實現此功能。如下所示:

復制
docker buildx build --platform linux/amd64 . \ -t someImage:someVersion - push \ --cache-to type=registry,ref=someCachedImage:someVersion,mode=max --cache-from type=registry,ref=someCachedImage:someVersion
  • 1.
  • 2.
  • 3.
  • 4.
 

模式“max”表示我們將為每個層存儲構建信息,即使這些層在最終的鏡像中未被使用(例如在使用多階段構建時)。默認情況下,使用模式“min”,它僅存儲關于最終鏡像中存在的層的構建信息。

緩存存在一個特殊情況是將緩存數據“內聯”存儲,這意味著它將與鏡像一起緩存。在使用Buildkit沒有使用Buildx時也支持此選項。但在使用多階段構建時會更具挑戰性,并且它無法清晰地區分構建產物的輸出和緩存。緩存數據“內聯”存儲的命令如下所示:

復制
docker buildx build - platform linux/amd64 . \ -t someImage:someVersion --push \ --cache-to type=inline,mode=max \ --cache-from someImage:somePreviousVersion
  • 1.
  • 2.
  • 3.
  • 4.
 

二、添加文件到鏡像的新方法

Docker推出了新版本的Dockerfile語法,即#syntax=docker/dockerfile:1.4。它支持COPY和ADD命令的額外鏈接選項。

以前,當使用COPY或ADD命令時,構建器會創建一個新的快照,將新文件與已存在的文件系統合并。結果是,在執行此操作之前,父層都需要存在,不然的話目標目錄可能還不存在。最終的鏡像(構建命令的結果)將由每個層的tarball組成,其中包含相應快照之間的差異。

復制
FROM baseImage:version COPY binary /opt/
  • 1.
  • 2.
 

使用鏈接選項時,新文件將放入自己的快照中,而不會依賴于先前的層。鏈接的文件存儲在自己的tarball中,并且不同的tarball相互鏈接在一起,而不會依賴于現有的文件系統,如下圖所示。

復制
# syntax=docker/dockerfile:1.4 FROM baseImage:version COPY [--chown=<user>:<group>] [--chmod=<perms>] --link binary /opt/
  • 1.
  • 2.
  • 3.
 

主要的優勢是文件不再依賴于先前的層。只要文件沒有改變,即使父層發生了更改,該層也可以重復使用。

并且還可以提高構建速度,因為現在可以并行執行多個層復制數據的操作。

結論

通過上述兩種方式,我們將鏡像構建速度提升了 1 倍。

相關文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感興趣
推薦閱讀 更多>
推薦商標

{{ v.name }}

{{ v.cls }}類

立即購買 聯系客服
主站蜘蛛池模板: 亚洲爆乳大丰满无码专区| 无码欧精品亚洲日韩一区| 亚洲日韩精品无码一区二区三区| 无码人妻一区二区三区av| 一区二区三区人妻无码| 无码专区久久综合久中文字幕| 精品无码中出一区二区| 亚洲AV人无码综合在线观看| 精品无码一区二区三区爱欲| 亚洲中文字幕无码中文字在线| 无码专区天天躁天天躁在线| 国产V片在线播放免费无码| 国产成人无码AV在线播放无广告| 国产成人无码一区二区在线观看 | 无码毛片内射白浆视频| 精品无码人妻一区二区免费蜜桃| 秋霞鲁丝片无码av| 中文字幕无码亚洲欧洲日韩| 久久久久亚洲AV无码专区首JN| 亚洲AV日韩AV永久无码绿巨人| 精品无码中出一区二区| 亚洲AV无码一区二区大桥未久| 熟妇人妻无码中文字幕| 亚洲VA中文字幕无码一二三区 | 色视频综合无码一区二区三区| 亚洲AV综合色区无码二区偷拍| 国产在线无码视频一区二区三区 | 四虎成人精品无码永久在线| 97在线视频人妻无码| 人妻丰满熟妞av无码区| 亚洲国产精品无码专区| 中文字幕无码无码专区| 国精品无码一区二区三区左线 | 无码中文字幕日韩专区视频| 国产精品99久久久精品无码| 伊人久久综合精品无码AV专区| 久久久久久av无码免费看大片| 狠狠躁天天躁无码中文字幕| 久久午夜无码免费| 无码精品国产VA在线观看| 无码人妻少妇久久中文字幕蜜桃|