KylinX:A Dynamic Library Operating System for Simplified and Efficient Cloud ~

正文以前

彷彿很久沒寫過東西了。。剛纔一翻,最新文章在1-19,三個月了。。。果真我已經快放棄簡書了,不過這兒好歹承載了那麼多的回憶,仍是別丟了吧。之後把我翻譯的一些論文丟上來算了。。php

正文

~原文我都用CAJviewer識別出來,而且整理過了,有須要的請私信我~ 或者發我郵箱:1184827350@qq.com詢問好了。下面我只放中文的內容了,(全篇大部分google翻譯,而後人讀一遍粗略修改過。有些地方可能仍是不太通順,不過那就基本表明我也不大懂了。。。)裏面還有一些【】裏面的內容是我本身作的標註,能夠忽略html


Unikernel專門簡化LibOS和目標應用到一個獨立的單一用途的虛擬機(VM)上運行在Hypervisor上,這被稱爲(虛擬)設備。 與傳統VM相比,Unikernel設備具備更小的內存佔用和更低的開銷,同時保證了相同的隔離級別。 在缺點方面,Unikernel剝離了其總體設備的流程抽象,從而犧牲了靈活性,效率和適用性。前端

本文探討了Unikernel設備(強隔離)和流程(高靈活性/高效率)的最佳平衡。 咱們提供KylinX,一個動態庫操做系統,經過提供pVM(相似進程的VM)抽象,實現簡化和高效的雲虛擬化。 pVM將虛擬機Hypervisor做爲操做系統,將Unikernel設備做爲容許頁面級和庫級動態映射的進程。linux

  • 在頁面級別,KylinX支持pVM fork以及一組用於pVM間通訊(IpC)的API。
  • 在庫級別,KylinX支持在運行時連接到Unikernel設備的共享庫。

KylinX對潛在威脅實施映射限制。 KylinX能夠在大約1.3毫秒內分叉pVM,並在幾毫秒內將庫連接到正在運行的pVM,二者都與Linux上的進程分支至關(大約1毫秒)。 KylinX IpC的延遲也與UNIX IPC的延遲至關。web

1 介紹

商品雲(如EC2 [5])提供了一個公共平臺,租戶租用虛擬機(VM)來運行他們的應用程序。 這些基於雲的VM一般專用於特定的在線應用程序,如大數據分析[24]和遊戲服務器[20],並被稱爲(虛擬)設備[56,64]。 高度專業化的單一用途設備只須要傳統操做系統支持的一小部分來運行其容納的應用程序,而當前的通用操做系統包含普遍的庫和功能,造成最終多用戶,多應用程序場景。設備的單一用途的使用和傳統操做系統的通用設計之間的失配引發的性能和安全性懲罰,使基於設備的服務的部署和安排變得繁瑣[62,52],運行效率低[56],並容易受到沒必要要的庫的影響[27]。後端

這個問題最近推進了Unikernel [56]的設計,這是一個庫操做系統(LibOS)架構,旨在實現雲中高效安全的設備。 Unikernel將傳統操做系統重構爲庫,並將應用程序二進制和必需庫封裝成專用的應用鏡像,該映像可直接在 Xen [ 30]和KVM [22] 等虛擬機Hypervisor上運行。與傳統VM相比,Unikernel設備去掉了未使用的代碼:跨域

  • 實現了更小的內存佔用
  • 更短的啓動時間
  • 更低的開銷
  • 同時保證了相同的隔離級別。

虛擬機Hypervisor的穩定接口避免了早期LibOS遇到的硬件兼容性問題[39]。 【Mark: 早期LibOS能夠一看】安全

在缺點方面,Unikernel剝離了其靜態密封的單片設備的過程提取,所以犧牲了靈活性,效率和適用性。 例如,Unikernel不能支持動態fork,這是傳統UNIX應用程序經常使用的多進程抽象的基礎; 而且編譯時致使的不可變性使得運行時沒法管理,例如在線庫更新和地址空間隨機化。 這種缺陷在很大程度上下降了Unikernel的適用性和性能。服務器

在多任務操做系統中,進程(運行的程序)須要一種方法來建立新進程,例如運行其餘程序。Fork及其變種在類Unix系統中一般是這樣作的惟一方式。若是進程須要啓動另外一個程序的可執行文件,它須要先Fork來建立一個自身的副本。而後由該副本即「子進程*」*調用exec系統調用,用其餘程序覆蓋自身:中止執行本身以前的程序並執行其餘程序。網絡

Fork**操做會爲子進程建立一個單獨的地址空間。子進程擁有父進程全部內存段的精確副本。在現代的UNIX變種中,這遵循出自SunOS-4.0的虛擬內存模型,根據寫入時複製語義,物理內存不須要被實際複製。取而代之的是,兩個進程的虛擬內存頁面可能指向物理內存中的同一個頁,直到它們寫入該頁時,寫入纔會發生。在用fork配合exec來執行新程序的狀況下,此優化很重要。一般來講,子進程在中止程序運行前會執行一小組有利於其餘程序的操做,它可能用到少許的其父進程的數據結構

當一個進程調用fork時,它被認爲是父進程,新建立的進程是它的孩子(子進程)。在fork以後,兩個進程還運行着相同的程序,都像是調用了該系統調用通常恢復執行。而後它們能夠檢查調用的返回值肯定其狀態:是父進程仍是子進程,以及據此行事。

fork**系統調用在第一個版本的Unix就已存在[1],它借用於更早的GENIE分時系統[2]Fork**是標準化的POSIX的一部分

在本文中,咱們將研究是否存在平衡,以得到Unikernel設備(強隔離)和進程(高靈活性/高效率)的最佳性能。 在虛擬機Hypervisor(Hypervisor)上的應用程序和傳統操做系統上的進程之間進行類比,從靜態Unikernel向前邁出一步,就有了KylinX,這是一個動態庫操做系統,經過提供pVM(process-like VM)抽象來實現簡化和高效的雲虛擬化。 咱們將虛擬機Hypervisor做爲操做系統和容許pVM的頁級和庫級動態映射的進程同樣的應用程序。

【Hypervisor,又稱虛擬機器監視器(英語:virtual machine monitor,縮寫爲 VMM),是用來創建與執行虛擬機器的軟件、固件或硬件。 被Hypervisor用來執行一個或多個虛擬機器的電腦稱爲主體機器(host machine),這些虛擬機器則稱爲客體機器(guest machine)。hypervisor提供虛擬的做業平臺來執行客體操做系統(guest operating systems),負責管理其餘客體操做系統的執行階段;這些客體操做系統,共同分享虛擬化後的硬件資源。】

  • 在頁面級別,KylinX支持pVM fork和一組用於inter-pVM communication(IpC)的API,它與傳統的UNIX進程間通訊(IPC)兼容。 IpC的安全性經過僅容許從同一個根pVM分叉的相互受信任的pVM之間的IpC獲得保證。
  • 在庫級別,KylinX支持共享庫,動態連接到Unikernel設備,使pVM可以執行(i)在線庫更新,在運行時將舊庫替換爲新庫,以及(ii)重用內存域以進行快速啓動。 咱們分析動態映射引起的潛在威脅並實施相應的限制。

咱們經過修改MiniOS [14](用C編寫的Unikernel LibOS)和Xen'stoolstack實現了基於Xen [30](1型Hypervisor)的KylinX原型。 KylinX能夠在大約1.3毫秒內分配pVM,並在幾毫秒內將庫連接到正在運行的pVM,這二者都與Linux上的進程分支至關(大約1毫秒)。 KylinX IpC的延遲也與UNIX IPC至關。對實際應用程序(包括Redisserver [13]和Web服務器[11])的評估代表,Kylin在保留隔離保證的同時,比靜態Unikernel具備更高的適用性和性能。

本文的其他部分安排以下。 第2節介紹了背景和設計選項。第 3 節介紹了具備安全限制的動態定製的KylinX LibOS的設計 。 第4節報告了KylinX原型實現的評估結果。 第5節介紹相關工做。 第6節總結了論文並討論了將來的工做。

2 背景

2.1 VM ,容器和Picoprocesses

虛擬化和隔離的文獻中有幾種傳統模型:進程,Jails和VM。

  1. OS進程。 進程模型是針對傳統的(部分信任)操做系統環境,並提供豐富的ABI(應用程序二進制接口)和交互性,使得它不適合真正的交付給租戶。
  2. FreeBSD Jails [47]。 jail模型提供了一種輕量級機制來分離應用程序及其相關策略。它在傳統操做系統上運行一個進程,但限制了幾個系統調用接口以減小漏洞。
  3. VMs。 VM模型構建隔離邊界匹配硬件。 它爲guest虛擬機提供了運行完整操做系統的傳統兼容性,但對於重複和殘留的操做系統組件而言,這是很是昂貴的。

虛擬機(圖1(左))已被普遍用於多租戶雲, 由於它保證了強大的(類型-監督)隔離[55]。 可是,VM的當前虛擬化體系結構很是繁重,包括高級Hypervisor,VM,OS內核,進程,語言運行時( 如glibc [16]和JVM [21]),庫和應用程序,它們很複雜,沒法再知足商業雲的效率要求。

容器(如LXC [9]和Docker [15])利用內核功能來打包和隔離進程。他們最近需求量很大[25,7,6],由於與VM相比它們很輕。可是,容器比在隔離性上比VM更弱,所以它們常常在VM中運行以實現適當的安全保障[58]。

【 Docker容器實現原理及容器隔離性踩坑介紹: http://dockone.io/article/8148

Picoprocesses [38](圖1(中))能夠被視爲具備更強隔離性但更輕量級的容器。他們使用主機操做系統和客戶機之間的小型接口來實現LibOS,實現主機ABI並將高級客戶機API映射到小接口。 Picoprocesses特別適合客戶端軟件交付,由於客戶端軟件須要在各類主機硬件和操做系統組合上運行[38]。它們也能夠在hvpervisors上運行【62,32】。

最近對picoprocesses的研究[67,32,54] 經過容許dynamics來從新啓動原始靜態隔離模型。 例如,Graphene [67]支持picoprocess fork和multi-picoprocess API,而Bascule [32]容許OS-independent擴展附加到運行時的picoprocess。 雖然這些鬆弛會稀釋嚴格的隔離模型,但它們有效地將picoprocesses的適用範圍擴展到更普遍的應用範圍。

2.2 Unikernel Appliances

基於進程的虛擬化和隔離技術面臨來自用於與主機操做系統交互的普遍內核系統調用API的挑戰。例如,進程/線程管理,IPC,網絡等.Linux系統調用已達到近400 [3]而且是不斷增長,而且系統調用API比VM的ABI( 能夠利用硬件內存隔離和CPU環) 更難以保護 [58]。

最近,研究人員提出減小VM,而不是增長進程,以實現安全和高效的雲虛擬化。Unikernel [56]專一於單應用程序VM設備[26],並將Exokernel [39]樣式的LibOS應用於VM guest虛擬機,以提升性能優點,同時保留1類虛擬機Hypervisor的強隔離保證。它打破了傳統的通用虛擬化架構(圖1(左)),並將OS功能(例如,設備驅動程序和網絡)實現爲庫。與其餘基於Hypervisor的簡化虛擬機(如Tiny CoreLinux [19]和OS 0 [ 49])相比,Unikernel僅將應用程序及其必需的庫封裝到鏡像中。

【Mark:Exokernel is an operating system kernel developed by the MIT Parallel and Distributed Operating Systems group,[1] and also a class of similar operating systems.

Operating systems generally present hardware resources to applications through high-level abstractions such as (virtual) file systems. The idea behind exokernels is to force as few abstractions as possible on application developers, enabling them to make as many decisions as possible about hardware abstractions.[2] Exokernels are tiny, since functionality is limited to ensuring protection and multiplexing of resources, which is considerably simpler than conventional microkernels' implementation of message passing and monolithic kernels' implementation of high-level abstractions.

Implemented applications are called library operating systems; they may request specific memory addresses, disk blocks, etc. The kernel only ensures that the requested resource is free, and the application is allowed to access it. This low-level hardware access allows the programmer to implement custom abstractions, and omit unnecessary ones, most commonly to improve a program's performance. It also allows programmers to choose what level of abstraction they want, high, or low.

Exokernels can be seen as an application of the end-to-end principle to operating systems, in that they do not force an application program to layer its abstractions on top of other abstractions that were designed with different requirements in mind. For example, in the MIT Exokernel project, the Cheetah web server stores preformatted Internet Protocol packets on the disk, the kernel provides safe access to the disk by preventing unauthorized reading and writing, but how the disk is abstracted is up to the application or the libraries the application uses. https://en.wikipedia.org/wiki/Exokernel*】*

l 【類型I:本地或裸機Hypervisor

l 類型II:Hosted Hypervisor】

因爲Hypervisor已經提供了傳統操做系統的許多管理功能(例如隔離和調度) ,所以Unikernel採用了(minimalism philosophy)極簡主義哲學[36],它不只經過刪除沒必要要的庫並且還從其LibOS中剝離了重複的管理功能來最小化VM。 例如,Mirage[57]遵循多核模型[31]並利用虛擬機Hypervisor進行多核調度,使單線程運行時能夠具備快速的順序性能; MiniOS [14]依賴於Hypervisor( 而不是in-LibOS連接器)來加載/連接設備啓動時間; 而LightVM [58]經過從新設計Xen的控制平面實現了快速VM啓動。

2.3 動機和設計選擇

Unikernel設備和傳統的UNIX進程能夠抽象出隔離,特權和執行狀態的單元,並提供內存映射,執行協做和調度等管理功能。爲了實現低內存佔用和小型計算基礎(TCB),Unikernel剝離了其單片設備的進程抽象,並將簡約LibOS與其目標應用程序相連接,展現了依靠虛擬機Hypervisor消除重複功能的好處。但在缺點方面,進程和編譯時肯定的總體性大大下降了Unikernel的靈活性,效率和適用性。

【TCB是Trusted Computing Base的簡稱,指的是計算機內保護裝置的整體,包括硬件、固件、軟件和負責執行安全策略的組合體。它創建了一個基本的保護環境並提供一個可信計算機系統所要求的附加用戶服務。】

如圖1(右)所示,KylinX經過將虛擬機Hypervisor顯式爲一個OS,而將Unikernel設備做爲進程顯式提供pVM抽象。 KylinX輕鬆放鬆了Unikernel的編譯時單片性要求,容許頁面級和庫級動態映射,這樣pVM就能夠擁有Unikernel設備和UNIX進程的最佳性能。如表1所示,KylinX能夠被視爲對Unikernel的擴展(提供pVM抽象),相似於Graphene [67](提供傳統的多工藝兼容性)和 Bascule [ 32](提供運行時可擴展性)的擴展到picoorocess。

出於如下緣由,咱們在Hypervisor而不是guestLibOS中實現KylinX的動態映射擴展。

  1. 首先,guestLibOS外部的擴展容許Hypervisor強制執行映射限制(第 3.2.3節和第3.3.3節),從而提升安全性。

  2. 其次,Hypervisor更靈活地實現動態管理,例如,在pVM的在線庫更新期間恢復實時狀態(第3.3.2節)。

  3. 第三,KylinX很天然地遵循Unikernel的極簡主義哲學(第2.2章),利用虛擬機Hypervisor來消除重複的客戶LibOS功能。

向後兼容性是另外一種權衡。 最初的Mirage Unikernel [56]佔據了一個極端的位置,現有的應用程序和庫必須在OCaml [10]中徹底重寫,以確保類型安全,這須要大量的工程工做,並可能引入新漏洞。 相比之下,KylinX旨在支持源代碼(主要是C)兼容性,所以能夠在KylinX上運行各類各樣的遺留應用程序,只需最少的調整工做。

威脅模型。 KylinX採用傳統的威脅模型[56,49],與Unikernel相同的上下文[ 56],其中 VM/pVM 在虛擬機Hypervisor上運行,而且有望在公共多租戶雲中提供面向網絡的服務。 咱們假設攻擊者能夠在VM/pVM中運行不受信任的代碼,而且在VM/pVM中運行的應用程序受到來自同一雲中的其餘人和來自經過Internet鏈接的惡意主機的潛在威脅。KylinX將虛擬機Hypervisor(使用其工具堆棧)和控制域(dom0)視爲TCB的一部分,並利用虛擬機Hypervisor隔離其餘租戶的攻擊。使用SSL和SSH等安全協議有助於KylinX pVM對外部實體進行信任。

www.ibm.com/developerwo…

------------------------------------------------------------------------------

Dom0 is the initial domain started by the Xen hypervisor on boot. Dom0 is an abbrevation of "Domain 0" (sometimes written as "domain zero" or the "host domain"). Dom0 is a privileged domain that starts first and manages the DomU unprivileged domains. The Xen hypervisor is not usable without Dom0

A DomU is the counterpart to Dom0; it is an unprivileged domain with (by default) no access to the hardware. It must run a FrontendDriver for multiplexed hardware it wishes to share with other domains. A DomU is started by running

英特爾軟件Guard eXtensions(SGX)[12]等硬件的最新進展證實了屏蔽執行的可行性,並以保護VM/pVM免受特權虛擬機Hypervisor和dom0 [33,28,45]破壞的可行性,這將在咱們將來的工做中進行研究。 咱們還假設硬件設備沒有受到損害,儘管已經肯定了硬件威脅[34]。

3 KylinX 設計

3.1概述

KylinX擴展了Unikernel,以實現之前僅適用於進程的理想功能。咱們不是從零開始設計一個新的LibOS,而是基於MiniOS構建KylinX [27],這是一個在Xen虛擬機Hypervisor上運行的用戶VM域(domU)的C風格Unikernel LibOS. MiniOS 使用其前端驅動程序訪問硬件,鏈接到相應的硬件特權dom0或專用驅動程序域中的後端驅動程序.MiniOS具備單個地址空間,沒有內核和用戶空間分隔,也沒有搶佔的簡單調度程序。 MiniOS很小巧但適合在Xen上採用整潔高效的LibOS設計。 例如,Erlang on Xen [1],LuaJIT [2],C1ickOS [59]和LightVM [58]分別利用MiniOS提供 Erlang,Lua ,Click和快速啓動環境。 【Marked:Xen虛擬化基本原理詳解 blog.51cto.com/wzlinux/172… Mini-OS: wiki.xenproject.org/wiki/Mini-O…

如圖2所示,基於MiniOS的KylinX設計包括(i)DomO中Xen工具堆棧的(受限制的)動態頁面/庫映射擴展,以及(ii)進程抽象支持(包括動態pVMfork/IpC和運行時pVM)庫連接)在DomU。

3.2 動態頁面映射

KylinX經過利用Xen的共享內存和受權表來執行跨域頁面映射,從而支持進程式設備分支和通訊。

3.2.1 pVM Fork

fork API是實現pVM傳統多進程抽象的基礎。 KylinX將每一個用戶域(pVM)視爲一個進程,當應用程序調用fork()時,將生成一個新的pVM。

咱們利用Xen的內存共享機制實現fork操做,它經過 (i)複製xc_dom_image結構 (ii)調用Xen的unpause()API來分叉調用父pVM並將其域ID返回給父級來建立child pVM。

如圖3所示,當在父pVM中調用fork() 時,咱們使用內聯彙編來獲取CPU寄存器的當前狀態並將它們傳遞給子寄存器。控制域(dom0)負責分支和啓動子pVM。 咱們修改libxc以在建立父pVM時將xc_dom_images結構保留在內存中,這樣當調用fork()時,結構能夠直接映射到子pVM的虛擬地址空間,而後父進程可使用受權表與子進程進行共享。以可寫數據以寫時複製(CoW)方式共享。 【Copy-on-write (CoW or COW), sometimes referred to as implicit sharing[1] or shadowing,[2] is a resource-management technique used in computer programming to efficiently implement a "duplicate" or "copy" operation on modifiable resources.[3] If a resource is duplicated but not modified, it is not necessary to create a new resource; the resource can be shared between the copy and the original. Modifications must still create a copy, hence the technique: the copy operation is deferred to the first write. By sharing resources in this way, it is possible to significantly reduce the resource consumption of unmodified copies, while adding a small overhead to resource-modifying operations. 若是資源重複但未修改,則無需建立新資源; 資源能夠在副本和原始文件之間共享。 修改必須仍然建立一個副本,所以技術:複製操做被推遲到第一次寫入。 經過以這種方式共享資源,能夠顯着減小未修改副本的資源消耗,同時爲資源修改操做增長一小部分開銷 en.wikipedia.org/wiki/Copy-o…

經過unpause()啓動子pVM以後,它(i)接受來自其父級的共享頁面,(ii)恢復CPU寄存器並跳轉到fork以後的下一條指令,以及(iii)開始做爲子級運行。在完成fork()以後 ,KylinX異步初始化一個事件通道並在父子pVM之間共享專用頁面以啓用它們的IpC,以下一小節中所介紹的。

3.2.2 inter-pVM通訊(IpC)

KylinX提供了一個多進程(多pVM)應用程序,其全部進程(pVM)都在OS(Hypervisor)上協同運行。目前,KylinX遵循嚴格的隔離模型[67],其中只有相互信任的pVM才能相互通訊,這將在第3.2.3中詳細討論。

兩個通訊pVM使用事件通道共享頁面來實現pVM間通訊。若是兩個相互信任的pVM在第一次通訊時還沒有初始化事件通道,由於它們沒有經過fork()產生的父子關係(3.2.1),那麼KylinX將:

  • 驗證其相互適應性(第3.2.3節,必須是一個family的)
  • 初始化事件通道
  • 在它們之間共享專用頁面。

事件通道用於通知事件,共享頁面用於實現通訊。 KylinX已經實現瞭如下四種類型的inter-pVM通訊API(在表2中列出)。

  • (1)pipe(fd)建立一個管道並返回兩個文件描述符(fd [0]和fd [1]),一個用於寫入,另外一個用於讀取。
  • (2)kill( domid,SIG )經過將SIG寫入共享頁面並通知目標pVM(domid)從該頁面讀取信號,將信號(SIG)發送到另外一個pVM(domid); exit和wait是使用kill實現的。
  • (3) ftok( path,projid)將path和proj id轉換爲IpC密鑰,這將由msgget(key,msgflg)用於建立帶有標誌的消息隊列(msgflg)並返回隊列ID(msgid); msgsend (msgid,msg,len)和msgrcv(msgid,msg,len)使用長度len寫入/讀取隊列(msgid)到/來自msmbuf結構(msg)。
  • (4)shmget(key,size,shmflg)使用鍵(key),內存大小(size)和flag(shmflg)建立並存儲一個內存區域,並返回共享內存區域ID(shmid),它能夠附加和分離到shmat(shmid,shmaddr,shmflg)和shmdt(shmaddr)。

3.2.3 動態頁面映射限制

在執行動態pVM fork時,父pVM將頁面分享給空的子pVM ,該過程不會引入新的威脅。

在執行IpC時,KylinX經過抽象相互信任的pVM 來保證安全性,這些pVM是從同一個根pVM分叉的。例如,若是pVM A分支pVM B,它進一步分叉另外一個pVM C,那麼三個pVM A,B和C屬於同一個家庭。爲簡單起見,目前KylinX遵循all-all-nothing隔離模型:只有屬於同一系列的pVM才被認爲是可信的而且容許彼此通訊。 KylinX拒毫不受信任的pVM之間的通訊請求。

3.3 動態庫映射

3.3.1 pVM庫連接

繼承自MiniOS,KylinX具備單個平面虛擬存儲器地址空間,其中應用程序二進制和庫,系統庫(用於引導程序,內存分配等)和數據結構共同定位以運行。 KylinX將一個動態段加入MiniOS的原始內存佈局中,以便在加載後適應動態庫。

如圖2所示,咱們在Xen控件庫(libxc)中實現了動態庫映射機制,它由上層工具棧使用,例如xm/xl/chaos。 pVM其實是一個準虛擬化domU,它

  • 建立一個域,
  • 解析kernel image文件
  • 初始化啓動內存,
  • 在內存中構建映像
  • 啓動映像的domU。

在上面的第4步中,咱們經過擴展libxc的靜態連接過程,添加一個函數(xc_dom_map_dyn())來將共享庫映射到動態段中,以下所示。

  1. 首先 ,KylinX從設備映像的程序頭表中讀取共享庫的地址,偏移量,文件大小和內存大小。
  2. 第二 ,它驗證是否知足限制(第3.3.4節KylinX強制限制庫的身份以及庫的加載器)。 若是不是,則程序終止。
  3. 第三 ,對於每一個動態庫,KylinX檢索其 動態部分的信息,包括動態字符串表,符號表等。
  4. 第四 ,KylinX將整個依賴樹中的全部必需庫映射到pVM的動態段,當實際訪問時,它將惰性地將未解析的符號重定位到正確的虛擬地址。
  5. 最後 ,它跳轉到pVM的入口點。

KylinX在實際使用以前不會加載/連接共享庫,這相似於傳統進程的延遲綁定[ 17]。所以,KylinX pVM的啓動時間低於之前的Unikernel VM。 此外,與以前僅支持靜態庫的Unikernel相比,使用共享庫的KylinX的另外一個優點是它有效地減小了高密度部署中的內存佔用(例如,LightVM [58]中的每臺機器8K VM和每臺機器80K容器)在Flurries [71]中,這是限制可擴展性和性能的惟一最大因素[58]。

【Mark:動態連接和延遲綁定:www.jianshu.com/p/20faf72e0…

接下來,咱們 將討論KylinX AVM的動態庫映射的兩個簡單應用。

3.3.2 在線 pVM庫更新 保持系統/應用程序庫的最新版本以修復錯誤和漏洞很是重要。 靜態Unikernel [56]必須從新編譯並從新啓動整個設備映像才能爲其每一個庫應用更新 ,這可能會致使設備擁有許多第三方庫時出現大量部署負擔。

在線庫更新比滾動啓動更有吸引力,主要是保持與客戶端的鏈接。首先,當服務器有許多長期鏈接時,從新啓動將致使高從新鏈接開銷。其次,不肯定第三方客戶端是否會從新創建鏈接,這會在從新啓動後爲從新鏈接施加複雜的設計邏輯。第三,頻繁重啓和從新鏈接可能會嚴重下降關鍵應用程序的性能,如高頻交易。

動態映射使KylinX能夠實如今線庫更新。 可是,庫可能有本身的狀態,例如壓縮或加密,所以簡單地替換無狀態函數不能知足KylinX的要求。

像大多數庫更新機制(包括DYMOS [51],Ksplice [29],Ginseng [61],PoLUS [37 ],Katana [63],Kitsune [41]等),KylinX要求新舊庫與二進制兼容:容許向庫中添加新函數和變量,但不容許更改函數接口,刪除函數/變量或更改結構字段。對於庫狀態,咱們指望全部狀態都存儲爲在更新期間將被保存和恢復的變量(或動態分配的結構)。

KylinX提供了更新(domid,new_lib,old_lib)API,能夠動態地將old_lib和new_lib替換爲domU pVM(ID = domid),並具備必要的庫狀態更新。 咱們還提供了一個更新命令「update domid,new_lib,old_lib」 用於解析參數並調用update() API。

動態pVM更新的難點在於在密封的VM設備中操做符號表。 咱們利用dom0來解決這個問題。 當調用更新API時,dom0將 (i)將新庫映射到dom0的虛擬地址空間; (ii)與domU共享裝載的庫; (iii)經過要求domU檢查domU的每一個內核線程的調用堆棧來驗證舊庫是否靜止; (iv)等到舊庫未被使用並暫停執行; (v)將受影響的符號條目修改成適當的地址; 最後 (vi)釋放舊庫。 在上述第五步中,有兩種符號(函數和變量)將以下所述進行解析。

函數。 函數的動態解析過程如圖4所示。咱們將重定位表,符號表和字符串表保存在dom0中,由於它們不在可加載段中。 咱們在dom0中加載全局偏移表函數(.got.plt )和過程連接表(.plt)並與domU共享它們。 爲了在不一樣的域中解析符號,咱們在.plt 表的第1st個條目中修改了2nd的彙編行 (如圖4中的藍色區域所示),以指向KylinX的符號解析函數(du_resolve)。 在加載新的庫(new_lib)以後,將old_lib中的每一個函數輸入 .got.plt表(例如,圖4中的foo)被修改成指向.plt表中的相應條目,即圖4中虛線綠線所示的2nd組件(push n)。當一個函數(在new_lib加載後第一次調用庫的foo),將使用兩個參數( n (got + 4)) 調用du_resolve ,其中n是.got.plt表中符號(foo)的偏移量和(got+ 4)是當前模塊的ID。 而後du_resolve要求dom0調用對應的d0_resolve,它在new_lib中找到foo,並將當前模塊的gt.plt表中的相應條目(由n定位)更新爲foo的正確地址(圖中的藍線) 4)。

變量。 變量的動態分辨率略微複雜。 目前咱們只是假設new_libexpect將其全部變量設置爲它們的實時狀態inold_lib而不是它們的初始值。 若是沒有這個限制,編譯器將須要擴展以容許開發人員爲每一個變量指定他們的意圖。

(1)全局變量。 若是在主程序中訪問了庫的全局變量(g),則g存儲在程序的數據段 (.bss )中,而且在指向g的庫的全局偏移表(.got)中存在條目,所以加載new_lib後,KylinX會將new_lib的.got表中的g條目解析爲g的正確地址。 不然,g存儲在庫的數據段中,所以KylinX負責將全局變量g從old_lib複製到new_lib。

(2)靜態變量。 因爲靜態變量存儲在庫的數據段中而且沒法從外部訪問,所以在加載new_1 ib以後,KylinX將簡單地將它們從old_lib逐個複製到new_lib。

(3)指針。 若是庫指針(p)指向動態分配的結構,那麼KylinX會預先設置結構並將new_lib中的p設置爲它。 若是p指向存儲在程序數據段中的全局變量,那麼p將從old_lib複製到new_lib。 若是指向靜態變量(或存儲在庫中的全局變量),則p將指向新地址。

3.3.3 pVM 回收

KylinX pVM和Unikernel VM [58]的標準啓動(第3.3.1節)相對較慢。 正如評估的第4章所述,啓動pVM或UnikernelVM須要100多毫秒,大部分時間用於建立空域。 所以,咱們爲KylinX pVM設計了一個pVM回收機制,利用動態庫映射來繞過域建立。

回收的基本思想是重用一個內存空域來動態地將應用程序(做爲共享庫)映射到該域。 具體來講,在調用佔位符動態庫的app_entry函數以前,會檢查一個空的可回收的域並等待運行應用程序。使用app_entry做爲條目,將應用程序編譯爲共享庫而不是可引導映像。爲了加速應用程序的pVM引導,KylinX恢復了被檢查的域,並經過在在線更新過程以後替換佔位符庫來連接應用程序庫(第3.3.2節)。

3.3.4 動態庫映射限制

與執行動態庫映射時靜態和單片密封的Unikernel相比,KylinX應該隔離任何新的漏洞。 主要的威脅是攻擊者可能會將惡意庫加載到pVM的地址空間,用具備相同名稱和符號的受損庫替換庫,或者將共享庫的符號表中的條目修改成僞符號/函數。

***【Linux進程地址空間學習: ***

http://www.choudan.net/2013/10/24/Linux%E8%BF%9B%E7%A8%8B%E5%9C%B0%E5%9D%80%E7%A9%BA%E9%97%B4%E5%AD%A6%E4%B9%A0***(%E4%B8%80).html******】***

爲了解決這些威脅,KylinX強制限制庫的身份以及庫的加載器。 KylinX支持開發人員指定動態庫的簽名,版本和加載器的限制,這些限制存儲在pVM映像的標頭中,並在連接庫以前進行驗證。

**簽名和版本。**庫開發人員首先生成庫的SHA1摘要,該摘要將由RSA(Rivest-Shamir-Adleman)加密。 結果保存在動態庫的asignature部分中。 若是設備須要對庫進行簽名驗證,則KylinX將使用公鑰讀取並驗證簽名部分。一樣要求並驗證版本限制。

裝載機。 開發人員能夠在庫的加載器上請求不一樣級別的限制:(i)僅容許pVM自己做爲加載器; (ii)還容許同一申請的其餘pVM; 或(iii)甚至容許其餘應用程序的pVM。 經過前兩個限制,一個受損應用程序中的惡意庫不會影響其餘應用程序。 加載程序檢查的另外一種狀況是將應用程序二進制文件做爲庫並將其連接到pVM以進行快速回收(第3.3.3節),其中KylinX將加載程序限制爲空pVM。

有了這些限制,與靜態密封的Unikernel相比,KylinX沒有引入任何新的威脅。 例如,pVM的運行時庫更新(第3.3.2節)對簽名(做爲可信開發人員 ),版本 (做爲特定版本號)和加載器(做爲pVM自己)具備限制,將具備相同的級別安全保障從新編譯和從新啓動。

4 評估

咱們在Ubuntu 16.04和Xen上實現了KylinX的原型。 按照MiniOS [14]的默認設置,咱們分別使用RedHat Newlib和1wIP做爲libc/libm庫和TCP/IP堆棧。咱們的試驗檯有兩臺機器,每臺機器都配有Intel 6 core Xeon ES-2640 CPU,128 GB RAM和一臺1 Gb ENIC。

咱們已經向KylinX移植了一些應用程序,其中咱們將使用多進程Redis服務器[13]以及多線程Web服務器[11]在4.6章中來評估KylinX的應用程序性能。 因爲MiniOS和RedHat Newlib的限制,目前須要進行兩種調整才能將應用程序移植到KylinX。 首先,KylinX只能支持select而不是更高效的epoll。 其次,進程間通訊(IPC)僅限於表2中列出的API。

4.1 標準啓動

咱們評估 KylinX pVM 的標準啓動過程( 3.3.1)的時間,並將其與全部運行Redis服務器的MiniOS VM和Docker容器進行比較。 Redis是一個內存中的鍵值存儲,支持快速鍵值存儲/查詢。 每一個鍵值對由固定長度鍵和可變長度值組成。它使用單線程進程來提供用戶請求,並經過分配新的備份過程來實現(按期)序列化。

咱們禁用Xen Store日誌記錄以消除按期日誌文件刷新的干擾。RedHat Newlib的C庫(libc)在嵌入式系統中是靜態的,很難轉換爲共享庫。簡單來講,咱們將libc編譯成靜態庫和libyn( Newlib的數學庫)到一個共享庫中,該庫將在運行時連接到KylinX pVM。因爲Mini不能支持fork,咱們(暫時)刪除此實驗中的相應代碼。

啓動單個KylinX pVM大約須要124毫秒,能夠大體分爲兩個階段,即在內存中建立域/映像(步驟1~4,第3.2.1節),以及引導映像(步驟5)。動態映射在第一階段執行。大多數 時間(大約121毫秒)花費在第一階段,這會調用高級調用來與Hypervisor進行交互。第二階段啓動pVM大約須要3毫秒。在此相反,MiniOS大約須要133毫秒啓動一個虛擬機,而Docker 須要花費約210毫秒開始創建容器。 KylinX比MiniOS花費的時間更短,主要是由於在引導期間不會讀取/連接共享庫。

而後,咱們評估在一臺機器上順序啓動大量(最多1K)pVM的總時間。咱們還評估了MiniOS VM和Docker容器的總啓動時間,以便進行比較。

結果如圖5所示。首先,因爲延遲加載/連接,KylinX比MiniOS快得多。其次,MiniOS和KylinX的啓動時間隨着VM/pVM數量的增長而線性增長,而Docker容器的啓動時間只是線性增長,這主要是由於XenStore在服務大量的VM/pVM時效率很低。

4.2 fork和回收

與容器相比,因爲XenStore效率很高,KylinX的標準啓動沒法很好地擴展到大量pVM。最近,LightVM [58]經過實現chaos/libchaos,noxs(無XenStore)和拆分工具堆棧以及許多其餘優化來徹底從新設計Xen的控制平面,從而實現大量VM的ms級啓動時間。咱們採用LightVM的nox來消除XenStore的影響,並測試運行未經修改的Redis仿真傳統進程分支的pVM fork機制。 LightVM的noxs使KylinX pVM的啓動時間即便對於大量pVM也能線性增長。單個pVM的fork大約須要1.3毫秒(未顯示缺乏空間),比LightVM的原始啓動過程快幾倍(約4.5毫秒)。KylinX pVM 的fork比 Ubuntu上的進程fork(大約1 ms)略慢,由於包括頁面共享和參數傳遞在內的多個操做很是耗時。請注意,父/子pVM的事件通道和共享頁的初始化是異步執行的,所以不計入fork的延遲。

4.3 內存佔用

咱們在一臺機器上測量不一樣數量的pVM/VM/容器的KylinX,MiniOS和Docker(Running Redis)的內存佔用量。結果(如圖6所示)證實,與靜態密封的MiniOS和Docker容器相比,KylinX pVM具備更小的存儲空間。這是由於KylinX容許同一個應用程序( 第3.3章) 的全部設備共享庫(libc除外),所以共享庫最多須要加載一次。內存佔用優點促進了虛擬化[42],可用於在VM設備之間動態共享物理內存,並使KylinX可以實現與頁面級重複數據刪除[40]至關的內存效率,同時下降複雜性。

4.4 Inter-pVM通訊

咱們經過分配父pVM並測量父/子通訊延遲來評估pVM間通訊(IpC)的性能。咱們將一對父/子pVM稱爲線性pVM。正如引言第3.2.1節所述,兩個線性pVM已經有一個事件通道共享頁面,所以它們能夠直接與其餘頁面進行通訊。相反,非線性pVM對必須在第一次通訊以前初始化事件通道和共享頁面。

結果列於表3中,咱們將其與Ubuntu上相應的IPC進行比較。因爲Xen的高性能事件通道和共享內存機制,兩個線性pVM之間的KylinX IpC延遲與Ubuntu上相應的IPC延遲至關。請注意,pipe的延遲不只包括建立管道,還包括經過管道寫入和讀取值。因爲初始化成本的緣由,非線性pVM之間的首次通訊延遲要高出幾倍。

4.5 運行時庫更新 咱們經過使用較新版本(RedHat Newlib 1.18)動態替換默認libyn(RedHat Newlib 1.16)來評估KylinX的運行時庫更新。libyn是MiniOS / KylinX使用的數學庫,包含110個基本數學函數的集合。

爲了測試KylinX對全局變量的更新過程,咱們還向舊的和新的libyn庫添加了111個僞全局變量以及一個read_global函數(讀出全部全局變量)。主函數首先將全局變量設置爲隨機值,而後經過調用讀取全局函數按期驗證這些變量。

所以,在咱們的測試中總共有111個函數和111個變量須要更新。更新程序大體可分爲 4個階段,咱們測量每一個階段的執行時間。

首先,KylinX將new_lib加載到dom0的內存中並與domU共享。其次,KylinX修改.got.plt表中函數的相關條目,以指向.plt表中的相應條目。 第三,KylinX 爲每一個函數調用du_resolve,這些函數要求dom0解析給定的函數並返回其在new_lib中的地址,而後將相應的條目更新爲返回的地址。最後,KylinX將新lib的.got表中的全局變量的相應條目解析爲適當的地址。咱們在評估中修改第三階段,一次更新libyn中的全部111個函數,而不是在實際被調用時懶惰地連接函數(第3.3.2節),以便概述libyn的整個運行時更新成本。

結果如圖7所示,其中更新全部函數和變量的總開銷約爲5毫秒。第三階段(解析函數)的開銷高於其餘階段,包括第四階段(解析變量),這是由第三階段中的幾個耗時的操做引發的,包括解析符號,跨域調用d0_ resolve,返回實際函數地址和更新相應的條目。

4.6 申請

除了pVM調度和管理的流程靈活性和效率以外,KylinX還爲其容納的應用程序提供了高性能,與Ubuntu上的對應應用程序至關,如本小節所述。

4.6.1 Redis 服務器應用程序

咱們在KylinX pVM中評估Redis服務器的性能,並將其與MiniOS/Ubuntu中的性能進行比較。一樣,因爲MiniOS不支持fork(),咱們暫時刪除了序列化代碼。 Redis服務器使用select而不是epoll來實現異步I/O,由於 MiniOS和KylinX使用的lwIP堆棧[4]尚不支持epoll。

咱們使用Redis基準[13]來評估性能,該性能使用可配置數量的繁忙循環來異步寫入KV。咱們爲客戶端的寫請求運行不一樣數量的pVM/VM/進程(1個服務器一個)。咱們測量寫入吞吐量做爲服務器數量的函數(圖8)。三種Redis服務器具備類似的寫入吞吐量(因爲選擇的限制),隨着併發服務器的數量幾乎線性增長(在lwIP堆棧成爲瓶頸以前,縮放是線性的,最多8個實例)。

4.6.2 Web 服務器應用程序

咱們評估了KylinX中的JOS Web服務器[11],它爲多個鏈接提供多線程處理。主線程接受傳入鏈接後,Web服務器建立工做線程來解析標頭,讀取文件,並將內容發送回客戶端。咱們使用Weighttp基準測試來支持HTTP協議的一小部分(但對咱們的Web服務器來講足夠)來衡量Web服務器性能。與Redis服務器的評估相似,咱們經過在一臺計算機上運行多個Weighttp [8]客戶端來測試Web服務器,每一個客戶端不斷向Web服務器發送GET請求。

咱們將吞吐量做爲併發客戶端數量的函數進行評估,並將其與分別在MiniOS和Ubuntu上運行的Web服務器進行比較。結果如圖9所示,其中KylinX web服務器實現了比MiniOS web服務器更高的吞吐量,由於它提供更高的順序性能。KylinX和MiniOS Web服務器都比Ubuntu Web服務器慢,由於異步選擇是使用MiniOS的網絡驅動程序[27}進行低效調度的。

5 相關工做

KylinX與靜態Unikernel設備[56,27 ],減小 VM [ 19,48,49 ],容器[66,9,15]和圖像處理[38,62,32,54,67,33]有關。

5.1 Unikernel 和Redced VMs

KylinX是Unikernel[56]的擴展,在MiniOS [27]之上實現。Unikernel OS包括Mirage [56],Jitsu [55],Unikraft [18]等。 例如,Jitsu [55]利用Mirage [56]設計一個功能強大且響應迅速的平臺,用於在邊緣網絡中託管雲服務。LightVM [58]利用Xen上的Unikernel來實現快速啓動。

MiniOS [27]設計並實現了一個C風格的Unikernel LibOS,它做爲Xen域中的半虛擬客戶OS運行。MiniOS具備比Mirage更好的向後兼容性,並支持用C語言編寫的單進程應用程序。可是,最初的MiniOS靜態密封設備而且遇到與其餘靜態Unikernel類似的問題。

KylinX和靜態 Unikernels( 如Mirage [56],MiniOS [27]和EbbRT [65])之間的區別在於pVM抽象,它明確地將hypervisoras做爲操做系統並支持過程式操做,如pVM fork/IpC和動態庫映射。映射限制(第3.3.4節)使KylinX儘量地引入漏洞,而且沒有比 Mirage/MiniOS 更大的TCB [56,55]。 KylinX支持源代碼(C)兼容性,而不是使用類型安全的語言來重寫整個軟件堆棧[56]。

最近的研究 [19,49,48]試圖改進基於Hypervisor的類型1虛擬機,以實現更小的內存佔用,更短的啓動時間和更高的執行性能。 Tiny Core Linux [19]儘量減小現有的Linux發行版,以減小客戶的開銷。 0S0 [49]實現了一個新的客戶操做系統,用於在VM上運行單個應用程序,解析對其內核的libc函數調用,該內核採用優化技術,如spinlock-freemutex [70]和網絡通道網絡堆棧[46 ] .RumpKernel [48]經過實現優化的客戶操做系統來減小VM。與KylinX不一樣,這些通用LibOS設計包含針對目標應用的沒必要要的特徵,致使更大的攻擊面。它們不支持多進程抽象。此外,KylinX的pVM fork比SnowFlock中基於重複的VM_fork要快得多[50]。

5.2 容器

容器使用操做系統級虛擬化[66]和利用內核功能來打包和隔離進程,而不是依賴於虛擬機Hypervisor。做爲回報,他們不須要捕獲系統調用或模擬硬件,而且能夠做爲正常的OS進程運行。例如,Linux Containers(LXC)[9]和Docker [15]經過使用許多Linux內核功能(例如naynespaces和cgroups)來建立容器,以打包資源並運行基於容器的進程。

容器須要使用相同的主機操做系統API [49],從而暴露數百個系統調用並擴大主機的攻擊面。所以,儘管LXC和Docker容器一般比傳統VM更有效,但它們提供的安全性較低,由於攻擊者可能會破壞容器內運行的進程。

5.3 Picoprocess

picoprocess本質上是一個容器,它在主機操做系統和客戶機之間實現LibOS,將高級客戶機API映射到一個小接口上。原始的picoprocess設計(Xax [38]和Embassies [43])只容許一個微小的系統調用API ,它能夠小到使人信服(甚至能夠證明)的孤立。 Howell等。經過提供POSIX 仿真層並綁定現有程序,展現如何在最小的picoprocess接口[44]之上支持一小組單進程應用程序。

最近的研究放鬆了靜態和剛性微過程隔離模型。。例如,Drawbridge [62]是Xax [38] picoprocess的WinBows轉換,並建立了支持豐富桌面應用程序的picoprocess LibOS。 Graphene [67]擴展了LibOS範式,支持在picoprocesses的一個家族(沙箱)中使用多進程API(使用消息傳遞)。 Bascule [ 32]容許 在運行時安全有效地附加與OS無關的擴展。 Tardigrade [54]使用picoprocesses輕鬆構建容錯服務。這些鬆弛在picoprocess上的成功激發了咱們對Unikernel的動態KylinX擴展。

容器和picoprocesses一般具備大的TCB,由於LibOS包含未使用的功能。相比之下,KylinX和其餘Unikernel利用虛擬機Hypervisor的虛擬硬件抽象來簡化它們的實現,並遵循極簡主義[36]僅將應用程序與必需的庫相結合,不只提升了效率,還提升了安全性。

Dune [34]利用Intel VT-x [69]提供進程(而不是機器)抽象來隔離進程並訪問特權硬件功能。IX [ 35]將 虛擬設備整合到Dune過程模式中,爲網絡系統實現了高吞吐量和低延遲。1wCs [53]在進程內提供獨立的保護,特權和執行狀態單元。

與這些技術相比,KylinX直接運行Xen(1型虛擬機Hypervisor),天然提供強大的隔離,使KylinX可以專一於靈活性和效率問題。

6 結論

在雲虛擬化的文獻中,長期存在強烈孤立和豐富特徵之間的緊張關係。本文利用新的設計空間,經過在高度專用的靜態Unikernel中添加兩個新特性(動態頁面和庫映射)來提出pVM抽象。簡化的虛擬化架構(KylinX)將虛擬機Hypervisor做爲OS,並安全地支持靈活的進程式操做,例如pVM fork和inter-pVM通訊,運行時更新和快速回收。

在將來,咱們將經過模塊化[27],分解[60]和新交所飛地[33,28,45,68] 來提升安全性。咱們將經過採用更高效的運行時MUSL來改善KylinX的性能[23],並使KylinX適應Multi LibOS model [65],容許將pVM跨越多個機器。目前,pVM的回收機制仍是暫時的和有條件的:它只能檢查點的空域; 循環的pVM沒法使用事件通道或共享內存與其餘pVM通訊; 應用程序只能採用自包含共享庫的形式,不須要加載其餘共享庫; 回收後,新老pVM之間仍然沒有檢查潛在安全威脅的保障措施。咱們將在將來的工做中解決這些缺點。

7 致謝

這項工做獲得了中國國家基礎研究計劃(2014CB340303)和國家天然科學基金(61772541)的支持。Wethank Li Ziyang Li,Qiao Zhou和匿名評論員幫助他們完善了本文。這項工做是在第一做者訪問劍橋大學計算機實驗室的NetOS小組時進行的,咱們感謝Anil Madhavapeddy 教授,Ripduman Sohan和劉浩的討論。

正文以後

搞掂,但願有用吧。。這些新點的文章網絡上屁內容都沒得,國防科技大學的老師也沒得對外的聯繫方式,因此說,選了這篇文章作彙報的同窗,加油~

相關文章
相關標籤/搜索