作者 | 陳博
近日阿里巴巴開源了其云原生容器鏡像加速技術(shù),它推出的 overlaybd 鏡像格式,相比于傳統(tǒng)的分層 tar 包文件格式,實現(xiàn)了基于網(wǎng)絡(luò)的按需讀取,從而使得容器可以快速啟動。
該技術(shù)方案原本是阿里云內(nèi)部 DADI 項目的一部分, DADI 是 Data Accelerator for Disaggregated Infrastructure 的縮寫,旨在為計算存儲分離架構(gòu)提供各種可能的數(shù)據(jù)訪問加速技術(shù)。鏡像加速是 DADI 架構(gòu)在容器及云原生領(lǐng)域的一次突破性嘗試,該技術(shù)自 2019 年投產(chǎn)以來,已在線上部署了大量機(jī)器,累計啟動容器次數(shù)超過 10 億,支持了阿里巴巴集團(tuán)及阿里云的多個業(yè)務(wù)線,極大提高了應(yīng)用的發(fā)布和擴(kuò)容效率。2020 年,團(tuán)隊在國際頂級會議發(fā)表了論文 "DADI: Block-Level Image Service for Agile and Elastic Application Deployment. USENIX ATC'20"[1],并隨后啟動了開源項目,計劃將技術(shù)該貢獻(xiàn)給社區(qū),通過建立標(biāo)準(zhǔn)并打造生態(tài),吸引更多的開發(fā)者投入到容器及云原生性能優(yōu)化這個領(lǐng)域上來。
背景簡介
隨著 Kubernetes 和云原生的大爆發(fā),容器在企業(yè)內(nèi)部的大規(guī)模應(yīng)用已經(jīng)越來越廣泛。部署啟動快是容器的核心優(yōu)勢之一,這個啟動快是指本地鏡像實例化的時間非常短,即“熱啟動”時間短。然而對于“冷啟動”,即在本地?zé)o鏡像的情況下,需要先從 Registry 下載鏡像才能創(chuàng)建容器。業(yè)務(wù)的鏡像經(jīng)過長期維護(hù)和更新,無論是鏡像層數(shù)還是整體大小都會達(dá)到一個較大的量級,比如可能達(dá)到數(shù)百 MB 或者幾個 GB。因此生產(chǎn)環(huán)境中,容器的冷啟動往往耗時數(shù)分鐘,并且隨規(guī)模擴(kuò)大會導(dǎo)致 Registry 因集群內(nèi)網(wǎng)絡(luò)擁堵而無法快速地下載鏡像。
例如,在之前某年的雙十一活動中,阿里內(nèi)部一個應(yīng)用因為容量不足觸發(fā)緊急擴(kuò)容,但因并發(fā)量過大,整體擴(kuò)容耗時較長,這期間對部分用戶的使用體驗造成了影響。而到了 2019 年,隨著 DADI 的部署上線,新鏡像格式的容器在“鏡像拉取+容器啟動”上耗費(fèi)的總時間比普通容器縮短了 5 倍,且 p99 長尾時間更是比后者快了 17 倍。
如何處理存儲在遠(yuǎn)端的鏡像數(shù)據(jù),這是解決容器冷啟動慢這個問題的核心點(diǎn)。歷史上業(yè)界對這一問題做出的嘗試有:使用塊存儲或者NAS保存容器鏡像,實現(xiàn)按需讀??;使用基于網(wǎng)絡(luò)的分發(fā)技術(shù)(如 p2p),將鏡像從多個源頭下載、或者提前預(yù)熱到主機(jī)上,避免出現(xiàn)網(wǎng)絡(luò)單點(diǎn)瓶頸。近年來,針對新鏡像格式的討論也逐漸被提上議題,根據(jù) Harter 等人的研究表明,拉取鏡像占用了容器啟動時間的 76%,而只有 6.4% 的時間用來讀取數(shù)據(jù)。因此,支持 On-demand Read 技術(shù)的鏡像,已經(jīng)成為默認(rèn)的潮流風(fēng)向。Google 提出的stargz 格式,其全稱是 Seekable tar.gz,顧名思義,可以有選擇地從存檔中搜尋并提取特定的文件,無需掃描或者解壓整個鏡像。stargz 旨在提高鏡像拉取的性能,其延遲拉取技術(shù)(lazy-pull)不會拉取整個鏡像文件,實現(xiàn)了按需讀取。為了進(jìn)一步提高運(yùn)行時效率,stargz 又推出了一個 containerd 的 snapshotter 插件,在存儲層面對 I/O 做了進(jìn)一步優(yōu)化。
在容器的生命周期中,鏡像就緒后需要掛載(mount),而分層鏡像掛載的核心技術(shù)便是 overlayfs,它以一種堆疊的形式將下層的多個 layer 文件合并,并向上暴露出一個統(tǒng)一的只讀文件系統(tǒng)。類比上文提到的塊存儲和 NAS,一般可以通過快照的形式進(jìn)行分層堆疊,而跟 stargz 綁定的 CRFS,也可以看做是 overlayfs 的另一種實現(xiàn)。
新鏡像格式
DADI 沒有直接使用 overlayfs,或者說,它只是借鑒了 overlayfs 和早期聯(lián)合文件系統(tǒng)(union filesystem)的思想,但提出了一種全新的基于塊設(shè)備的分層堆疊技術(shù),稱之為 overlaybd,它為容器鏡像提供了一系列基于塊的合并數(shù)據(jù)視圖。overlaybd 的實現(xiàn)十分簡單,因此很多之前想做而不能做的事都可以成為現(xiàn)實;而實現(xiàn)一個完全 POSIX 兼容的文件系統(tǒng)接口則充滿挑戰(zhàn),并可能存在 bug,這點(diǎn)從各個主流文件系統(tǒng)的發(fā)展歷史上就可以看出。
除了簡單以外,overlaybd 對比 overlayfs 的其他優(yōu)點(diǎn)有:
避免多層鏡像導(dǎo)致的性能下降,如 overlayfs 模式下大文件的更新會觸發(fā)跨層引用復(fù)制,系統(tǒng)必須先將文件復(fù)制到可寫層;或者創(chuàng)建硬鏈接速度很慢等問題。
可以方便地采集 block 級別的 I/O 模式,進(jìn)行錄制以及重放,從而預(yù)取數(shù)據(jù),進(jìn)一步加速啟動。
用戶的文件系統(tǒng)和宿主機(jī) OS 可以靈活選擇,如支持 Windows NTFS。
可以使用有效的編解碼器進(jìn)行在線解壓縮。
可以下沉到云中的分布式存儲(如 EBS)中,鏡像系統(tǒng)盤可以跟數(shù)據(jù)盤使用同一套存儲方案。
overlaybd 具有天然的可寫層支持(RW),只讀掛載甚至可以成為歷史。
overlaybd 原理
為了理解 overlaybd 的原理,首先需要了解容器鏡像的分層機(jī)制。容器鏡像由多個增量 layer 文件組成,在使用時進(jìn)行疊加,這樣在鏡像分發(fā)時只需要對 layer 文件進(jìn)行分發(fā)。每一層實質(zhì)上都是與上一層的差異(包括文件的添加,修改或刪除)的壓縮包。容器引擎可以通過其 storage driver,按照約定的方式將差異疊加起來,然后以 Read-Only 的模式掛載到指定目錄,該目錄即稱為 lower_dir;而以 Read/Write 模式掛載的可寫層,掛載目錄則一般稱為 upper_dir。
請注意,overlaybd 本身沒有文件的概念,它只是將鏡像抽象為虛擬塊設(shè)備,并在其上裝載常規(guī)的文件系統(tǒng)。當(dāng)用戶應(yīng)用讀取數(shù)據(jù)時,該讀取請求首先由常規(guī)的文件系統(tǒng)處理,將請求轉(zhuǎn)換為虛擬塊設(shè)備的一次或多次讀取。這些讀取請求會被轉(zhuǎn)發(fā)到用戶態(tài)的接收程序,即 overlaybd 的運(yùn)行時載體,最后轉(zhuǎn)換為對一個或多個 layer 的隨機(jī)讀取。
與傳統(tǒng)鏡像一樣,overlaybd 在內(nèi)部仍然保留著 layer 分層的結(jié)構(gòu),但每層的內(nèi)容都是文件系統(tǒng)變更差異對應(yīng)的一系列 data block。overlaybd 向上提供了一個合并視圖,對 layer 的疊加規(guī)則很簡單,即對于任意一個 data block,總是使用最后的變更,在 layer 中未發(fā)生變更的塊均視為全零塊;向下又提供了將一系列 data block 導(dǎo)出成一個 layer 文件的功能,該文件高密度非稀疏、且可索引。因此,對塊設(shè)備某個連續(xù) LBA 范圍進(jìn)行讀操作,可能包含了原本屬于多層的小塊數(shù)據(jù)段,我們將這些小塊數(shù)據(jù)段稱為 segment。從 segment 的屬性中找到層號,便能夠繼續(xù)映射到對這層的 layer 文件的讀取上來。傳統(tǒng)的容器鏡像可以將它的 layer 文件保存在 Registry 或者對象存儲上,那么 overlaybd 鏡像自然也可以。
為了更好的兼容性,overlaybd 在 layer 文件的最外層,包裝了一層 tar 文件的頭和尾,這樣偽裝成一個 tar 文件。由于 tar 內(nèi)部僅一個文件,不影響按需讀取。目前無論是 docker、containerd 或者 buildkit,對鏡像的下載或上傳默認(rèn)都有 untar 和 tar 的流程,不侵入代碼是無法逾越的,所以增加 tar 偽裝有利于兼容性和流程的統(tǒng)一,例如在鏡像轉(zhuǎn)換、構(gòu)建、或者全量下載使用時,都無需修改代碼,只需提供插件即可。
整體架構(gòu)
DADI 整體架構(gòu)如圖,以下分別介紹各個組件:
1. containerd snapshotter
containerd 自 1.4 版起,開始初步支持一些啟動遠(yuǎn)程鏡像的功能,并且 K8s 已經(jīng)明確將放棄 Docker 作為運(yùn)行時的支持。所以 DADI 開源版本選擇優(yōu)先支持 containerd 生態(tài),之后再支持 Docker。
snapshotter 的核心功能是實現(xiàn)抽象的服務(wù)接口,用于容器 rootfs 的掛載和卸載等操作。它的設(shè)計替代了在 Docker 早期版本稱之為 graphdriver 的模塊,使得存儲驅(qū)動更加簡化,同時兼容了塊設(shè)備快照與 overlayfs。
DADI 提供的 overlaybd-snapshotter 一方面能讓容器引擎支持新的 overlaybd 格式的鏡像,即將虛擬塊設(shè)備掛載到對應(yīng)的目錄,另一方面也兼容傳統(tǒng) OCI tar 格式鏡像,讓用戶繼續(xù)以 overlayfs 運(yùn)行普通容器。
2. iSCSI target
iSCSI 是一種被廣泛支持的遠(yuǎn)程塊設(shè)備協(xié)議,穩(wěn)定成熟性能高,遇到故障可恢復(fù)。overlaybd 模塊作為 iSCSI 協(xié)議的后端存儲,即使程序意外 crash,重新拉起即可恢復(fù)。而基于文件系統(tǒng)的鏡像加速方案,例如 stargz,則無法恢復(fù)。
iSCSI target 是 overlaybd 的運(yùn)行時載體。在本項目中,我們實現(xiàn)了兩種 target 模塊:第一種是基于開源項目tgt,由于其擁有 backing store 機(jī)制,可以將代碼編譯成動態(tài)鏈接庫以便運(yùn)行時加載;第二種是基于 Linux 內(nèi)核的LIO SCSI target(又稱為 TCMU),整個 target 運(yùn)行在內(nèi)核態(tài),可以比較方便地輸出虛擬塊設(shè)備。
3. ZFile
ZFile 是我們提供的一種支持在線解壓的數(shù)據(jù)壓縮格式。它將源文件按固定大小的 block size 切分,各數(shù)據(jù)塊進(jìn)行單獨(dú)壓縮,同時維護(hù)一個 jump table,記錄了各數(shù)據(jù)塊在 ZFile 中的物理偏移位置。如需從 ZFile 中讀數(shù)據(jù),只要查找索引找到對應(yīng)位置,并僅解壓縮相關(guān)的 data block 即可。
ZFile 支持各種有效的壓縮算法,包括 lz4,zstd 等,它解壓速度極快,開銷低,可以有效節(jié)省存儲空間和數(shù)據(jù)傳輸量。實驗數(shù)據(jù)表明,按需解壓遠(yuǎn)程的 ZFile 數(shù)據(jù),性能高于加載非壓縮數(shù)據(jù),這是因為傳輸節(jié)省的時間,大于解壓的額外開銷。
overlaybd 支持將 layer 文件導(dǎo)出成 ZFile 格式。
4. cache
正如上文所說,layer 文件保存在 Registry 上,容器對塊設(shè)備的讀 I/O 會映射到對 Registry 的請求上(這里利用到了 Registry 對 HTTP Partial Content 的支持)。但是由于 cache 機(jī)制的存在,這種情形不會一直存在。cache 會在容器啟動后的一段時間后自動開始下載 layer 文件,并持久化到本地文件系統(tǒng)。如果 cache 命中,則讀 I/O 就不會再發(fā)給 Registry,而是讀本地。
行業(yè)領(lǐng)先
3 月 25 日,權(quán)威咨詢機(jī)構(gòu) Forrester 發(fā)布 2021 年第一季度 FaaS 平臺(Function-As-A-Service Platforms)評估報告,阿里云憑借產(chǎn)品能力全球第一的優(yōu)勢脫穎而出,在八個評測維度中拿到最高分,成為比肩亞馬遜 AWS 的全球 FaaS 領(lǐng)導(dǎo)者。這也是首次有國內(nèi)科技公司進(jìn)入 FaaS 領(lǐng)導(dǎo)者象限。
眾所周知,容器是 FaaS 平臺的承載基礎(chǔ),而容器啟動速度更是決定了整個平臺的性能與響應(yīng)延遲。DADI 助力阿里云函數(shù)計算產(chǎn)品,大幅度縮短容器啟動時間 50%~80%,帶來了全新的 Serverless 使用體驗。
總結(jié)展望
阿里巴巴開源的 DADI 容器加速項目以及其推出的 overlaybd 鏡像格式,有助于應(yīng)對新時代下容器對快速啟動的需求。項目組未來將協(xié)同社區(qū)一起,加快對接主流工具鏈,積極參與新鏡像格式標(biāo)準(zhǔn)制定,目標(biāo)是讓 overlaybd 成為 OCI 遠(yuǎn)程鏡像格式的標(biāo)準(zhǔn)之一。
后續(xù)工作
1.Artfacts Manifest
OCI Image 的 v1 Manifest 格式描述能力有限,無法滿足遠(yuǎn)程鏡像需求。目前 v2 的討論沒有實質(zhì)進(jìn)展,推翻 v1 也不現(xiàn)實。但是,可以借助 OCI Artfacts Manifest 使用 Additional Descriptor 來描述原始數(shù)據(jù),兼容性上有所保證,用戶更容易接受。Artfacts 也是 OCI/CNCF 在推廣的項目,DADI 未來計劃擁抱 Artfacts 并實現(xiàn) PoC。
2. 開放對多種文件系統(tǒng)的支持
DADI 本身支持用戶根據(jù)需要選擇合適的文件系統(tǒng)來構(gòu)建鏡像,但是目前尚未開放相應(yīng)的接口,默認(rèn)使用了 ext4 文件系統(tǒng)。我們未來將完善相關(guān)接口并放開此功能,由用戶根據(jù)自身需要,決定使用什么文件系統(tǒng)。
3. Buildkit 工具鏈
目前用戶可以通過 buildkit 外掛 snapshotter 來構(gòu)建鏡像,未來將進(jìn)一步完善,形成完整工具鏈。
4. 數(shù)據(jù)領(lǐng)取
在容器啟動后對 I/O 模式進(jìn)行記錄,后續(xù)啟動同一鏡像時便可以重放該記錄,對數(shù)據(jù)進(jìn)行預(yù)取,避免臨時請求 Registry,這樣容器的冷啟動時間將繼續(xù)縮短一半以上。理論上所有無狀態(tài)或冪等容器都可以進(jìn)行錄制和重放。