Kata Containers創始人:安全容器導論

從2015年5月初開始創業開發 HyperContainer (runV) 到如今,也快五年了,在這個時候還來寫一篇什麼是安全容器,顯得略有尷尬。不過,也正是通過這五年,愈來愈多到人開始感到,我須要它卻說不清它,這個時候來給你們從新解釋 「安全容器」 也正是時候。

緣起:安全容器的命名

Phil Karlton 有一句名言——緩存

計算機科學界只有兩個真正的難題——緩存失效和命名。安全

就容器圈而言,我相信命名絕對配得上這句話,這毫無疑問是一件讓老開發者沉默,讓新人落淚的事情。網絡

僅就係統軟件而言,咱們當今比較通行地稱爲 Linux 容器(LinuxContainer)的這個概念,曾經用過的名字大概還有——jail, zone, virtualserver, sandbox... 而一樣,在早期的虛擬化技術棧裏,也曾經把一個虛擬機環境叫作容器。畢竟這個詞自己就指代着那些用來包容、封裝和隔離的器物,實在是太過常見。以致於,以嚴謹著稱的 Wikipedia 裏,這類技術的詞條叫作「系統級虛擬化」,從而回避了「什麼是容器」這個問題。架構

當2013年 Docker 問世以後,容器這個概念伴隨着「不可變基礎設施」、「雲原生」這一系列概念,在隨後的幾年間,以摧枯拉朽之勢顛覆了基於「軟件包+配置」的細粒度組合的應用部署困境,用簡單地聲明式策略+不可變容器就清爽地描述了軟件棧。應用怎麼部署彷佛離題了,咱們這裏想要強調的是——框架

雲原生語境下的容器,實質是「應用容器」——以標準格式封裝的,運行於標準操做系統環境(經常是Linux ABI)上的應用打包——或運行這一應用打包的程序/技術。運維

這個定義是我在這裏寫下的,可是它並非個人我的意志,這是基於 OCI (Open ContainerInitiative) 規範這一共識的,這個規範規定了容器之中的應用將被放置在什麼環境中,如何運行,好比啓動容器根文件系統上的哪一個可執行文件,用什麼用戶,須要什麼樣的 CPU、內存資源,有什麼外置存儲,有什麼樣的共享需求等等。性能

有了這一共識作基礎,咱們來講安全容器,這又是一段命名血淚史。當年,個人聯合創始人趙鵬是用「虛擬化容器」命名的咱們的技術的,爲了搏人眼球,用了「Secure as VM, Fast asContainer」的大字標語,自此,被容器安全性問題戳中心坎的人們馬上用「Secure Container」來稱呼這類東西,一發而不可收。而咱們的心裏中,這項技術提供了一層額外的隔離,隔離可能意味着安全性中的一環,也意味着某些運維效率、某些優化可能或者其餘的功能。實際上,給安全容器這樣的定義更合理——優化

一種運行時技術,爲容器應用提供一個完整的操做系統執行環境(經常是LinuxABI),但將應用的執行與宿主機操做系統隔離開,避免應用直接訪問主機資源,從而能夠在容器主機之間或容器之間提供額外的保護。spa

間接層:安全容器的精髓

安全問題的惟一正解在於容許那些(致使安全問題的)Bug發生,但經過額外的隔離層來阻擋住它們。操作系統

—— LinuxCon NA 2015, Linus Torvalds

爲了安全,爲何要引入間接層?由於以 Linux 之類的目前主流宿主機操做系統的規模,是沒法從理論上驗證程序是沒有 Bug 的,而一旦合適的 Bug 被合適地利用,安全性風險就變成了安全性問題了,框架和修補並不能確保安全,因此,進行額外的隔離、縮減攻擊面,就成了緩解安全問題的法寶——咱們不能確保沒有漏洞,但咱們經過組合來減小漏洞被完全攻破的風險。

Kata: 雲原生化的虛擬化

2017年12月,咱們在 KubeCon上對外發布了 Kata Containers 安全容器項目,這個項目的兩個前身——咱們發起的的 runV 和Intel 發起的 Clear Container 都發佈於2015年5月(是的,早於上面 Linus 的引語)。這組項目的思路很簡單 ——

1. 操做系統自己的容器機制沒辦法解決安全性問題,須要一個隔離層;

2. 虛擬機是一個現成的隔離層,AWS這樣的雲服務已經讓全世界相信,對戶來講,"secure of VM" 是能夠知足需求的;

3. 虛機裏面只要有個內核,就能夠支持 OCI 規範的語義,在內核上跑個 Linux 應用這並不太難實現;

4. 虛機可能不夠快,阻礙了它在容器環境的應用,那麼可不能夠擁有 "speed of container" 呢?

如今,若是最後一個問題能夠解決,那麼它就是咱們要的「安全的容器」了——這就是 Kata Containers。

目前 Kata Containers 一般是在 Kubernetes 環境中使用的,Kubelet 經過CRI 接口讓 containerd 或 CRI-O 執行運行時操做,一般鏡像操做由這些 CRI Daemon 來進行,而根據請求,把 Runtime 操做寫成一個 OCI Spec 交給 OCI Runtime 執行。這裏,對於 1.2 以上的 containerd 和 1.5 版本上後的 Kata Containers(對應 ),一般是利用 containerd 來完成的:

  • 每一個 Pod 會有一個 shim-v2 進程來爲 containerd/CRI-O 執行各類運行時操做,這個進程和整個 Pod 的生命週期一致,經過一個 ttRPC 接口爲 containerd/CRI-O 提供服務;
  • Shim-v2 會爲 Pod 啓動一個虛擬機做爲 PodSandbox提供隔離性,其中運行着一個 Linux 內核,一般這個 Linux 內核是一個裁剪過的內核,不會支持沒有必要的設備;
  • 這裏用的虛擬機能夠是 Qemu 或是 Firecracker,若是是 Firecracker,那麼根本就沒有模擬的設備,而若是是 Qemu,經過配置和補丁,也會讓它儘可能小一些,支持的其餘虛擬機還包括 ACRN 和 cloud-hypervisor,將來後者可能會被愈來愈多的用到;
  • 這個虛擬機在啓動的時候可能根本就是一個 initrd 而沒有完整操做系統,或者有個極小的操做系統,總之,它徹底不是按照一臺模擬機的操做系統來配置的,它只是支撐容器應用運行的基礎設施,以及相關的應用環境 Metrics 採集或應用跟蹤調試須要的資源;
  • 容器自己的 rootfs 會在 Sandbox 啓動以後,在收到 contaienrd/CRI-O 的建立容器的 OCI 請求以後,以熱插拔的方式動態插入到虛機中,容器的 rootfs 準備和虛機自己的啓動是能夠並行的;
  • 依照 CRI 語義和 OCI 規範,Pod 裏能夠啓動多個相關聯的容器,它們被放在同一個虛機裏,而且能夠互相共享 namespace;
  • 外來的存儲卷能夠以塊設備或文件系統共享的方式插入到 PodSandbox 中,但對於 Pod 裏的容器來講,它們都是加載好的文件系統,目前開始逐漸普及的文件系統方式是專爲 Kata 這樣的場景設計的 virtio-fs,它不只比傳統的 9pfs 更快、有更完整的 POSIX 文件系統的支持,並且藉由所謂 vhost-user 和 DAX 技術,它還能夠在不一樣的 Pod 之間共享相同存儲內容的緩存頁 (page-cache),讓它們能夠和普通的 runC 容器同樣,節約寶貴的內存;
  • 對於網絡,使用 tcfilter,能夠直接支持各類 CNI 的插件來提供容器網絡,這樣的好處是無需作什麼調整就天然的工做,可是效率上由於作一次橋接會有損失,在生產環境中,也能夠考慮使用 enlightened 網絡模式,用一個特製的 CNI 插件來高效接入容器網絡。

能夠看到,首先 Kata Containers 是個全功能的容器運行時引擎,它用起來徹底不像是傳統虛機,分明就是個容器引擎,而且,經過「少用沒必要要的內存」和「共享能共享的內存」來下降內存的開銷,更小的內存不只開銷更小,啓動也更輕快,對於大多數場景來講,這實現了"secure of VM, speed of container"。在安全性以外,它比起傳統的虛機,更具備容器的彈性,更少了機器的那種物理操做手感,咱們把這種技術稱爲「雲原生化虛擬化」或者「面向雲原生的虛擬化」技術。

gVisor: 進程級虛擬化

在 Kata Containers 以後半年的哥本哈根KubeCon 上,Google 開源了他們內部開發了五年的 gVisor 安全容器做爲迴應。

若是說 Kata Containers 是對經過對有隔離技術進行組合和改造來構建容器間的隔離層的話,gVisor 的設計顯然是更加簡潔的——gVisor 是一個用 Go 語言重寫的運行在用戶態的操做系統內核,稱爲 Sentry,它並不依賴於虛擬機,相反,它藉助「平臺(Platform)」的能力,讓宿主機把應用的全部訪問都從新轉交給 Sentry,在 Sentry 中處理後再將一些必要的操做請宿主機幫忙來完成。

能夠說 gVisor 在作的是一個純粹的面向應用的隔離層,從 Linux ABI 到 Linux ABI 的「過濾器」。全新寫做的優點在於不須要遷就太多已有技術棧的桎梏,能夠寫得更輕,啓動確定也會更快,事實上,資源的伸縮也更方便,或者說更容器一些。好多操做系統圈的朋友都絕不掩飾地說,他們更喜歡 gVisor 的架構,若是能解決一些目前不容易解決掉的問題的話。

gVisor 做爲隔離層,它的安全性依據在於:

  • 首先是攻擊面變小,宿主操做系統將只爲沙箱裏的應用執行大約20%的 Linux 系統調用。經過研究,gVisor 的做者們發現,大多數攻擊都是經過一些不經常使用系統調用中的缺陷進行的,不經常使用的系統調用的實現路徑通常也比較少被審閱,相對於那些熱路徑來講,安全性要更差一些,gVisor 的設計讓應用對那些不經常使用系統調用的訪問根本不會落到宿主機操做系統內核上,從而避免了大部分的攻擊;
  • 其次是他們發現了最最常被攻擊到的系統調用是 open(),因而他們直接將真有必要的 open()調用交給了一個專門的稱爲 Gopher 的進程來執行,從而能夠更容易被限制、審計和管控;
  • 最後,他們是用高級語言 Go 寫的內核,優點固然是更加內存安全,固然,他們也坦誠,這個語言其實不太「系統級」,他們爲此不得不作了不少手腳,也爲 Go Runtime 貢獻了不少修改。

固然,gVisor 的架構是很漂亮,但從新實現一個內核這件事情,除了 Google 這樣的巨頭恐怕也沒有幾家能夠作(相似的基本作到的也就是微軟的初代 WSL了),並且這個超前的設計仍是有些現實問題:

  • 首先,就是它不是 Linux,因此,在兼容性方面和 Kata 這樣的解決方案尚有差距;
  • 其次,對於當前的 Linux 系統調用方式和 CPU 指令系統,每一個系統調用的攔截都會有至關的性能開銷,儘管全棧優化能夠有必定緩解,但對系統調用比較多的場景來講,性能損失沒法忽略。

因此,短期內 gVisor 方案並不能成爲一個終極解決方案,固然,它不只能夠適應一些特定的場景,並且帶來的啓示性可能對將來的操做系統乃至 CPU 指令集的演進發生做用,從而推進咱們能夠擁有一個更完美的安全容器解決方案。

安全容器:不止於安全

安全容器的隔離層讓應用的問題——不管是惡意攻擊,仍是意外錯誤——都不至於影響宿主機,也不會在不一樣的 Pod 之間相互影響。並且實際上,額外隔離層帶來的影響並不只是安全,對於調度、服務質量和應用信息的保護都有好處。

傳統的操做系統容器技術是內核進程管理的一個延伸,容器進程自己是一組關聯的進程,對於宿主機的調度器來講是徹底可見的,一個 Pod 裏的全部容器或進程,同時也都被宿主機調度和管理。這就意味着,在有大量容器的環境下,宿主機內核的負擔很重,在不少實際環境中已經能夠觀察到這個負擔帶來的開銷了。而採納安全容器以後,從宿主機上是看不到這些完整的信息的,隔離層同時也下降了宿主機的調度開銷,減小了維護負擔,避免了容器之間、容器和宿主機之間的服務質量干擾。從另外一個方向看,安全容器做爲一道屏障,可讓宿主機的運維管理操做不能直接訪問到應用的數據,這樣,把用戶的應用數據直接保護在沙箱裏就能夠下降對用戶的受權要求,保障用戶的數據私密性。

當咱們的目光向投向將來,能夠看到,安全容器不只僅是在作安全隔離,由於安全容器隔離層的內核,相對於宿主機的內核是獨立的,專門對應用服務,從這個角度說,主機/應用的功能之間作合理的功能分配和優化,展示出讓人期待的潛力,未來的安全容器,可能不只是隔離性開銷的下降,甚至是提高應用的效能——

隔離,讓雲原生基礎設施更完美。

Kata Containers開源地址:

https://katacontainers.io/

相關文章
相關標籤/搜索