深度解析 AWS Firecracker 原理篇 – 虛擬化與容器運行時技術


https://aws.amazon.com/cn/blogs/china/deep-analysis-aws-firecracker-principle-virtualization-container-runtime-technology/

 

摘要

AWS Firecracker是一款由 AWS開源的輕量級虛擬化運行環境,客戶可以在 AWS 雲上和本地環境中使用它。Firecracker MicroVM 同時具備傳統虛擬機的安全性和工作負載隔離能力以及容器的速度和資源利用率。運行在為 Firecracker 優化過的 Amazon 裸金屬 EC2 服務器上的 MicroVM是多租戶容器服務的理想選擇,可以為最新的微服務或無服務器架構的現代應用提供方便、敏捷的開發和部署環境。

計算機虛擬化歷史

為了便於讀者理解,本文在正式介紹 Firecracker 前,先回顧一下虛擬化的發展,同時按照筆者的理解對涉及到的一些專業術語做一下翻譯和解釋:

  1. 輕量級虛擬機(以下簡稱 MicroVM,它沒有模擬完整的計算機硬件設備,只實現了運行現代化工作負載的必要功能)
  2. 虛擬機管理監視器(Virtual Machine Monitor以下簡稱VMM,配合設備模型的模擬器共同實現虛擬機 Hypervisor)
  3. 設備模型(Device Model 指需要 Hypervisor 模擬仿真的硬件設備)
  4. 無服務器(Serverless 指開發者不用再考慮服務器運行環境了,代表服務有 AWS Lambda)

在計算機科學中,虛擬化技術(Virtualization) 是一種資源管理優化技術,將計算機的各種物理資源(如:CPU、內存、磁盤網卡等 I/O 設備)進行抽象、轉換,呈現出一個可以供分割和組合的一個或多個虛擬機計算機環境。早在1974年,Gerald J. Popek 在論文中定義了虛擬化原型和准則。

而 X86平台虛擬化的轉折點則發生在2001年,VMware 發布了 ESX,法國著名程序員Fabrice Bellard編寫了開源設備模擬器軟件QEMU(Quick EMUlator)的第一個版本,實現了全虛擬化。后來 QEMU 通過集成 KVM 與 XEN 技術,廣泛用於虛擬機管理監視器,並提供接近原生的半虛擬化性能。現今已成為了開源領域 VMM 的事實標准(QEMU-KVM 在中小雲廠商中被廣泛使用)。作為通用設備模擬器,它在設計上做到了盡可能兼容任何硬件平台,同時各種高級特性(例如設備熱插拔)也在一直不斷豐富,並於2019年宣稱可以模擬所有設備。

然而風光的背后是,一些統計顯示2013至2018年間 QEMU 報告的 CVE 漏洞數量由49%來自它所模擬的設備,其中最為著名的 VENOM ”毒液”漏洞就是由它所模擬的軟驅控制器導致。現代硬件設備與 KVM 的成熟使得需要 QEMU 模擬的設備越來越少,對大量其它體系結構(事實支持 Intel、AMD、ARM足以)和陳舊設備(例如軟驅、打印機串口)的模擬,而此時的 QEMU 還依然在做加法,截止到2019年整個項目的代碼量超過了三百萬行(僅列出 C 代碼、頭文件與 Makefile,不包括注釋),總文件數量超過一萬。因此 QEMU 頻繁爆出虛擬機逃逸漏洞相關安全事件也就不足為奇了。

讀者看到這里一定會有一個疑問,有沒有一款更精簡、更安全、更現代化、Bug 更少易於維護的開源 VMM 用來替代 QEMU 這個龐然大物?

那么這個問題的其中一個答案,就是今天文中將要介紹的 Firecracker。

關於 AWS Firecracker 虛擬機

作為一款輕量級虛擬機,Firecracker 僅僅實現了以下功能:

  1. 基於 VirtIO 的網絡,磁盤和套接字驅動(virtio-net,virtio-blk,virtio-vsock),分別用於 MicroVM 的網絡與磁盤 IO 訪問,以及 MicroVM 上的 AF_VSOCK 套接字與宿主機的 AF_UNIX 套接字通信,從而實現 MicroVM 內運行的應用傳遞 vhost 內核代碼到宿主機的通信
  2. 可編程的間隔計時器
  3. KVM 時鍾
  4. 串口終端控制台(例如 /dev/ttyS0)
  5. 僅包含關機鍵的鍵盤

其中 VirtIO 驅動是一種主流的半虛擬化 IO 驅動方式, 它減少了用戶態和內核態之前都切換次數從而提升效率,也是 QEMU-KVM 中最常用的一種 IO 驅動方式。

在介紹具體 Firecracker 之前,不妨一起分析下運行在雲端的現代化 IT 工作負載,一類是曾經跑在 X86 物理機上的傳統應用,客戶會希望雲端 EC2 虛擬機能夠提供與本地  X86 同等,甚至更強的性能,更靈活豐富功能特性。另一類是通過容器、Serverless 等方式運行的雲原生現代化應用,這類應用往往由更加輕量化、松耦合、服務和模塊組成,運行方式也變得更加彈性和靈活。

傳統虛擬機技術

承載第一類負載為代表的平台虛擬化技術經過了幾十年的發展演進,從全虛擬化,半虛擬化,到硬件輔助虛擬化(例如Intel VT-x技術),再到如今以硬件卸載虛擬化(例如借助 Intel VT-d 通過 SR-IOV 方式卸載 IO 請求到硬件加速卡)。CPU 不需要預留計算資源給設備模型,而以前絕大部分設備都需要使用 QEMU 模擬(帶來 CPU 額外開銷),從而提升性能表現。

其中 AWS 的 Nitro 架構經過幾代演進之后,現在的版本基於 KVM 虛擬化自研 VMM 以及配套專用硬件加速卡,這使得虛擬化環境下獲得幾乎與裸金屬物理機一樣的性能,大規模的這項技術用於新一代 EC2 實例,獲得了極致的性能和安全可靠性。而關於 AWS Nitro 架構網上已經有大量的文章介紹,也可以參考 AWS re:INVENT 2017 CMP332 主題演講,筆者在這就不做深度詳細介紹了。

容器沙箱技術


而第二類負載的代表則是近年來大火的 Docker 容器,與傳統虛擬機的捕獲 – 模擬(Trap – and – Emulate)技術路線不同,容器最早的技術原型為 Unix 系統的 chroot 操作(誕生於1979年代),從而限制進程對指定根目錄之外的文件訪問。后來經歷了 FreeBSD Jails、OpenVZ、LXC、libcontainer 等技術逐步演進,形成了完整的一套應用運行環境沙箱隔離技術。而 Docker 則通過一系列創新,將古老的容器沙箱技術上升到了一個新的高度。在筆者看來這其中主要包括但不局限於:

  1. OCI (Open Container Initiative) 規范了運行時標准
  2. 鏡像分層設計與 OCI Image Spec 鏡像規范
  3. 實現了一個輕量級容器運行時 RunC,它擁有簡單運行容器所需要的全部組件
  4. 貢獻給 CNCF 社區的 containerd 運行時生命周期管理程序

盡管這些優秀的設計使得 Docker 成功的大規模在生產環境中得到運用,並且后來的Kubernetes 等容器編排調度工具也選擇了復用上面這些技術,但是容器的安全隱患從這項技術誕生的第一天起就一直存在。Docker容器技術采用共享宿主機內核方式運行,利用內核特性實現對不同用戶的命名空間進行隔離(6種方式),使用 CGroups進行硬件資源分配與限制,POSIX Capabilities進行 root 權限分割等,Seccomp 限定系統調用。雖然有組合了很多種技術,但實現原理決定了容器的其隔離性、封閉性還是遠遠低於擁有獨立 GuestOS 的虛擬機。由於操作系統內核漏洞,Docker 組件設計缺陷,以及不當的配置都會導致  Docker 容器發生逃逸,從而獲取宿主機權限。由於頻發的安全及逃逸漏洞,在公有雲環境容器應用不得不也運行在虛擬機中,從而滿足多租戶安全隔離要求。而分配、管理、運維這些傳統虛擬機與容器輕量、靈活、彈性的初衷背道而馳,同時在資源利用率、運行效率上也存浪費。

而AWS 同樣面臨着與 Docker 容器類似的技術困擾,2014年11月推出了 AWS Lambda 服務。為了提供無服務器計算下安全的體驗,最初通過后台為每個租戶置備獨立的  EC2 實例從而實現與其它租戶的強安全隔離。

隨着 AWS Lambda 服務的增長,開發團隊意識到需要一個新技術提供高安全性、靈活性和效率的運行時環境給類似 AWS Lambda 和 Fargate 這樣的服務。此時開發團隊利用打造硬件卸載虛擬化所積攢的經驗,重新開始構建一款全新的 VMM 並且整合容器生態系統,也就是 AWS Firecracker。

 

AWS Firecracker 開源項目詳解

從 AWS 官方公布Firecracker至今已經有一年時間了,在這短短的一年時間里,作為一個開源項目,不僅引起了社區的廣泛關注同時也孵化出了多個基於 Firecracker 運行時的容器項目。開源也大大拓寬了 Firecracker 這款通用輕量級虛擬機的使用場景,除了現在 AWS 的無服務計算產品,還能運行在 AWS 以外的本地環境中運行容器,未來還有可能運行在邊緣設備硬件上運行各種應用。

以社區的 firecracker-containerd 項目為例,通過該項目使得標准的 RunC 容器能夠運行在 MicroVM 內部,而且通過 HostOS 上的 containerd 就能夠管理 GeustOS 的容器。從而無縫兼容 OCI (Open Container Initiative) 標准規范,鏡像格式以及管理工具,這使得以 Docker 和 Kubernetes 的主流容器運行調度框架只需要少量修改,就能夠適配基於 Firecracker 虛擬化技術隔離的安全容器方案。這樣提現了容器領域以開源文化主導的社區生態魅力。

除此之外與 firecracker-containerd 功能類似的另一個項目,則是由 OpenStack 社區主導的 Kata Containers,該項目在1.5版本后,新增加了對 Firecracker VMM 的支持(之前僅支持 QEMU和 NEMU作為 VMM),Kata 自己的運行時和 RunC 一樣也符合 OCI 及 CRI 標准規范,能夠同時被 Docker、Kubernetes 及 OpenStack 直接支持。

那么基於 Firecracker 的容器運行時有哪些優勢呢?

首先是虛擬化提升了應用負載的隔離性,每個 MicroVM 內部僅運行一個應用容器,或者僅運行一個應用 Pod(Kubernetes 情況下,同一 Pod 內的多個容器還是采用 Docker 沙箱方式隔離構成單個應用)。而不同租戶的不同應用之間,實現了虛擬化級別的隔離,每個應用不再共享 HostOS 內核,而是擁有獨立的 GeustOS Linux 內核。與此同時 Firecracker  運行在普通 Linux 上,每個 MicroVM 都是以 KVM 進程的方式運行,由操作系統負責進程調度。對於不同 MicroVM 在宿主機上運行的 Firecracker 進程,Firecracker 通過靜態鏈接以 jailer 方式啟動,並通過 CGroups 和 Seccomp BPF 進行進程間安全隔離,全方位提供隔離性保障。

其次,安全始終是 AWS 關注的頭等大事。虛擬化作為一項最基礎的服務,其本身的安全性格外重要,在 Amazon EC2 的主頁是這樣描述產品的:”Amazon EC2 安全並且可以調整大小的雲計算容量。在需要時啟動應用程序,無需預先承諾。”,安全是描述 EC2 的一個詞匯。而前文中也講到了 QEMU 作為設備模型開源實現,它的安全方面的聲譽卻相當糟糕,這也成了 AWS 決定重新做一款 VMM 的原因。從主要兩個維度降低風險:

  1. 拋棄 QEMU 使用的 C 語言,選擇內存安全的 Rust 作為開發語言
  2. 基於 crosvm 使用極簡設備模型,模擬盡可能少的必要設備,減小暴露的攻擊面

在 Rust 語言的定義中,凡是可能會導致程序內存使用出錯的特性,都被認為是不安全的(Unsafe),反之是安全的(Safe)。除非通過”  Unsafe “關鍵字顯示使用, 如果您的代碼有某種方式可能會導致內存不安全(例如緩沖區溢出),則會出現編譯錯誤。生命周期和所有權也可以確保安全的並發性。 例如,編譯器強制在任何時候,給定的內存區域只能由一個線程寫,也可以由任意數量的線程讀取。而與 Rust 並列的底層開發語言 C 和 C++,則是屬於不安全的語言。

再次是高性能和低開銷:得益於極簡的設備模型, Firecracker 取消了 SeaBIOS (開源的 X86 BIOS),移除了 PCI 總線,取消了 VGA 顯示等等硬件模擬,嚴格的說它甚至不是一台完整的虛擬計算機。而 Firecracker 運行的 GuestOS 使用的也是 AWS 定制過的精簡  Linux 內核,同樣裁剪掉了對應的設備驅動程序、子系統等等。因此叫它 MicroVM,其啟動步驟和加載項要遠遠少於傳統虛擬機。因此 Firecracker 目前已經能提供小於125ms 的 MircroVM 啟動速度,每秒150台的啟動能力,小於5MiB 的內存開銷,並發運行4000台的極限承載容量(AWS i3.metal EC2 作為宿主機),以及熱升級能力等。這些都是傳統虛擬機所遙不可及,但現代化彈性工作負載又有強烈需求的性能指標。

其實為了解決容器安全隔離性問題,開源社區也涌現了大量同類項目,而 Firecracker  是跟它們相比有哪些不同,又如何脫穎而出的呢?在筆者看來這些其它方案大致分為兩類:

一類是基於在已有的成熟 VMM,進行編譯選項裁剪和 GeustOS 精簡,同樣使用虛擬化技術解決問題。這類方案包括基於 QEMU-KVM 的 Hyper.sh RunV,Intel Clear Container,Pouch Container 等,基於 VMware ESXi 的 vSphere Integrated Containers,以及 Microsoft 的 Hyper-V Container。這類方案的主要不足源於這些 Hypervisor 過去用在傳統虛擬機,並不是面向無服務器計算這類的現代化工作負載而設計開發,因此在安全、性能、開銷方面可能會存在先天不足。

而另一類則完全不使用虛擬機,以 Google 的 gVisor 以及一眾 Unikernel 技術為代表gVisor 引入了進程虛擬化的思想,去掉了設備模型,將虛擬化的邊界移到了系統調用層面,從而減少傳統設備虛擬化的開銷。而代價卻是有大量的 Linux 系統調用需要沙箱處理,暴露了更多的攻擊面(目前已實現了數百個系統調用)。而 Unikernel 則源於90年代的操作系統微內核理念,隨着近年來容器技術的走紅,這項技術也越來越被人關注(例如 Nabla container)。其核心思想是將 Linux 的宏內核拆分成為多個庫,只打包應用依賴的庫到微內核鏡像中。每個應用擁有獨立的微內核,從而提升性能,降低開銷,減少攻擊面。不過這些 Unikernel 項目大部分處於早期階段,作為容器技術的競爭對手,其部署、管理以及與 OCI 的兼容性都會是一大考驗。

小結

虛擬化技術從誕生到如今已經歷經了近五十年,芯片硬件,虛擬化軟件,操作系統廠商都在不斷迭代自己技術,從而共同推動虛擬化技術的發展。近年來隨着雲計算的崛起,雲廠商充分整合優化硬件、軟件、系統三條線上獨立發展的技術,在此基礎上又結合業務需求進行了優化和剪裁,讓大家已經看到了虛擬化的老樹又開出了新花,AWS 從不同需求出發,通過 Nitro 與 Firecracker 兩款虛擬機技術,將的虛擬化演進到了一個全新的高度。

引用

https://firecracker-microvm.github.io/

https://github.com/firecracker-microvm/

https://aws.amazon.com/cn/blogs/china/kata-containers-1-5-firecracker-support/

https://aws.amazon.com/cn/blogs/china/firecracker-lightweight-virtualization-for-serverless-computing/

https://www.slideshare.net/AmazonWebServices/c5-instances-and-the-evolution-of-amazon-ec2-virtualization-cmp332-reinvent-2017


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM