1. 軟件運行過程中的資源和環(huán)境的隔離。
2. 軟件因為運行環(huán)境多樣帶來的打包和配置的復(fù)雜性。
而對于軟件運行環(huán)境的隔離需求,從計算機出現(xiàn)之初就已經(jīng)開始了,多任務(wù)分時操作系統(tǒng)和虛擬地址的引入,都是為了解決多個任務(wù)在同一主機上運行,并且讓任務(wù)本身認為自己獨占機器。當然這樣的隔離是遠遠不夠的,當今軟件,根據(jù)不同的層級,可以將隔離技術(shù)分為以下三類:
1. 進程級別的隔離
2. 操作系統(tǒng)級別的隔離
3. 虛擬化級別的隔離
操作系統(tǒng)以進程作為程序運行過程的抽象,進程擁有獨立的地址空間,進程的執(zhí)行依靠操作系統(tǒng)的調(diào)度。但是進程共享了文件系統(tǒng),函數(shù)庫等資源,程序之間出現(xiàn)互相干擾的可能性很大。這個層級的隔離適合在相同主機上運行單個用戶的不同程序,由用戶自己保證程序之間的資源分配。
上世紀70年代出現(xiàn)了chroot,進行文件系統(tǒng)的隔離,21世紀初開始,隨著計算硬件的性能提升,軟件隔離的需求更加強烈,這時候開始出現(xiàn)如jail,cgroup,namespace等各種不同資源的隔離技術(shù)。我們將這些技術(shù)統(tǒng)一劃分到操作系統(tǒng)的隔離技術(shù),這類隔離技術(shù)可以實現(xiàn)軟件在諸如硬件資源、文件系統(tǒng)、網(wǎng)絡(luò)、進程號等方面的隔離,但是不同的應(yīng)用依然是運行在相同的操作系統(tǒng)內(nèi)核上,對于惡意的利用漏洞攻擊的場景,這種隔離技術(shù)依然會捉襟見肘。但是這種級別的隔離帶來的額外資源消耗較小,適合相同的組織內(nèi)不同用戶的應(yīng)用在相同主機上運行。
虛擬化技術(shù)的出現(xiàn),讓相同的物理機上也能運行多個不同的操作系統(tǒng)。操作系統(tǒng)對硬件的接口,由虛擬機管理程序(VMM)負責模擬。運行在不同系統(tǒng)中的程序,內(nèi)核也是隔離的。硬件資源則通過各種硬件輔助手段進行劃分,虛擬機上的程序很難突破虛擬化層加上的資源限制。并且因為內(nèi)核的隔離,資源的可見性也做到了很強的隔離性。即使是惡意的用戶,也很難突破這層虛擬化的限制,已達到攻擊物理機,或者相同主機上其他虛擬機的目的。
以上三種隔離是按照層級一步一步加強的,同時帶來的理論損耗也是逐步遞進的。虛擬化由于需要模擬各種設(shè)備,帶來的資源損耗比其他兩種隔離方式要大很多。
什么是“安全容器”
容器概念出來的時候,最初大家做隔離的思路,幾乎都是操作系統(tǒng)級的隔離,也就是基于內(nèi)核提供的namespace、cgroup、seccomp等機制,實現(xiàn)容器內(nèi)的資源、文件、系統(tǒng)調(diào)用等限制和隔離。這種隔離方式更加高效,損耗更小。但是隨著容器的大規(guī)模使用,尤其是各種容器編排系統(tǒng),如k8s的深入使用,人們逐漸發(fā)現(xiàn)這樣的隔離級別往往不能滿足要求。在公有云場景下,相同主機如果需要運行不同租戶的應(yīng)用,因為這種隔離級別依然采用了共內(nèi)核的機制,存在這廣泛的攻擊面,容器的隔離級別完全不能滿足要求。所以最初的公有云上的容器服務(wù),都是配合虛擬機的使用來完成的,首先是用戶需要創(chuàng)建一批虛擬機作為運行容器的節(jié)點,形成一個私有的集群,然后才能在其上創(chuàng)建容器應(yīng)用。虛擬化級別的隔離已經(jīng)被各種公有云的實踐證明,是一種安全的隔離技術(shù)。
自從云計算的概念提出開始,虛擬機一直是云平臺的基礎(chǔ),無論是平臺本身服務(wù)還是用戶的使用,都是從IaaS平臺創(chuàng)建通用虛擬機開始的。一般都是創(chuàng)建相應(yīng)的規(guī)格的虛擬機,使用一個完成操作系統(tǒng)鏡像啟動一個完整的操作系統(tǒng),隨后在其安裝,配置,運行軟件和服務(wù)。包括我們上節(jié)提到的公有云容器服務(wù)的提供形式也是如此。
虛擬化本身帶來的隔離能力是受到普遍認可的,不過IaaS層希望提供的是一個和應(yīng)用完全無關(guān)的基礎(chǔ)設(shè)施層,它幾乎完全不感知應(yīng)用的任何信息。于是從基礎(chǔ)設(shè)施到應(yīng)用運維,中間巨大的鴻溝則是由PaaS和用戶自己來填平,這中間依然需要耗費無數(shù)的人力和成本。通用的虛擬機服務(wù)誠然有它的好處,比如完整的操作系統(tǒng)很適合程序調(diào)試,或者作為工作辦公環(huán)境等等。但是對于多數(shù)運行于云平臺的軟件,它需要的是它獨有的運行環(huán)境,它的運行環(huán)境由它的鏡像已經(jīng)完全定義好了。如果在此之外,又啟動一個完整的操作系統(tǒng),既浪費資源,也增加了運維的成本。為什么不能直接將虛擬化級別的隔離引入到容器技術(shù)中呢?結(jié)合虛擬化的安全性和容器在軟件生命周期管理方面的優(yōu)勢,是不是可以給軟件開發(fā)運維帶來巨大的便利呢?
也就是在這個時間,docker和coreos等一起成立了OCI組織,其目的是將容器的運行時和鏡像管理等流程標準化。OCI標準定義了一套容器運行時的命令行接口和文件規(guī)范,docker將其RunC捐給OCI作為運行時標準的一個參考實現(xiàn)。2015年Hyper.sh開源了RunV,則是一種基于虛擬化的容器運行時接口的實現(xiàn),它很好地結(jié)合了虛擬化的安全性和容器的便利性。后來RunV和ClearContainer合并成立了kata項目,kata提供了更加完整的基于虛擬化的容器實現(xiàn)。我們把這種基于虛擬化的容器實現(xiàn)稱作安全容器。
除kata之外,還相繼出現(xiàn)了多個安全容器的實現(xiàn)方式,比如google的gVisor、AWS的firecracker-containerd、IBM的Nabla、VMware的CRX等等,其原理不盡相同,但共同反應(yīng)了一個趨勢,就是將容器的便利和虛擬化的安全隔離結(jié)合起來,讓虛擬化直接和應(yīng)用運維結(jié)合,成為云原生技術(shù)的大勢所趨。下面對這些“安全容器”的實現(xiàn)技術(shù)進行簡要的介紹和對比。
Google gVisor
相比于其他幾種實現(xiàn),gVisor的顯著不同之處在于,它通過攔截容器中應(yīng)用的系統(tǒng)調(diào)用,模擬了一個操作系統(tǒng)內(nèi)核,因此gVisor實際上沒有虛擬化,而是在用戶態(tài)實現(xiàn)了一個操作系統(tǒng)。這種方式可以降低因為虛擬化帶來的模擬設(shè)備內(nèi)存損耗。gVisor提供的runsc符合OCI標準,可以直接對接docker、containerd等容器平臺,同時它也完全兼容docker的鏡像格式。但是由于不是一個標準linux內(nèi)核,因為應(yīng)用的兼容性有較大問題。另外攔截系統(tǒng)調(diào)用帶來的巨大的性能損耗也是阻止其廣泛使用的一個阻礙。
圖片來自 https://gvisor.dev/docs/
IBM nabla
nabla是繼承于unikernel的隔離方式,應(yīng)用采用rumprun打包成一個unikernel鏡像,直接運行在一個專為運行unikernel定制虛擬機(ukvm)中。應(yīng)用直接打包首先可以降低很多內(nèi)核態(tài)和用戶態(tài)轉(zhuǎn)換的開銷,另外通過ukvm暴露非常有限的主機上的syscall(只剩7個),可以大大縮小主機的攻擊面。它是這些安全容器實現(xiàn)中,最安全的。不過由于它要求應(yīng)用打包成unikernel鏡像,因此和當前docker的鏡像標準是不兼容的。另外,unikernel應(yīng)用在諸如支持創(chuàng)建子進程等一些常規(guī)操作上都有很難解決的問題。
圖片來自 https://unit42.paloaltonetworks.com/making-containers-more-isolated-an-overview-of-sandboxed-container-technologies/
AWS Firecracker
最初firecracker是為AWS的Lambda打造的高密度輕量級虛擬化組件。由于它是從頭開始構(gòu)建虛擬化,帶著輕量化的目的,因此他拋掉了qemu這種通用虛擬化組件的大部分功能,只留下運行容器和Function必要的一些模擬設(shè)備。因此它的內(nèi)存開銷非常?。ㄐ∮?M),啟動速度非??欤ㄐ∮?25ms),一秒鐘可以在一個節(jié)點上運行150個輕量級虛擬機。
為了讓firecracker-microvm更好的運行容器,AWS啟動了firecracker-containerd項目,firecracker-containerd是containerd-shim-v2的一個實現(xiàn),不符合OCI標準,但是可以直接對接containerd啟動容器,也就很容易通過containerd對接k8s的CRI接口。containerd-shim-v2是containerd定義的新的runtime接口,它是對最初shim-v1的一個簡化,可以大大精簡runtime的組件和內(nèi)存使用。containerd是一個全插件化的代碼框架,擴展性非常好。firecracker-containerd在該框架下,實現(xiàn)了一個snapshotter作為鏡像插件,負責塊設(shè)備鏡像的生成;實現(xiàn)了一個shim-v2的runtime,負責容器的生命周期管理。另外還有個fc-control-plugin作為虛擬機的管理插件,提供grpc接口供runtime調(diào)用。在輕量級虛擬機內(nèi)部,有一個agent負責監(jiān)聽runtime傳進來的vsock,接收runtime的指令進行虛機內(nèi)部真正的容器生命周期管理操作,它是直接調(diào)用runc來管理容器的。
圖片來自 https://github.com/firecracker-microvm/firecracker-containerd/blob/master/docs/architecture.md
VMware CRX
VMware發(fā)布的vSphere 7與kubernetes進行了融合,它利用k8s的CRD將其集群的虛擬機、容器、函數(shù)等運行實體管理的所有功能都集成到了k8s中。VMware是一個做虛擬化起家的公司,因此虛擬化作為它的老本行,這塊的積累是很深厚的。它將虛擬化融合到它的容器runtime CRX中,因此和firecracker-containerd和kata類似,也是一個基于輕量級虛擬化的容器runtime的實現(xiàn)。通過對其虛擬化組件和guest內(nèi)核的精簡,CRX 容器同樣做到了很低的內(nèi)存損耗(20MB)、快速(100ms)的啟動以及高密度部署(單個節(jié)點大于1000個pod)。
圖片來自 https://cormachogan.com/2019/11/22/project-pacific-vmworld-2019-deep-dive-updates/
vSphere對node上的kubelet組件改造比較大,節(jié)點上的Spherelet部分功能和kubelet重合,負責pod的生命周期管理(他們稱之為Native Pod),運行在虛擬機中的SphereletAgent則集成了符合OCI接口規(guī)范的libcontainer,實現(xiàn)容器的生命周期管理,以及容器的監(jiān)控日志采集、容器的shell登錄(kubectl exec)。Spherelet和虛機中的SphereletAgent交互實現(xiàn)類似于kubelet使用CRI接口管理pod的效果。
kata containers
相比于以上幾種,kata containers 最大的特點是它專注于實現(xiàn)一個開放的符合OCI標準的安全容器runtime實現(xiàn),對于對接什么樣的虛擬化方案,它抽象了一套hypervisor接口,如今已經(jīng)對接了多種虛擬化實現(xiàn),比如qemu、nemu、firecracker、cloud-hypervisor等等。
圖片來自 https://katacontainers.io/
通過containerd-shim-v2和vsock技術(shù),kata精簡了大量的組件,配合輕量級hypervisor和精簡內(nèi)核,kata可以做到將額外內(nèi)存消耗降低到10MB以下。容器啟動時間降低到100ms以下。后續(xù)還會通過rust語言重寫等方式,提供更低內(nèi)存額外消耗。
圖片來自 https://github.com/kata-containers/documentation/blob/master/design/architecture.md
現(xiàn)有安全容器技術(shù)對比
安全容器技術(shù)發(fā)展趨勢
隨著Serverless等技術(shù)的興起,應(yīng)用部署和運維工作已經(jīng)下沉到云平臺上,人們需要一個更加高效的云原生技術(shù)平臺。從這幾年涌現(xiàn)的安全容器實現(xiàn)技術(shù)可以觀察到,無論公有云還是私有云廠商,都認識到了將虛擬化的隔離性和容器的高效運維特性相結(jié)合,是云原生平臺發(fā)展的必然趨勢。結(jié)合當前安全容器實現(xiàn)中遇到的一些問題,我們可以預(yù)見到,未來這項技術(shù)發(fā)展的幾個走向:
- 需要一個為安全容器而生的輕量級hypervisor ,當前qemu+kvm是主流的虛擬化技術(shù),但因為qemu是為通用的虛擬機而設(shè)計的,其體量過于龐大,而 對于安全容器而言,一個模塊化可定制的虛擬化實現(xiàn)尤為重要。 如果結(jié)合gVisor和nabla的實現(xiàn)來看,內(nèi)核的可定制性也是安全容器場景的必然要求。rust-vmm即是這樣一種模塊化的虛擬化組件庫。linux內(nèi)核本身的模塊化特性可以部分滿足容器場景下的內(nèi)核定制需求,不過也許像gVisor那樣實現(xiàn)一個專為容器而生的內(nèi)核也許是未來的趨勢。
- 容器的啟動時間是衡量一個云原生平臺效率的重要指標 ,尤其是在Serverless場景下,程序運行時間本身可能很短,這時候啟動時間可能占用了其絕大部分,那么這種低效就顯得尤為明顯。 安全容器通過極致的輕量化,可以將容器啟動時間降低到100ms以下 ,但是容器鏡像拉取時間過長仍是當前容器部署過程中的一個短板。由于當前容器鏡像格式和鏡像掛載方式等方面的限制,需要在啟動容器之前將容器鏡像拉取到本地以后,才能啟動容器。而容器啟動本身需要的數(shù)據(jù)只占鏡像的6%左右。因此我們亟需一個高效的鏡像掛載方式,當前已經(jīng)有一些免下載和懶加載(Lazy-Loading)的技術(shù)原型,后續(xù)需要盡快推出一個可商用的鏡像下載加速方案。
3. 當前公有云的網(wǎng)絡(luò)普遍采用原IaaS的網(wǎng)絡(luò)管理模式,在地址分配,網(wǎng)絡(luò)配置效率等方面完全趕不上容器快速啟停的需求,docker容器采用的veth方式在性能等方面也很難滿足高效轉(zhuǎn)發(fā)的要求。因此 需要一個專為云原生設(shè)計的網(wǎng)絡(luò)管理方案 。
4. 我們看到云平臺對應(yīng)用的管理逐步深入,從只管理基礎(chǔ)設(shè)施的IaaS層,發(fā)展到管理應(yīng)用整體部署和運維的PaaS,再到如今服務(wù)網(wǎng)格(Service Mesh)技術(shù)將平臺管理能力深入到應(yīng)用內(nèi)部的微服務(wù)級別。同時我們也看到, 以K8s容器、Istio服務(wù)網(wǎng)格為代表的云原生技術(shù)已經(jīng)和下層的計算/網(wǎng)絡(luò)虛擬化等技術(shù)逐步整合到了一起,比如安全容器即是容器與計算虛擬化的結(jié)合,而Istio服務(wù)網(wǎng)格也會與虛擬化網(wǎng)絡(luò)進行深度整合以提供更高的性能與更精細的QoS控制 。
5. 當前硬件加速技術(shù)在AI和大數(shù)據(jù)等領(lǐng)域大行其道, 安全容器需要與各種計算加速硬件技術(shù)進行結(jié)合 , 使得AI、大數(shù)據(jù)、科學計算等批量計算領(lǐng)域的用戶可以利用云平臺直接投遞其海量的計算任務(wù) ,可大大降低他們在底層技術(shù)上的心智負擔。通過硬件加速也是提升云平臺本身效率、降低云平臺運行成本的有效手段。比如 華為云擎天架構(gòu)在硬件加速方面擁有的技術(shù)優(yōu)勢在“安全容器”領(lǐng)域已得到充分的證明,CCE Turbo裸金屬容器已經(jīng)實現(xiàn)了安全容器的部分硬件卸載能力 。
總結(jié)
未來必然是云原生技術(shù)大行其道的時代,我們已經(jīng)看到很多傳統(tǒng)行業(yè)也逐漸認識到云原生技術(shù)可以給傳統(tǒng)企業(yè)的IT軟件,工業(yè)自動化,線上運維和數(shù)據(jù)管理等帶來明顯的效率提升。我們將看到通過對底層硬件和上層服務(wù)的全棧整合,打造出一個高效智能的云計算技術(shù)平臺,而這中間,容器將是串聯(lián)整個技術(shù)棧的關(guān)鍵所在。