咱們在上篇中介紹了如何限制容器可執(zhí)行的系統(tǒng)調用來解決當容器變節(jié)后,來控制爆炸半徑,接下來咱們將視角抽象一層,看看有哪些沙箱技術可以用來約束容器實例的行為。沙箱技術的驅動力主要來自于業(yè)界對VM虛擬機提供隔離機制在安全視角的認可,但是想推動技術來使虛擬機更加的輕量級,特別是讓虛擬機可以適配大規(guī)模容器化部署場景下應用實例的靈活性,快速啟動,臨時性特征。
Docker這樣的容器化部署方案天生的邏輯隔離性以及安全邊界的問題對谷歌也造成了困擾,為了解決這些問題,谷歌在2018年年中發(fā)布了一款新的沙箱容器運行時gVisor,提供了比容器更安全的隔離,比VM虛擬機更加輕量級。gVisor設計的核心是:隔離。大白話講就是解決在容器中運行的應用程序對宿主機內核的依賴,這也是容器化部署被吐槽最多的點,雖說操作系統(tǒng)內核(Linux操作系統(tǒng))也在不斷的增強其安全性,但是由于復雜性的原因(這也是筆者一直秉承的另外一個觀點,復雜性和安全性有較強的關聯(lián)),操作系統(tǒng)內核中的安全風險持續(xù)的被披露。
而谷歌gVisor基本上隔離了惡意代碼對宿主機上操作系統(tǒng)內核的惡意訪問,采用的實現(xiàn)方式是進程虛擬化。具體來說,gVisor在內核之外實現(xiàn)一個稱作內核進程的組件:Sentry,提供了大部分對Linux內核調用的實現(xiàn),并將容器對操作系統(tǒng)內核訪問請求定向到這個Sentry組件。不過Sentry并不是一個完整的進程級別的內核實現(xiàn),也就是說gVisor雖然截獲了容器實例對操作系統(tǒng)的所有調用,但是部分調用還是要代理到底層宿主機上的操作系統(tǒng)內核來處理并返回結果給容器實例。
另外谷歌gVisor的這種實現(xiàn)也被稱作是半虛擬化(paravirtualization),半虛擬化的含義是在用戶空間中重新實現(xiàn)操作系統(tǒng)指令,以期在用戶空間中滿足進程某些系統(tǒng)調用。這樣做的好處顯而易見,無論是從效率還是安全性方面,都得到的極大的提升。
從上邊的描述中筆者希望大家能夠體會到gVisor提供了近乎虛擬機級別的隔離,但是從實現(xiàn)原理角度讀者也能看到,gVisor只是改變了容器實例中運行的應用程序系統(tǒng)調用的方式,容器實例的隔離還是重度依賴于三個支柱:命名空間Namespace,CGroups以及chroot。雖然說gVisor的提升了容器實例的隔離性,由于gVisor的實現(xiàn)并沒有包含所有的系統(tǒng)調用,因此并不是所有的應用程序都可以部署到gVisor中,因此這個技術可以看成是過渡,也是我們接下來要討論的Kata容器的基礎。
有了對gVisor的了解后,咱們接著來看幾種真正虛擬機級別的容器實例隔離技術,先從Kata Container開始。容器實例和普通的進程沒有太大的區(qū)別,筆者在介紹容器本質系列文章的時候,反復的提這個概念,容器實例本質上就是被“動過手腳”的普通進程而已。而Kata Containers的實現(xiàn)方式就稍微有點不同了,具體來說,Kata Container將容器實例實例運行在隔離的虛擬機中。這種方式就如同大家熟知的“中間路線”這樣的概念,同時享受了將應用程序運行在OCI兼容的容器實例中,以及虛擬機帶來的良好隔離性。
由于Kata Conatiners將應用程序運行在獨立的虛擬機中,因此可以充分享受硬件虛擬化帶來的第二層防御,安全性得到的較大的提升。Kata Containers實現(xiàn)原理是在容器運行時和虛擬機之間通過代理來協(xié)作,當我們創(chuàng)建一個新的容器實例的時候,容器運行時通過代理將運行應用程序的請求代理給QEMU這樣的虛擬機管理軟件來運行。這種模式能支撐云原生架構下應用程序的前提是虛擬機足夠輕量級,啟動速度可以接受。阿里云,AWS等廠商針對這個問題給出了解決方案,對于阿里云來說,ACK服務中包含了安全沙箱v2,這個輕量級的虛擬化技術。安全沙箱v2是阿里云全新自研的基于輕量虛擬機技術的安全容器運行時,在提供隔離性的同時,由于虛擬機的體量很小,因此資源overhead降低了90%,沙箱啟動速度提升了3倍,單機密度提升了10倍。感興趣的同學可以參考阿里云的相關文檔。
AWS也提供了一種叫Firecracker的輕量級虛擬機技術,專門用來運行容器化應用,當然啟動速度相比傳統(tǒng)的虛擬機,有了數(shù)量級級別的提升??赡艽蠹視?,啟動速度真的那么重要嗎?對于需要支持高并發(fā)的應用來說,啟動速度是系統(tǒng)彈性的前提。咱們來舉個例子,假設我們基于阿里云的ACK部署了一套電商系統(tǒng),核心的服務購物車和交易中心為獨立部署的服務。由于微博出現(xiàn)某種熱點事件,導致訪問系統(tǒng)的用戶數(shù)量快速增加,作為系統(tǒng)的負責人,你通過ARMS,日志服務等監(jiān)控手段第一時間收到通知后,決定對系統(tǒng)進行臨時擴容。而擴容的速度其實很大一部分取決于實例的啟動速度。如果我們拉起新應用的速度在分鐘級別,那么很厚可能就會造成現(xiàn)有系統(tǒng)被打垮(沒有使用AHAS做限流降級的前提下),或者很多用于收到系統(tǒng)返回的錯誤,導致商機白白的流失。
由于虛擬機本身的技術限制因素,包括啟動操作系統(tǒng),初始化操作系統(tǒng)等,那么阿里云安全沙箱v2和AWS的Firecracker是如何做到極致的啟動速度呢?這里邊關鍵還是在內核,因為對于運行在容器中的應用程序,內核中的大部分功能都使用不到。因此阿里云安全沙箱v2和AWS的Firecracker使用的鏡像中,操作系統(tǒng)內核都是做過定制,清除了還運行容器應用無關的部分,只留下運行容器應用有關的功能,因此這種類型的輕量級虛擬機可以把啟動時間做到100ms。并且這種輕量級的虛擬機已經(jīng)經(jīng)過阿里云多年的生產(chǎn)系統(tǒng)驗證,無論是從安全性還是穩(wěn)定性方面,都可以得到保障。讀到這里好奇心強的同學可能會問,具體把內核中的哪些功能給清除了呢?我們都知道模擬系統(tǒng)硬件是整個虛擬化機制中最耗時最復雜的部分,而這些輕量級的虛擬機技術主要是圍繞這部分做了優(yōu)化,由于大部分容器化部署的應用都只使用部分硬件,比如存儲和網(wǎng)絡,因此簡化的硬件虛擬化模型大大加速了虛擬機的尺寸和啟動時間。
最后我們了解一下一種應用和操作系統(tǒng)結合的機制:Unikernels。這種機制的驅動力還是來自于操作系統(tǒng)本身,我們運行一個購物車服務,操作系統(tǒng)中大量的功能和模塊本質上都不太需要,從資源使用率的角度來看,屬于浪費。如果我們能夠為應用程序定制特制的操作系統(tǒng),比如只包含支持購物車應用運行的功能,那么不光是減小了資源使用,提升了應用的啟動時間,同時也縮小了攻擊面,一舉三得,何樂而不為啊。而Unikernels就是這種思路的具體實現(xiàn),通過創(chuàng)建包含應用和特定操作系統(tǒng)模塊的軟件機器鏡像,來在Hypervisor上直接啟動操作系統(tǒng)和之上的應用程序。這種模式的好處就是隔離性,和普通的虛擬機完全一致,并且由于對操作系統(tǒng)的模塊做了精簡,因此啟動速度(輕量級的程度)簡直可以和阿里云的安全沙箱v2想媲美。在將應用部署到Unikernels之前,我們需要將應用程序打包成兼容的機器鏡像,這樣虛擬機軟件的Hypervisor就可以像拉起標準的Linux操作系統(tǒng)那樣,啟動應用程序。
好了,今天這篇文章就這么多了,希望通過這篇文章,大家對隔離性更好(安全性更高)的技術有全面的了解,特別是阿里云提供的安全沙箱v2輕量化虛擬機機制,是很多對安全性要求高企業(yè)的首選,如果讀者的企業(yè)有這方面的需求,可以訪問阿里云ACK服務的官方文檔詳細了解:https://help.aliyun.com/document_detail/142151.html。