這篇文章將為大家詳細講解有關如何實現對容器鏡像的思考和討論,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
10多年的蕭山網站建設經驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。全網整合營銷推廣的優(yōu)勢是能夠根據用戶設備顯示端的尺寸不同,自動調整蕭山建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯公司從事“蕭山網站設計”,“蕭山網站推廣”以來,每個客戶項目都認真落實執(zhí)行。
常言道,startup 有 startup 的好,大廠有大廠的好,那么大廠究竟好在哪呢?拿硅谷老牌大廠們 FLG 來說,如果要問最令人懷念的是什么?Free food 和基礎設施(Infrastructure)一定是會上榜的,兩者均極大提升了廣大應用開發(fā)者的幸福指數。那么能不能“讓天下沒有難做的應用”呢?請大家把目光投向正在興起的云原生生態(tài)。
在云原生生態(tài)中,容器服務包括了鏡像和容器引擎兩個部分。其中容器鏡像作為核心的云原生應用制品,打包了完整的操作系統(tǒng)和應用運行環(huán)境,應用的迭代也因為使用了這種不可變架構而變得更簡單,更頻繁。
小編將圍繞著容器鏡像這一核心,分享它的相關知識和業(yè)界的思考與實踐。
容器鏡像有一個官方的類比,"生活中常見的集裝箱",雖然擁有不同的規(guī)格,但箱子本身是不可變的(Immutable),只是其中裝的內容不同。
對于鏡像來說,不變的部分包含了運行一個應用軟件(如 MySQL)所需要的所有元素。開發(fā)者可以使用一些工具(如 Dockerfile)構建出自己的容器鏡像,簽名并上傳到互聯網上,然后需要運行這些軟件的人可以通過指定名稱(如 example.com/my-app)下載、驗證和運行這些容器。
在 OCI 標準鏡像規(guī)范出臺之前,其實有兩套廣泛使用的鏡像規(guī)范,分別是 appc 和 docker v2.2,但“合久必分,分久必合”,有意思的是兩者的內容已經在各自的發(fā)展中逐步同化了,所以 OCI 組織順水推舟地在 docker v2.2 的基礎上推出了 oci image format spec,規(guī)定了對于符合規(guī)范的鏡像,允許開發(fā)者只要對容器打包和簽名一次,就可以在所有的容器引擎上運行該容器。
這份規(guī)范給出了 OCI image 的定義:
This specification defines an OCI Image, consisting of a manifest, an image index (optional), a set of filesystem layers, and a configuration.
一個典型的容器工作流程是從由 developers 制作容器鏡像開始的(build),然后上傳到鏡像存儲中心(ship),最后部署在集群中(run)。
不得不說,容器鏡像的設計是很出彩的,首先它蘊含了“完整的操作系統(tǒng)就是一個包”的優(yōu)秀思想,帶著大家跳出了安裝包的思路,又提出了諸如 dockerfile 這樣的提升開發(fā)者體驗的 killer features,還能利用分層結構來節(jié)約時間空間。
不過,"金無足赤,人無完人",優(yōu)秀的設計并不等于優(yōu)秀的實踐,下面來聊一聊問題具體出在哪。
容器啟動慢的情況普遍發(fā)生在當用戶啟動一個很大 size 的容器鏡像時,由于在容器準備階段需要三步(以 overlayfs 為例):
download 鏡像。
unpack 鏡像。
使用 overlayfs 將容器可寫層和鏡像中的只讀層聚合起來提供容器運行環(huán)境。
其中,download 鏡像時需要 download 整個鏡像,不能實現文件數據按需加載。再加上 download 鏡像本身受限于網絡帶寬的影響,當容器鏡像 size 在到幾個 G 時,下載時間會較長,破壞了容器原本優(yōu)秀的用戶體驗。
不同鏡像之間可以共享的最小單位是鏡像中的層,它的缺點之一是在 deduplication 上的效率是較低的,原因是:
首先,層內部存在重復的數據。
其次,層與層之間可能存在大量重復的數據,但即使有微小的差別,也會被作為不同的層。
再次,根據 OCI image spec 對刪除文件和 hardlink 的設計,一個鏡像內部可能存在已經被上層刪除的文件仍然存在于下層中,并包含在鏡像中。
所以,當不同鏡像的容器被調度到同一臺機器上運行時,鏡像本身在本地文件系統(tǒng)中所占的存儲空間是一筆不可忽視的成本開銷。
這里的提供者主要指容器服務的鏡像中心。
存在大量相似鏡像 造成這種情況有兩個原因:
首先,上面提到的層的缺點,在容器鏡像中心會產生許多相似鏡像。
其次,OCI image 使用了 tar+gzip 格式來表達鏡像中的層,而 tar 格式并不區(qū)分 tar archive entries ordering,這帶來一個問題,即如果用戶在不同機器上 build 去同一個鏡像,最終可能會因為使用了不同的文件系統(tǒng)而得到不同的鏡像,然后用戶上傳之后,鏡像中心中會存在若干不同鏡像的實質內容是完全相同的情況。
鏡像去重效率低:雖然鏡像中心有垃圾回收來實現去重功能,但其仍然以層為單位,所以只能在有完全相同 hash value 的層之間去重。
隨著時間推移,和軟件供應鏈一起發(fā)展的還有對軟件供應鏈環(huán)節(jié)的多樣性攻擊手段。安全防護是軟件供應鏈中非常重要的組成,不光體現在對軟件本身的安全增強,也體現在對供應鏈本身的安全增強。而因為應用運行環(huán)境被前置到了容器鏡像中,所以對容器鏡像的安全,包括對鏡像的漏洞掃描和簽名成為了容器服務提供者的必要能力。
針對前面所述的問題,業(yè)界大小廠也是集思廣益,各顯神通,下面提幾個典型的項目:
使用了 fuse 按需從遠程加載需要的數據。
通過設計一個鏡像的 benchmark 貢獻了幾個有意思的理論基礎:
事實上,容器啟動時間很長。
啟動時數據讀寫放大系數很大(啟動時中只使用 6% 的數據)。
分析了 57 個 docker image 的 layer 數量,發(fā)現一半以上的 image 的 layer 數量大于 9。
Slacker 最終使用了按需加載和減少鏡像層數將啟動速度提高了 5-20 倍。
Oracle 使用 Linux SquashFS 來替代 targz 存儲容器 image layer 的內容,去掉了 unpack tar 的環(huán)節(jié)。
自 2019 年開始,對于鏡像本身的吐槽慢慢多了起來,發(fā)酵了一年多,OCI 社區(qū)覺得時機成熟了,從 2020 年 6 月開始,花了一個多月時間密集討論了當前 OCI 鏡像規(guī)范的缺陷,以及 OCIv2 鏡像格式(*)需要滿足哪些要求。
(*)OCIv2 在這里只是一個宣傳命名,實際上 OCIv2 是當前 OCI 鏡像規(guī)范的改進,而不會是一個全新的鏡像規(guī)范。
經過討論得出目前的缺陷主要有兩點:
tar 格式標準
tar 格式并不區(qū)分 tar archive entries ordering,這帶來一個問題,即如果用戶在不同機器上去 build 同一個鏡像,最終可能會因為使用了不同的文件系統(tǒng)而得到不同的鏡像,比如在文件系統(tǒng) A 上的 order 是 foo 在 bar 之前進入 tar,在文件系統(tǒng) B 上的 order 是 bar 在 foo 之前進入 tar,那么這兩個鏡像是不同的。
當 tar 被 gzip 壓縮過之后不支持 seek,導致 run container 之前必須先下載并解壓 targz 的 image layers,而不能實現文件數據按需加載。
以層為鏡像的基本單位
內容冗余:不同層之間相同信息在傳輸和存儲時都是冗余內容,在不讀取內容的時候無法判斷到這些冗余的存在。
無法并行:單一層是一個整體,對同一個層既無法并行傳輸,也不能并行提取。
無法進行小塊數據的校驗,只有完整的層下載完成之后,才能對整個層的數據做完整性校驗。
其他一些問題:比如,跨層數據刪除難以完美處理。
這次鏡像格式大討論從一個郵件和一份共享文檔開始,并促成了多次在線的 OCI 社區(qū)討論會議。最后的結論也很鼓舞人心,在這份共享文檔中可以找到對 OCIv2 鏡像格式需要滿足的要求的詳細描述。我們可以將這些要求分類為:
(*): 諸如 file timestamp 等只在一個特定機器上有意義的 metadata 是沒有必要存在于鏡像中的。
可以看出,上面這些要求明確了容器鏡像的下一步重點在易用、效率、安全三個方面,達到在 "build - ship - run" 這三個階段協同優(yōu)化的目的。
阿里云一直積極地推動和發(fā)展云原生生態(tài),提供了基礎設施“阿里云容器鏡像服務(ACR)”作為用戶云原生容器化的第一站,負責提供容器鏡像、Helm Chart 等 OCI Artifacts 管理和分發(fā)服務。同時我們也在結合容器業(yè)務現狀深化對容器鏡像格式的理解,不斷地總結什么是滿足發(fā)展需求的容器鏡像格式,這里可以概括為以下幾點,新的鏡像格式需要:
滿足容器 "build once, run anywhere" 的理念。
實現在鏡像中心和容器運行結點上存儲資源上的高效使用。
在容器鏡像的全鏈路上(build, ship, run)比現有的 OCI 鏡像格式速度更快。
能夠擴展在安全上的能力。
最大程度兼容已有基礎設施,普惠大多數用戶。
相比于社區(qū)的討論重點放在了新的鏡像格式的設計上,阿里云更關心如何設計出一套優(yōu)化全鏈路的鏡像方案,為客戶帶來能夠應用在生產中的價值。
在明確以上在技術發(fā)展過程中產生的需求之后,我們?yōu)榘⒗镌粕诚淙萜髟O計了新的鏡像格式 Rafs,并為 CNCF 下的 Dragonfly 項目引入了容器鏡像服務,它能夠極大縮短鏡像下載時間,并提供端到端的鏡像數據一致性校驗,從而讓用戶能夠更安全快捷地管理容器應用。
Rafs 把一個容器鏡像只分成元數據和數據兩層。其中:
元數據層:元數據層是一顆自校驗的哈希樹。每個文件和目錄都是哈希樹中的一個附帶哈希值的節(jié)點。一個文件節(jié)點的哈希值是由文件的數據確定,一個目錄節(jié)點的哈希值則是由該目錄下所有文件和目錄的哈希值確定。
數據層:每個文件的數據被按照固定大小切片并保存到數據層中。數據切片可以在不同文件以及不同鏡像中的不同文件共享。
除了使用上面的鏡像格式 Rafs,Nydus 還包含一個負責解析容器鏡像的 FUSE 用戶態(tài)文件系統(tǒng)進程。
nydus 能夠解析 FUSE 或者 virtiofs 協議來支持傳統(tǒng)的 runC 容器或者阿里云沙箱容器。容器倉庫、OSS 對象存儲、NAS、以及 Dragonfly 的超級節(jié)點和 peer 節(jié)點都可以作為 nydus 的鏡像數據源。同時,nydus 還可以配置一個本地緩存,從而避免每次啟動都從遠端數據源拉取數據。
基于這個設計架構,nydus 分別在 build, ship, run 和兼容性方面提供下面這些優(yōu)化:
在設計之初,Nydus 選擇了基于文件的設計而不是基于塊的設計,為什么這樣做呢?
主要的原因是,我們想在鏡像加速的基礎上做基于容器特點的附加能力,這一切都建立在能夠獲取到鏡像中的文件元數據;而基于塊的設計只使用 disk LBA,天然的無法獲取其上層(即文件系統(tǒng))中的信息。
有了文件元數據之后,我們輕松地實現了以下幾個增值功能:
鏡像優(yōu)化建議:在 build container 環(huán)節(jié),提示用戶有哪些文件是根本沒有訪問過的,可以考慮借此來優(yōu)化鏡像。
預讀:在 run container 環(huán)節(jié)預加載,猜到用戶要讀文件,那就預先在讀操作發(fā)生之前送過去,從而優(yōu)化訪問速度。
安全審計:在 run container 環(huán)節(jié),如果一個容器訪問鏡像內容的模式和其他容器產生了明顯差異,那么,這有可能是一個安全性風險。
變更風險發(fā)現:在 run container 環(huán)節(jié),如果一個鏡像升級之后,發(fā)現它訪問內容的模式和之前發(fā)生了明顯差異,那么,要么是程序自己有意變了,要么就可能是引入 bug 了,這時可以考慮提醒開發(fā)者這個變化。
關于如何實現對容器鏡像的思考和討論就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
網頁標題:如何實現對容器鏡像的思考和討論
文章位置:http://jinyejixie.com/article12/gdppgc.html
成都網站建設公司_創(chuàng)新互聯,為您提供網站維護、虛擬主機、小程序開發(fā)、品牌網站建設、搜索引擎優(yōu)化、外貿網站建設
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯