開發與維運

阿里巴巴開源容器鏡像加速技術

近日阿里巴巴開源了其雲原生容器鏡像加速技術Accelerated Container Image[1],其推出的overlaybd鏡像格式,相比於傳統的分層tar包文件格式,實現了基於網絡的按需讀取,從而使得容器可以快速啟動。

該技術方案原本是阿里雲內部DADI項目的一部分, DADI是Data Accelerator for Disaggregated Infrastructure的縮寫,旨在為計算存儲分離架構提供各種可能的數據訪問加速技術。鏡像加速是DADI架構在容器及雲原生領域的一次突破性嘗試,該技術自2019年投產以來,已在線上部署了大量機器,累計啟動容器次數超過10億,支持了阿里巴巴集團及阿里雲的多個業務線,極大提高了應用的發佈和擴容效率。2020年,團隊在國際頂級會議發表了論文 "DADI: Block-Level Image Service for Agile and Elastic Application Deployment. USENIX ATC'20"[2],並隨後啟動了開源項目,計劃將技術該貢獻給社區,通過建立標準並打造生態,吸引更多的開發者投入到容器及雲原生性能優化這個領域上來。

背景簡介

隨著Kubernetes和雲原生的大爆發,容器在企業內部的大規模應用已經越來越廣泛。部署啟動快是容器的核心優勢之一,這個啟動快是指本地鏡像實例化的時間非常短,即“熱啟動”時間短。然而對於“冷啟動”,即在本地無鏡像的情況下,需要先從Registry下載鏡像才能創建容器。業務的鏡像經過長期維護和更新,無論是鏡像層數還是整體大小都會達到一個較大的量級,比如可能達到數百MB或者幾個GB。因此生產環境中,容器的冷啟動往往耗時數分鐘,並且隨規模擴大會導致Registry因集群內網絡擁堵而無法快速地下載鏡像。

例如,在之前某年的雙十一活動中,阿里內部一個應用因為容量不足觸發緊急擴容,但因併發量過大,整體擴容耗時較長,這期間對部分用戶的使用體驗造成了影響。而到了2019年,隨著DADI的部署上線,新鏡像格式的容器在“鏡像拉取+容器啟動”上耗費的總時間比普通容器縮短了5倍,且p99長尾時間更是比後者快了17倍。

如何處理存儲在遠端的鏡像數據,這是解決容器冷啟動慢這個問題的核心點。歷史上業界對這一問題做出的嘗試有:使用塊存儲或者NAS保存容器鏡像,實現按需讀取;使用基於網絡的分發技術(如p2p),將鏡像從多個源頭下載、或者提前預熱到主機上,避免出現網絡單點瓶頸。近年來,針對新鏡像格式的討論也逐漸被提上議題,根據Harter等人的研究[3]表明,拉取鏡像佔用了容器啟動時間的76%,而只有6.4%的時間用來讀取數據。因此,支持On-demand Read技術的鏡像,已經成為默認的潮流風向。Google提出的stargz[4]格式,其全稱是Seekable tar.gz,顧名思義,可以有選擇地從存檔中搜尋並提取特定的文件,無需掃描或者解壓整個鏡像。stargz旨在提高鏡像拉取的性能,其延遲拉取技術(lazy-pull)不會拉取整個鏡像文件,實現了按需讀取。為了進一步提高運行時效率,stargz又推出了一個containerd的snapshotter插件,在存儲層面對I/O做了進一步優化。

在容器的生命週期中,鏡像就緒後需要掛載(mount),而分層鏡像掛載的核心技術便是overlayfs,它以一種堆疊的形式將下層的多個layer文件合併,並向上暴露出一個統一的只讀文件系統。類比上文提到的塊存儲和NAS,一般可以通過快照的形式進行分層堆疊,而跟stargz綁定的CRFS,也可以看做是overlayfs的另一種實現。

新鏡像格式

DADI沒有直接使用overlayfs,或者說,它只是借鑑了overlayfs和早期聯合文件系統(union filesystem)的思想,但提出了一種全新的基於塊設備的分層堆疊技術,稱之為overlaybd,它為容器鏡像提供了一系列基於塊的合併數據視圖。overlaybd的實現十分簡單,因此很多之前想做而不能做的事都可以成為現實;而實現一個完全POSIX兼容的文件系統接口則充滿挑戰,並可能存在bug,這點從各個主流文件系統的發展歷史上就可以看出。

除了簡單以外,overlaybd對比overlayfs的其他優點有:

  • 避免多層鏡像導致的性能下降,如overlayfs模式下大文件的更新會觸發跨層引用複製,系統必須先將文件複製到可寫層;或者創建硬鏈接速度很慢等問題
  • 可以方便地採集block級別的I/O模式,進行錄製以及重放,從而預取數據,進一步加速啟動
  • 用戶的文件系統和宿主機OS可以靈活選擇,如支持Windows NTFS
  • 可以使用有效的編解碼器進行在線解壓縮
  • 可以下沉到雲中的分佈式存儲(如EBS)中,鏡像系統盤可以跟數據盤使用同一套存儲方案
  • overlaybd具有天然的可寫層支持(RW),只讀掛載甚至可以成為歷史

overlaybd原理

為了理解overlaybd的原理,首先需要了解容器鏡像的分層機制。容器鏡像由多個增量layer文件組成,在使用時進行疊加,這樣在鏡像分發時只需要對layer文件進行分發。每一層實質上都是與上一層的差異(包括文件的添加,修改或刪除)的壓縮包。容器引擎可以通過其storage driver,按照約定的方式將差異疊加起來,然後以Read-Only的模式掛載到指定目錄,該目錄即稱為lower_dir;而以Read/Write模式掛載的可寫層,掛載目錄則一般稱為upper_dir。

請注意,overlaybd本身沒有文件的概念,它只是將鏡像抽象為虛擬塊設備,並在其上裝載常規的文件系統。當用戶應用讀取數據時,該讀取請求首先由常規的文件系統處理,將請求轉換為虛擬塊設備的一次或多次讀取。這些讀取請求會被轉發到用戶態的接收程序,即overlaybd的運行時載體,最後轉換為對一個或多個layer的隨機讀取。

與傳統鏡像一樣,overlaybd在內部仍然保留著layer分層的結構,但每層的內容都是文件系統變更差異對應的一系列data block。overlaybd向上提供了一個合併視圖,對layer的疊加規則很簡單,即對於任意一個data block,總是使用最後的變更,在layer中未發生變更的塊均視為全零塊;向下又提供了將一系列data block導出成一個layer文件的功能,該文件高密度非稀疏、且可索引。因此,對塊設備某個連續LBA範圍進行讀操作,可能包含了原本屬於多層的小塊數據段,我們將這些小塊數據段稱為segment。從segment的屬性中找到層號,便能夠繼續映射到對這層的layer文件的讀取上來。傳統的容器鏡像可以將它的layer文件保存在Registry或者對象存儲上,那麼overlaybd鏡像自然也可以。

image

為了更好的兼容性,overlaybd在layer文件的最外層,包裝了一層tar文件的頭和尾,這樣偽裝成一個tar文件。由於 tar內部僅一個文件,不影響按需讀取。目前無論是docker、containerd或者buildkit,對鏡像的下載或上傳默認都有untar和tar的流程,不侵入代碼是無法逾越的,所以增加tar偽裝有利於兼容性和流程的統一,例如在鏡像轉換、構建、或者全量下載使用時,都無需修改代碼,只需提供插件即可。

整體架構

image

DADI整體架構如圖,以下分別介紹各個組件

containerd snapshotter

containerd自1.4版起,開始初步支持一些啟動遠程鏡像的功能,並且k8s已經明確將放棄Docker作為運行時的支持。所以DADI開源版本選擇優先支持containerd生態,之後再支持Docker。

snapshotter的核心功能是實現抽象的服務接口,用於容器rootfs的掛載和卸載等操作。它的設計替代了在Docker 早期版本稱之為graphdriver的模塊,使得存儲驅動更加簡化,同時兼容了塊設備快照與overlayfs。

DADI提供的overlaybd-snapshotter一方面能讓容器引擎支持新的overlaybd格式的鏡像,即將虛擬塊設備掛載到對應的目錄,另一方面也兼容傳統OCI tar格式鏡像,讓用戶繼續以overlayfs運行普通容器。

iSCSI target

iSCSI是一種被廣泛支持的遠程塊設備協議,穩定成熟性能高,遇到故障可恢復。overlaybd模塊作為iSCSI協議的後端存儲,即使程序意外crash,重新拉起即可恢復。而基於文件系統的鏡像加速方案,例如stargz,則無法恢復。

iSCSI target是overlaybd的運行時載體。在本項目中,我們實現了兩種target模塊:第一種是基於開源項目tgt[5],由於其擁有backing store機制,可以將代碼編譯成動態鏈接庫以便運行時加載;第二種是基於Linux內核的LIO SCSI target(又稱為TCMU)[6],整個target運行在內核態,可以比較方便地輸出虛擬塊設備。

ZFile

ZFile是我們提供的一種支持在線解壓的數據壓縮格式。它將源文件按固定大小的block size切分,各數據塊進行單獨壓縮,同時維護一個jump table,記錄了各數據塊在ZFile中的物理偏移位置。如需從ZFile中讀數據,只要查找索引找到對應位置,並僅解壓縮相關的data block即可。

ZFile支持各種有效的壓縮算法,包括lz4,zstd等,它解壓速度極快,開銷低,可以有效節省存儲空間和數據傳輸量。實驗數據表明,按需解壓遠程的ZFile數據,性能高於加載非壓縮數據,這是因為傳輸節省的時間,大於解壓的額外開銷。

overlaybd支持將layer文件導出成ZFile格式。

cache

正如上文所說,layer文件保存在Registry上,容器對塊設備的讀I/O會映射到對Registry的請求上(這裡利用到了Registry對HTTP Partial Content的支持)。但是由於cache機制的存在,這種情形不會一直存在。cache會在容器啟動後的一段時間後自動開始下載layer文件,並持久化到本地文件系統。如果cache命中,則讀I/O就不會再發給Registry,而是讀本地。

行業領先

3月25日,權威諮詢機構Forrester發佈2021年第一季度FaaS平臺(Function-As-A-Service Platforms)評估報告,阿里雲憑藉產品能力全球第一的優勢脫穎而出,在八個評測維度中拿到最高分,成為比肩亞馬遜AWS的全球FaaS領導者。這也是首次有國內科技公司進入FaaS領導者象限。

眾所周知,容器是FaaS平臺的承載基礎,而容器啟動速度更是決定了整個平臺的性能與響應延遲。DADI助力阿里雲函數計算產品,大幅度縮短容器啟動時間50%~80%[7],帶來了全新的Serverless使用體驗。

總結展望

阿里巴巴開源的DADI容器加速項目以及其推出的overlaybd鏡像格式,有助於應對新時代下容器對快速啟動的需求。項目組未來將協同社區一起,加快對接主流工具鏈,積極參與新鏡像格式標準制定,目標是讓overlaybd成為OCI遠程鏡像格式的標準之一。

歡迎大家參與開源項目,一起貢獻力量!

後續工作

Artfacts Manifest

OCI Image的v1 Manifest格式描述能力有限,無法滿足遠程鏡像需求。目前v2的討論沒有實質進展,推翻v1也不現實。但是,可以藉助OCI Artfacts Manifest使用Additional Descriptor來描述原始數據,兼容性上有所保證,用戶更容易接受。Artfacts也是OCI/CNCF在推廣的項目,DADI未來計劃擁抱Artfacts並實現PoC。

開放對多種文件系統的支持

DADI本身支持用戶根據需要選擇合適的文件系統來構建鏡像,但是目前尚未開放相應的接口,默認使用了ext4文件系統。我們未來將完善相關接口並放開此功能,由用戶根據自身需要,決定使用什麼文件系統。

Buildkit工具鏈

目前用戶可以通過buildkit外掛snapshotter來構建鏡像,未來將進一步完善,形成完整工具鏈。

數據預取

在容器啟動後對I/O模式進行記錄,後續啟動同一鏡像時便可以重放該記錄,對數據進行預取,避免臨時請求Registry,這樣容器的冷啟動時間將繼續縮短一半以上。理論上所有無狀態或冪等容器都可以進行錄製和重放。

參考文獻

[1] https://github.com/alibaba/accelerated-container-image

[2] https://www.usenix.org/conference/atc20/presentation/li-huiba

[3] https://www.usenix.org/conference/fast16/technical-sessions/presentation/harter

[4] https://github.com/containerd/stargz-snapshotter

[5] http://stgt.sourceforge.net/

[6] http://linux-iscsi.org

[7] https://developer.aliyun.com/article/781992

Leave a Reply

Your email address will not be published. Required fields are marked *