【閱讀總結——更新中】Xen and the Art of Virtualization

這兩天終於看完了Xen,開始整理筆記到博客上來,並做做總結,過兩天再去實踐一下Xen。才疏學淺,如果理解有誤,請大家不吝賜教。

本文的翻譯找到地址如下,希望本人對文章的閱讀消化能夠幫助到大家的理解:
https://www.hackhome.com/InfoView/Article_113992.html

0. 本文關鍵名詞解釋

VMM -> Virtual Machine Monitor,虛擬機監視器。

Xen -> 即是整體架構中的hypervisor,相較於GuestOS有最高權限。

Guest OS -> 指要運行到VMM之上的OS。
Domain -> Xen中的一個運行中的操作系統。
GuestOS和Domain的關係就像Program和Process關係一樣。

UML:User Mode Linux,虛擬化水平性能測試的關鍵,測試用戶態下程序跑的咋樣。

1. Prequisites知識、概念總結

  這裏對文中的一些Prerequisites知識進行總結,包含名詞,傳統方法等,這裏結合我自己的理解記錄如下:

  • Q:什麼叫做VMM,什麼又是hypervisor
    A:VMM全稱叫做Virtual Machine Monitor,我們以前直接叫VMware這樣的軟件爲虛擬機,在語義上實際上是不太對的,也應該叫做VMM纔對,它作爲硬件和操作系統的中介,其實是衆多虛擬機的一個監控。

  • Q:什麼是全虛擬化(Full Virtualization),半虛擬化(Para Virtualization),與現在DevOps所流行的Docker,LXC(Linux Container)有什麼區別?
    A:三種虛擬化方式的不同在於其虛擬化工作所屬層次、虛擬化的泛化力度等方面,簡述如下:

    1. 全虛擬化的目的在於完全在硬件層以上建立VMM,大規模兼容操作系統,即可以當VMM不存在,安裝虛擬機。
    2. 半虛擬化會儘可能的以較低修改代價來**遷移(port)**原有操作系統到VMM上,以支持更優的性能。
    3. 類Docker技術,處於操作系統層的虛擬化,進程級的輕量虛擬化技術,採用cgroup控制資源和namespace控制命名空間隔離進程,爲內核所提供的支持。
  • Q:什麼是crosstalk
    A:Crosstalk發生在多個實體(進線程,網絡請求)爭奪資源時產生的服務性能(QoS,Quality of Service)無法保障的問題,所以crosstalk通常與QoS寫在一起,叫QoS crosstalk
      從應用層軟件來看,例如網絡服務器在接收到大量請求後,如何保證每個客戶端得到了應得的響應性能?如果無法拆分整合這些流或請求(從web角度來看,不結合業務肯定較難),這裏便需要合適的調度算法對請求排序,優化多路複用。Web服務器未響應某些請求事小,但是在VMM這裏就是大問題,因爲服務對象是OS。參考:https://www.cl.cam.ac.uk/research/srg/netos/projects/archive/pegasus/papers/jsac-jun97/node4.html

  • Q:全虛擬化如何實現?半虛擬化如何實現?
    A:全虛擬化包括軟件輔助硬件輔助兩個方面,下圖是軟件輔助下的全虛擬化,VMM會將本來操作系統內核所要執行的權限下的指令(需要陷入內核執行的代碼)全都捕捉,然後再向下請求。
      爲了實現全虛擬化所應該具有的泛化能力,基於軟件輔助的VMM會拆解很多指令,即換爲元指令的組合。所以全虛擬化的工作壓力應該主要在於學習各個操作系統的特權指令,然後用元指令替換。
    PS:我們常用的VMware就是如此。
    在這裏插入圖片描述
      硬件輔助下的全虛擬化如下圖所示:可以看出來HostOS不再需要,VMM成爲了HostOS。區別在於VMM在硬件支持下可以直接將特權指令進行執行。這裏可以想象一個VMM的設計,可以用一個HostOS加上支持虛擬化的內核模塊,便成爲了VMM。這樣的VMM的代表性技術就是KVM(kernel based virtual machine)虛擬機,知道了它的實現方案,即可顧名思義。
    在這裏插入圖片描述
      半虛擬化的結構會對VMM進行功能的擴充,VMM會更加的像一個元操作系統,擁有更多的功能,同時它也需要對GuestOS進行修改,實現設計目的,Xen就是一個半虛擬化的成果。對於它的架構可以參考Xen架構圖,Xen虛擬了CPU,內存,磁盤網絡模塊,建立了一個高級的OS。
    在這裏插入圖片描述

  • Q:x86架構由於本身設計並未太多考慮虛擬化的功能,留下了哪些坑?
    A:本文發佈時,x86架構中的一些特權指令允許在Ring1下執行,導致在全虛擬化環境下的VMM難以捕捉這樣的指令。後續有一些方法通過掃描GuestOS的二進制代碼,強行捕獲特權指令並翻譯執行。
      VMware爲了解決這個問題,就用了動態插入trap進行了解決,GuestOS也要進行相關修改。VMware在這樣的狀況下,更新操作會有很多開銷,如更新頁表,創建進程。

  • Q:什麼是scatter gather DMA?
    A:首先DMA(Direct memory access)都很熟悉了,龜速的外設和高速的CPU,爲了不要總是麻煩CPU處理外設的消息讀入內存的問題,外設上通常也加了一個類-cpu的東西,用於將數據直接傳給內存頁。scatter指分散,gather指收集,對於內存頁等存儲單位上不連續的信息所造成多次訪問的問題,爲了提高IO效率,提出了scatter gather DMA技術。查到一篇資料如下:
    How Does Scatter/Gather Work?: https://www.eejournal.com/article/20170209-scatter-gather/

  • Q:什麼叫做differentiated service?
    A:直接翻譯是差異化服務,在VMM當中大概是指與調度相關的工作,通過對服務進行分類、整合、限制的策略,最終提升QoS。

  • Q:VMM本身的作用是什麼?
    A: 1)加強服務器能力,2)提供同節點部署的優勢(幾乎localhost下的消息傳遞當然高於分佈式),3)分佈式的仿真實現,4)安全的計算平臺(沙盒),5)應用的portable

  • Q:VMM面臨什麼挑戰?
    A:1)獨立性挑戰(避免一個OS影響了全部),2)不同操作系統,異構應用的共存,3)虛擬化低開銷的實現

  • Q:一定要虛擬化OS嗎?在一臺OS上嘗試運行各種應用不行嗎?
    A:虛擬化的作用的不用說,巨大的配置量和複雜的軟件關係,portable不會滿足,更不必說應用之間資源分配,調度管理。如果類似網格計算等計算單元之間沒有利益衝突的應用場景,那麼虛擬化的必要還真就沒有了。

  • Q:當下的容器技術如Docker不能幹掉虛擬機嗎?
    A:目前容器技術已經實現了資源隔離,在其目前存在的安全問題被解決之後或許可以幹掉虛擬機。但是,容器間同樣會發生的crosstalk問題,這類問題最好是在底層解決,比如,多個容器間的確設置了資源使用限制,實現了隔離,但是考慮到性能,底層的指令排序及CPU調度和大量的上下文切換帶來的多餘開銷上層或許不可見。
      此外,兩種技術的設計方向其實也不一樣,LXC偏向於Devops的簡潔性,向軟件工程向微服務架構的發展,容器本身仍然只是一個進程,當容器內部需要加入更多的軟件,容器間需要更方便的調試時,或許還是虛擬機方便點。此外還有一點,Docker可以繼續運行在虛擬機之上~。
      對於這個問題,我覺得像是OS地址空間同時存在段劃分和頁劃分一樣。大集裝箱和小集裝箱一樣,這兩個技術並不是零和博弈。

2. 現有的虛擬化技術特點,Xen的不同

  本文提到現有的虛擬化技術的不足也就是虛擬化要解決的問題,優勢與問題如下所示:

  • 虛擬化技術需要特別的硬件支持。(這個弱點顯而易見,應用層軟件都有前後端分離,這個是軟硬端,必須解決)
  • 需要定製化的操作系統,商業操作系統支持程度不夠
  • 速度快而安全性或功能性不能得到滿足
  • 少數的虛擬化技術實現了資源隔離與性能保障,資源分配上做文章的方法很多

  Xen通過對底層資源抽象,接收上層虛擬OS進程的二進制接口執行。其成績達到了無性能、功能損失,商業OS如Linux,Xp,BSD都可以共存。實現100個OS同時運行,幾乎可忽略的虛擬化開銷,和與其它VMM技術在Benchmark上的性能突出對比。Xen特點總結如下:

  • GuestOS 的 ABI(Application Binary Interface)不用修改。
  • 全/多應用的操作系統
  • 實現了OS間資源隔離,在x86架構下
  • 完全隱藏了資源虛擬化面臨的正確性和性能威脅。

  與Denali項目的區別:

  1. Denali實現的是在單用戶單應用且處於特權態下的操作系統,Virtual MMU的實現或許可以幫助Denali改善這些弱點,但是當時還沒有Virtual MMU成果。
  2. Denali使用VMM進行了所有的頁管理,Xen認爲,GuestOS應該可以獨立處理自己的內存頁,管理自己的信息。
  3. Denali建立了namespace,不再namespace之內的OS不可以互相訪問,VM見到的都是虛擬出來的東西。Xen認爲hypervisor已經足夠做了安全檢查的工作,讓物理設備可被GuestOS訪問具有更多益處。

3. x86架構下的半虛擬化接口設計

  本節從宏觀概括的角度敘述Xen整體設計。

3.0 概述

  1. 內存方面:Xen對Guest OS的地址空間採取了分段操作,底層爲Xen獨享,然後是GuestOS的內核層,然後是Guest用戶空間。

    • 分段:GuestOS 不可以擁有全部權限的段標記符
    • 分頁:GuestOS允許看到硬件頁表,但是不可以直接更新頁表項。一個Domain擁有的頁空間不一定連續。這裏其實是又一層抽象,操作系統本身通過虛擬地址欺騙進線程,進線程陷入內核態更新頁表。這裏變成了VMM欺騙GuestOS。
  2. CPU方面:

    • 保護:Guest OS優先級低於Xen(Ring X)。
    • 異常:Guest OS需要註冊Exception Handler到Xen中,缺頁中斷除外。(前面所述Xen的設計讓GuestOS有管理內存的功能不被刪除)。
    • 系統調用:允許Guest OS專門裝一個handler處理系統調用,避免過多地通過Xen傳遞。
    • 中斷:Guest OS對各個設備等的中斷處理轉化爲由Xen的事件通知。
    • 時間與計時:GuestOS擁有timer接口,可以主動意識到真實時間和虛擬時間。
  3. Device IO方面:指磁盤網絡等的傳輸

    • Xen採用異步IO環向各個Domain傳輸數據,異步IO環可見後續的具體實現 IO Rings。
    • 事件機制代替設備中斷。

3.1 內存管理

  Xen內存管理需要hypervisor和Guest共同進行修改。由於x86架構下使用了硬件支持下的TLB,CPU會主動檢查TLB上頁表信息,相較於軟件輔助下的TLB可以對TLB項進行標記所屬,基於硬件輔助的TLB在操作系統的上下文切換會不太方便。所以爲了保障內存管理正確性,有兩個基本要求:

  1. 當前地址空間上的頁轉換必須與硬件相符合。
  2. TLB在每一次的地址空間切換後都要進行flush。

  上面要求裏1表達Xen不必再做地址翻譯,2是處理x86下硬件TLB的問題。所以,Xen做了兩個決策:

  1. GuestOS負責分配和管理硬件頁表,如此最小化Xen對內存管理的介入,Xen做的只是空間隔離及安全的事情。
  2. Xen佔據每個操作頂層64M的的地址空間,操作系統可以更加方便的同Xen進行信息交流,如此可以避免操作系統狀態與Xen狀態切換時不必要的TLB flush開銷。(PS:這個操作類似於Improving Linux IPC by Kernel Desgin裏的內核空間在進程空間裏的設置,操作系統若在頂上的64M地址空間進行操作,也就類似於操作系統陷入內核態)

  Guest OS在其Page Table上的操作會被Xen檢查,也就是說Xen即便不會干預各個Guest OS對其內存片區的操作,但是仍然擁有內存使用的全局視角,Xen參與相關過程如下:

  1. Guest OS對自己擁有的內存區塊進行分配和初始化,需要在Xen中進行註冊。
  2. 所有內存的更新操作需要由Xen進行。(Xen接收Guest OS請求完成內存更新)

  以上是內存頁相關的管理,對於段內存也是類似的,GuestOS始終有兩個限制:

  1. 段描述符優先級低於Xen
  2. Xen的地址空間禁止訪問

3.2 CPU

  Hypervisor的引入要求OS不再可以是擁有最高優先級的實體,所以GuestOS必須做出相應修改。處理器架構通常有兩種權限,高權限給Xen,低的給OS。x86架構有權限環Ring,Xen處於Ring0,操作系統核心態Ring1,用戶態Ring3。此外,由Xen執行所有的權限指令。

  在異常處理方面,Xen簡單直接地將異常向量表放到Xen中,便於異常處理。特別的對於缺頁中斷Page Fault,由於該異常需要在Ring0下才能解決,因爲需要訪問CR2寄存器,所以Xen會幫助Guest OS讀取CR2寄存器並將值返回給OS。

  如何保證異常處理的代碼安全,Xen在這裏只需要檢查一下CPU的權限即可,因爲Xen通過異常向量表可以獲得異常處理的代碼段,權限必爲Ring0,所以不是Ring0下的異常處理視爲非法即可。

  Xen也會記錄錯誤程序錯誤次數,連續發生2次的錯誤的Guest OS會被終止。此外,Lazy-checking是合適的,即是說Xen沒有必要對Guest OS發生的異常去主動捕捉,因爲即便Guest OS啓動了異常處理,異常處理也總是在Guest OS的地址空間,它的相關權限操作還是會被虛擬化。

3.3 設備IO

  在全虛擬化下,IO仿真了所有的硬件設備,而Xen提出採用簡單幹淨的設備抽象。Xen上Domain之間的數據通信及Domain與設備之間的數據通信都由一片處於共享內存上的異步IO Buffer Descriptor Rings環結構維護,即5.2中的IO Rings。這個環方便了Xen對各個Guest OS的檢查、驗證。
  Xen還設計了Xen與GuestOS之間的事件機制,可以發送各種消息給各Domain,消息發送的更新基於一個bitmap。對於事件的回調,即操作系統對事件的處理仍然由各Domain自行決定。

4. Guest OS的Xen遷移開銷

  XP的遷移開銷大點,XP特別的在內存頁管理部分的代碼數據結構衆多,Linux比較少。此外XP還存在很多16位的指令,需要對他們進行仿真。其它的修改包括對權限代碼的處理。

5. 細節實現——控制與數據傳遞

5.1 控制傳遞 Control Transfer: Hypercalls and Events

  首先本文確定了Hypervisor要管什麼不管什麼,Xen的設計理念是提供最基礎的操作支持,底層的Hypervisor應當維持其簡潔的特性。

不管
Domain間CPU資源調度 資源如何分配
網絡數據包的分發 網絡數據包如何傳遞
數據塊訪問時的權限控制 ~

  由Xen架構圖,有一個特殊的GuestOS,Domain 0,它是Xen的初始OS,提供了很多配置其它OS的能力,以管理軟件爲頂層接口,通過Control Interface進行資源配置,可以實現VIF(Virtual network interface)的管理和VBDs(Virtual Block Devices)的domain訪問控制。

  Xen以異步的事件通知方式通知Domains,Domains通過hypercall請求Xen。輕量級的事件機制替代了操作系統本身關鍵的中斷處理等狀況,例如事件可被用於告知網絡上新的數據接收完畢或磁盤請求完畢等。這個機制類似於傳統的Unix 信號。

  每一個Domain當中有一個存放Pending Events(掛起未處理的事件)的bitmask,它由Xen更新,GuestOS針對事件進行處理,回調的處理會重新設置Pending Event。Domain可以選擇推遲一些事件的處理,具體是設置Xen-readable software flag,這就類似真實處理器裏關閉中斷處理一樣。

5.2 數據傳遞 IO Rings(IO環)

  IO Rings的設計支持數據在Xen體系結構的縱向層面實現數據流動,並儘可能降低傳輸開銷。爲了實現目標,提出了三個方向:

  1. 在解複用數據時儘量降低開銷(即降低數據從物理設備到達具體Domain的開銷)
  2. 儘可能有Domain提供內存用於設備數據映射,避免crosstalk在Xen的共享內存區域發生
  3. 數據傳輸過程中固定頁表項,保護IO緩衝區。

  IORing由Domain所分配,Xen可以訪問,環中的entry或者slot都是一個指針,指向具體的內存頁或數據buffer。
  IO Ring的結構如下圖所示,Xen消費了由GuestOS產生的請求,同時也就製造了回覆。GuestOS擁有一個請求製造和一個選擇消費。其中消費者指針均爲private,製造者指針爲shared,爲什麼如此?看一下圖的結構其實很明顯,消費者需要知道什麼時候消費完了。
在這裏插入圖片描述
  Request本身不一定是按照隊列順序進行處理,GuestOS關聯了request的標示,在每一次事件響應接收後都可以重新生成順序。這樣的結構通用性很強,可以支持不同的設備模式。重排序功能支持Xen調度任務,Descriptor與帶外數據的使用(指針)方便了零傳輸拷貝(zero-copy transfer)。
  IO環將響應與通知進行了分離。Domain可以在請求Xen之前加入多個請求條目,還可以也可以設置閾值推遲通知,這個實現實際上允許了Domain自己去權衡吞吐量和服務延遲。

6. 細節實現——子系統虛擬化

  5中所述的技術在具體的子系統中都得到了體現,接下來對各個子系統的細節實現再做說明。

6.1 CPU調度

  CPU調度在虛擬化這裏的主要工作是快速切換Domain上下文,這裏使用了Borrowed Virtual Time(BVT)調度算法。每個Domain有關調度的參數在Domain0中均可設置。

6.2 時間和計時器Time & Timers

  Xen中有三種時間:

  1. Real Time:nanosecond爲單位的計時,自從系統啓動開始,輔助CPU,可用NTP進行時間校正。
  2. Virtual Time:Domain的計時器,記錄他們真實運行的時間,輔助調度。
  3. Wall clock Time:用於給時間加偏移,或許是幫助應用的運行,具體應用暫時不知。

  每一個Domain都可以設置計時器Timer,可以使用Real Time和Virtual Time,到時Xen會通知它們。

6.3 虛擬地址轉換

  如前面所述,x86使用的是硬件頁表,VMware是通過給每個GuestOS提供一個新的虛擬頁表,即再加上一層翻譯解決這個問題,OS的MMU不知道真實內存狀況。VMware用陷阱捕捉所有OS訪問內存的請求,然後交予自己創建的虛擬頁錶轉換找到真實的物理地址。

  VMware在硬件和OS中間再插上一層地址翻譯的做法大大增加了Guest OS的開銷,從語義上看,應該是加倍的,所以VMware在新地址空間的開闢,進程的創建時開銷都很大。

6.4物理內存

6.5 網絡

6.6 磁盤

7 新的Domain的創建

參考文章

淺談Xen和半虛擬化技術

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章