利用Makisu構(gòu)建容器鏡像
本系列文章深入研究了容器鏡像構(gòu)建的最新技術(shù)。我們已經(jīng)介紹了Podman和Buildah、Img、Kaniko,而這次輪到Makisu了。 Makisu是另一個開源鏡像構(gòu)建工具,由Uber的工程團隊構(gòu)思而成。像許多其他開源項目一樣,Makisu也是基于其他類似技術(shù)的不足而開發(fā)的。 Makisu尤其專注于優(yōu)化鏡像構(gòu)建時間和大小。
使用Makisu** 類似Kaniko,Makisu不會調(diào)用容器并依據(jù)Dockerfile指令在容器中構(gòu)建鏡像。它既可以作為獨立的二進制文件在本地運行,也可以作為沙箱運行在容器內(nèi)。但是,由于它無法執(zhí)行RUN Dockerfile指令,因此它作為獨立二進制文件的用途受到限制。當(dāng)然,你也不希望Makisu通過RUN指令更改主機的本地文件系統(tǒng)內(nèi)容! 實際上Makisu不允許更改本地文件;你需要指定標志--modifyfs = true,以允許使用命令對文件系統(tǒng)進行更改。
但請注意,如果使用--modifyfs = true運行獨立的Makisu二進制文件,最終將刪除主機的許多rootfs。 Makisu被設(shè)計為在容器中運行,在容器中更改文件系統(tǒng)內(nèi)容是安全的。 實際上用于執(zhí)行構(gòu)建的Makisu本身的容器鏡像很少。它是基于基本圖像指令(scratch base image directive)構(gòu)建的,僅包含Makisu二進制文件和根CA證書的文件。
需要使用卷將構(gòu)建上下文(包括Dockerfile)提供給容器。 Makisu提取Dockerfile中定義的基本鏡像,并將其文件系統(tǒng)提取到其容器內(nèi)。它還將此文件系統(tǒng)的副本存儲在內(nèi)存中。
隨后的構(gòu)建步驟針對該文件系統(tǒng)的內(nèi)容運行,然后對其進行掃描以查找更改。任何更改也會反映在“內(nèi)存”的副本中,并創(chuàng)建一個包含更改的新“差異層”。 “差異層”層緩存在目錄中,以供將來的版本使用,前提是用于存儲的卷已經(jīng)被掛載。 Dockerfile中定義的構(gòu)建步驟以這種方式執(zhí)行到完成,然后Makisu將構(gòu)建的鏡像推送到容器鏡像倉庫(如果已指定)。如果將Docker用作Makisu的容器運行時,則可以使用以下命令調(diào)用構(gòu)建容器: ``` $ docker run --rm \ -v $(pwd):/makisu-context \ -v /tmp/makisu-storage:/makisu-storage \ gcr.io/makisu-project/makisu:v0.1.12 build \ --tag=mycorp/my-app:1d03df1 \ --push=quay.io \ --modifyfs=true \ /makisu-context ``` 如果你閱讀了本系列的上一篇文章,你將已經(jīng)得出結(jié)論,如Kaniko一樣,Makisu將采用幾乎相同的方法來構(gòu)建鏡像。
你可以執(zhí)行構(gòu)建步驟而無需Docker守護程序,也無需運行嵌套容器所需的特權(quán)賬號。但是 Makisu的突出之處在于其構(gòu)建緩存實現(xiàn)的方法。 **緩存** 一旦決定放棄Docker守護進程構(gòu)建鏡像,你將失去其固有的緩存功能。 Docker守護程序提供的構(gòu)建步驟緩存可能不像許多人所希望的那樣具有豐富的功能,但是緩存是鏡像構(gòu)建的基本功能。通過復(fù)用以前執(zhí)行過的相同構(gòu)建步驟所生成的內(nèi)容,它有助于優(yōu)化構(gòu)建時間。對于Uber來說,這是促使他們決定創(chuàng)建替代容器鏡像構(gòu)建工具的重要因素之一。那么,Makisu通過緩存功能提供了什么?
分布式緩存
在Kubernetes設(shè)置中,包含構(gòu)建容器的Pod在理論上可以存在于集群內(nèi)的任何節(jié)點上。 這帶來了一個問題:構(gòu)建容器如何才能利用先前構(gòu)建迭代生成的緩存鏡像層? 我們可以嘗試迫使Pod落在執(zhí)行了先前構(gòu)建迭代的節(jié)點上,但這會影響調(diào)度程序的作用和目的。相反,Makisu利用分布式緩存來解決此問題。
首先,Makisu提供了Dockerfile指令序列和diff層摘要之間的本地映射。這些映射保存在鍵值存儲中,鍵值存儲可以是文件,分布式Redis緩存或基于HTTP的通用緩存。重要的是緩存是分布式的,因此可以由任何有權(quán)訪問緩存的Makisu構(gòu)建容器引用。 緩存中的映射使Makisu能夠確定是否需要執(zhí)行現(xiàn)有的構(gòu)建步驟,或者是否可以使用現(xiàn)有層的內(nèi)容。如果在緩存中找到匹配項,則可以從Makisu管理的本地存儲中解壓縮該圖層(如果它存在于本地存儲中),或者從鏡像倉庫中提取該圖層(如果已推送先前的構(gòu)建)。
緩存中的密鑰是從Dockerfile指令生成的,用于構(gòu)建步驟并與先前構(gòu)建步驟相關(guān)聯(lián)。關(guān)聯(lián)值是先前生成的鏡像層內(nèi)容的哈希值。如果構(gòu)建步驟指令序列與緩存中的現(xiàn)有鍵匹配,則Makisu將使用摘要(作為鍵值保存)來定位diff層。 緩存具有可配置的生存時間(TTL),以確保緩存的圖層不會過時。
選擇性提交(Optional Commits)
在使用Docker守護程序進行鏡像構(gòu)建期間,將為新生構(gòu)建或有更改內(nèi)容的每個構(gòu)建步驟生成diff層。這導(dǎo)致創(chuàng)建images鏡像非常臃腫。有時,可以通過合理地使用構(gòu)建步驟在控制這些中間層,或?qū)⒋罅棵罱M合到一個Dockerfile指令中來控制這些中間層的數(shù)量。 Makisu使用自己獨特的技術(shù)來緩解此問題。 Makisu的Dockerfile指令解析器引入了一個指令,該指令控制在構(gòu)建過程中何時提交差異層。語法#!COMMIT注釋的任何指令都被解析器解釋為生成新層。那些沒有該注釋的將不會生成新的層。
``` FROM alpine RUN apk add --no-cache wget RUN apk add --no-cache curl #!COMMIT ``` 在上面的示例中,安裝wget的RUN指令未提交為新層,而安裝curl的則被提交。它創(chuàng)建了一個圖層,其中包含自上一次提交以來或從構(gòu)建階段開始以來的所有新內(nèi)容。 當(dāng)為Makisu指定--commit = explicit標志時,顯示緩存將為構(gòu)建打開。
沒有它,#!COMMIT語法將被視為注釋,就像Docker守護程序的解析器一樣。這樣,用于Makisu顯式緩存的Dockerfile便與Docker守護程序保持兼容。 顯式提交可以為鏡像構(gòu)建提供更大的靈活性;創(chuàng)建的層數(shù)更少,通常會使得圖像更小,并改善了Dockerfile的可維護性。
結(jié)論
Makisu是一種非常強大的容器鏡像構(gòu)建工具,它是出于解決大型生產(chǎn)環(huán)境中存在的缺陷而產(chǎn)生的。它的方法消除了在容器構(gòu)建期間對提升特權(quán)的需求(盡管構(gòu)建是作為root用戶執(zhí)行的),并且它具有一種新穎的方法來構(gòu)建緩存實現(xiàn)。 它無法解決Dockerfile指令順序解析中固有的構(gòu)建效率低下的問題。而且,構(gòu)建執(zhí)行并不總是能忠實地反映Docker鏡像構(gòu)建的預(yù)期行為。但是,Makisu來自著名的工程師團隊,是新型容器鏡像構(gòu)建工具的又一個重要補充。
聲明:免責(zé)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻自行上傳,本網(wǎng)站不擁有所有權(quán),也不承認相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,請發(fā)
送郵件至:operations@xinnet.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,本站將立刻刪除涉嫌侵權(quán)內(nèi)容。本站原創(chuàng)內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時
需注明出處:新網(wǎng)idc知識百科