歡迎光臨
每天分享高質量文章

gVisor:Google開源的新型沙箱容器執行時環境

容器技術徹底改變了我們對應用程式進行開發、打包與部署的具體方式。然而,系統在與容器對接時仍會暴露出大量攻擊面,因此相當一部分安全專家不建議在容器當中執行不受信任或潛在的惡意應用程式[1]。
隨著使用者越來越多地希望在容器當中執行異構及低信任度工作負載,沙箱化容器也就應運而生——此類容器能夠在主機作業系統與容器內應用程式之間提供安全的隔離邊界。
為此,我們將介紹gVisor[2]——一款新型沙箱解決方案,其能夠為容器提供安全的隔離措施,同時繼續保持遠優於虛擬機器的輕量化特性。gVisor能夠與Docker及Kubernetes實現整合,從而在生產環境中更輕鬆地建立起沙箱化容器系統。


傳統Linux容器並不屬於沙箱環境

傳統Linux容器當中執行的應用程式採用等同於常規(非容器化)應用程式的系統資源訪問方式:即直接對主機核心進行系統呼叫。內核以高許可權樣式執行,允許其與必要硬體互動並將結果傳回給應用程式。

對於傳統容器,我們可以立足核心對應用程式所能訪問的資源作出一些限制。這些限制透過Linux cgroups與名稱空間來實現。然而,並非所有資源皆可透過這種方式加以控制。此外,即使存在這些限制,核心仍然在很大程度上暴露在惡意應用程式的攻擊範圍之內。
像seccomp過濾器這類核心功能可以在應用程式與主機核心之間建立更好的隔離機制,但其要求使用者建立預定義的系統呼叫白名單。在實踐當中,我們往往很難預先確定哪些應用程式需要哪些系統呼叫。如果應用程式所需要的系統呼叫當中存在安全漏洞,過濾器功能更是表現得無能為力。


現有基於虛擬機器的容器技術

改進容器隔離能力的一種方法,是在其自有虛擬機器中執行各套容器。這能夠為每個容器提供屬於自己的“機器”,包括對應核心與虛擬化裝置,且與主機完全分離。在這種情況下,即使訪客虛擬機器當中存在漏洞,管理程式也仍能將其與主機以及同樣執行在主機上的其它應用程式/容器隔離開來。

不同的虛擬機器往往能夠提供良好的隔離性、相容性與效能表現,但其同樣需要佔用可觀的資源與空間。
Kata容器是一個開源專案,其利用精簡化虛擬機器以盡可能減少資源佔用量,同時最大限度提高容器隔離能力。與gVisor一樣,Kata也包含與Docker及Kubernetes相相容的開放容器倡議(簡稱OCI)執行時。


利用gVisor建立沙箱化容器

gVisor能夠在保證輕量化優勢的同時,提供與虛擬機器類似的隔離效果。gVisor的核心為一套執行非特權普通行程的核心,且支援大多數Linux系統呼叫。該核心使用Go編寫,這主要是考慮到Go語言擁有良好的記憶體管理機制與型別安全性。與在虛擬機器當中一樣,gVisor沙箱中執行的應用程式也將獲得自己的核心與一組虛擬裝置——這一點與主機及其它沙箱方案有所區別。

gVisor透過在使用者空間內攔截應用程式系統呼叫並充當訪客核心,gVisor能夠提供強大的隔離邊界。而與需要一組固定資源的虛擬機器不同,gVisor能夠隨時適應不斷變化的資源條件,這一點更像是普通Linux行程。gVisor很像是一種超虛擬化作業系統,其與完整虛擬機器相比擁有更靈活的資源利用方式與更低的固定成本,但這種靈活性的代價是其系統呼叫成本更高且應用程式相容性略差。
保護工作負載已經成為目前業界的首要任務,我們很高興地看到gVisor這類創新方案的出現,並期待著能夠在規範方面開展合作,共同對聯合技術元件加以改進,從而為生態系統帶來更可靠的安全保障能力。”
——Samuel Ortiz,Kata技術指導委員會成員、英特爾公司首席工程師
“Hyper公司鼓勵我們瞭解gVisor採用的全新容器隔離方法,業界需要一套強大的安全容器技術生態系統,我們期待著與gVisor合作以將安全容器推向主流市場。”
——Xu Wang,Kata技術指導委員會成員、Hyper.sh公司CTO


與Docker及Kubernetes相整合

gVisor執行時能夠與Docker及Kubernetes實現無縫化整合,這一整合效果透過匹配OCI執行時API的runsc(即‘run Sandboxed Container’的縮寫)實現。
runsc執行時可與Docker的預設容器執行時runc進行互換。其安裝非常簡單; 在安裝完成後,只需要一個額外標記即可在Docker內執行沙箱化容器:

$ docker run --runtime=runsc hello-world
$ docker run --runtime=runsc -p 3306:3306 mysql
在Kubenetes當中,大多數資源隔離在pod層面實現,而這意味著pod能夠天然充當gVisor的沙箱邊界。Kubernetes社群目前正在對沙箱pod API進行標準化調整,但目前已經開放實驗性支援供使用者體驗。
runsc執行時能夠在Kubernetes叢集當中透過cri-o或cri-containerd等專案執行沙箱化pod——此類專案負責將Kubelet中的訊息轉換為OCI執行時命令。
gVisor能夠實現大部分Linux系統API(總計200項系統呼叫與計數),但仍有一部分無法支援。部分系統呼叫與引數目前尚無法使用,/proc與/sys檔案系統中的某些特定部分同樣如此。因此,還有少數應用程式不能在gVisor當中執行。但除此之外,包括Node.js、Java 8、MySQL、Jenkins、Apache、Redis以及MongoDB等在內的大多數應用程式皆可順利運作。
馬上開始

作為開發者,我們希望能夠讓容器的易用性與可移植性同虛擬機器的資源隔離能力結合起來。而gVisor無疑是我們朝著這一方向邁出的重要一步。您可以檢視我們在GitHub上的repo[2]以瞭解如何使用gVisor以及更多背後技術細節。同樣歡迎大家加入我們的Google群組[3]參與討論!
最後,請參閱gVisor PM的採訪內容以瞭解更多資訊。