歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

虛擬化的層次與機制

最近幾年隨著並行計算、集群等技術的火熱,虛擬機領域煥發了第二春。虛擬化就是指多台虛擬機共享一台物理機硬件的計算機體系結構技術。虛擬化的基本思想是分割軟硬件以產生更好的系統性能(實際上,軟硬件資源並沒有增加,只是利用率提高了)。一個例子就是常見的“虛擬內存”,通過將一部分不用的磁盤寫為頁面文件,可以獲得更大的內存地址空間,我們就可以跑更大的程序了。
1. 層次 我們都知道,傳統方式是應用程序跑在操作系統上,而操作系統需要適應主機的特定體系結構,比如x86的機器上就只能跑win,linux,MaxOS等幾種,AIX就沒法跑了。 有了虛擬化之後,用於的應用程序由相應的客戶操作系統管理,且1-n個客戶操作系統可以獨立於主機的操作系統,運行在同一個硬件上,且不需要適配硬件的特定體系結構。這通常通過增加一個虛擬化層來實現,該虛擬化層稱為hypervisor或VMM(Virtual Machine Monitor)。 虛擬化層將主機的物理硬件資源虛擬為可被各虛擬機互斥使用的虛擬硬件資源,這可以在不同的層面實現,如下圖:
層次 例子 應用程序級 JVM/.Net CLR 庫支持(用戶級API)級 WINE 操作系統級 Docker 硬件抽象級 VMware/Xen/KVM 指令集體系結構級 Bochs
我們從下往上看。
指令集體系結構級: 也稱為ISA(Instruction Set Architecture)級,通過使用物理主機的ISA模擬一個給定的ISA來實現。基本的模擬方式是“代碼解釋”,一個軟件翻譯層的程序將源指令逐條翻譯為目標指令,一條源指令可能會對應上百條目標指令來實現相同的功能。為改進性能,出現了動態二進制翻譯技術,將動態源指令的基本塊轉換為目標指令,基本塊可以轉化為超級塊來進一步提升轉換的效率。盡管如此,這種方式還是五種層次中效率最低的。 一個典型的代表是Bochs,可以在各種Unix like系統中模擬x86平台,包括指令集、I/O、內存、BIOS等都可以模擬。一些愛折騰的大仙在Android上裝windows就是用了這種方式(一個例子見 http://bbs.hiapk.com/thread-4750312-1-1.html ),當然速度慘不忍睹就是了。
硬件抽象級: 該類虛擬化直接在原始硬件上進行。該方法虛擬CPU、內存和I/O設備,目的是通過多個並行用戶來改進硬件資源的利用率。該類的典型代表是常用的VMware和Xen。這個層級的虛擬化有全虛擬化、半虛擬化等方式,參見第2部分介紹。 硬件級別的第一個問題是CPU虛擬化。如果當VMM/hypervisor運行在管理模式時,CPU支持在用戶模式運行虛擬機的特權指令和非特權指令,則該CPU體系結構是可虛擬化的。RISC的所有控制敏感指令和行為敏感指令都是特權指令,因此RISC CPU是天然可虛擬化的(指這些指令都會自動陷入hypervisor)。而x86體系結構並不是為虛擬化設計,如果套用全虛擬化、半虛擬化等方式,則效率較低。為此提出了一種“硬件輔助的CPU虛擬化”特殊處理,引入一種特殊的運行模式和指令,使得VMM和操作系統可以運行在不同模式中。在Intel和AMD的x86處理器中,這種模式稱為特權模式(位於環1),於是操作系統仍運行在環0(x86中操作系統只能跑在環0,見http://baike.baidu.com/link?url=sxY1XeWXddheQHsPnAOLIUpnHF6VWLCrw1IYv67T3BPaLAcnb5-j0NQpdY_B0D8iIFmUIh6OnENGyBAjsEgR1q),hypervisor運行在環1,所有特權指令和敏感指令都會自動陷入到hypervisor中。 通常來講硬件輔助虛擬化應具有更高的效率,然而,由於從hypervisor到客戶操作系統需要在處理器模式之間切換(用戶模式和特權模式),會引起較高的開銷,有時並不會優於二進制翻譯。因此,如VMware等現在使用混合的方法,一部分任務交給硬件,其余則仍由軟件處理。 內存虛擬化則類似於現代操作系統的虛擬內存。不同的是虛擬內存只有一級映射,而內存的虛擬化需要客戶操作系統和VMM分別維護“虛擬內存——物理內存”和“物理內存——機器內存”的映射,共兩級映射。VMware使用影子頁表進行虛擬內存到機器內存的地址轉換。但該技術效率太低(是早期VMware巨慢的原因之一),Intel開發了基於硬件的EPT(擴展頁表)技術來加以改進,下圖為該技術的示意圖(盜的台巴子的,原文找不到了)。(AMD也有類似的技術稱為NPT) \
I/O虛擬化包括管理虛擬設備和共享的物理硬件之間I/O請求的路由選擇。有如下三種方式:全設備模擬、半虛擬化和直接I/O,我也不是很懂就不展開講了。只知道VMware用的是全設備模擬。 該類虛擬化由於可以得到CPU級別的支持,性能是比較高的,但是VMM仍然需要自己實現調度器、內存管理器等部件,因此不論VMware還是Xen的代碼都比較龐大。
操作系統級: 指處於傳統操作系統和用戶應用程序之間的抽象層。操作系統級虛擬化在一個單一的物理服務器上創建隔離的容器和操作系統實例,常被用來創建虛擬主機環境,在大量互斥的不信任用戶之間分配硬件資源。這種虛擬機也稱為VE(虛擬執行環境)、VPS(虛擬專用系統)或容器。VE有自己的進程、文件系統、用戶賬號、IP地址、路由表、防火牆規則及其他設置。盡管VE可為不同用戶分別定制,但它們仍共享同一個操作系統。 操作系統級虛擬化方案解決了硬件級虛擬化的很多問題:首先物理機器和虛擬機實例數可以動態改變;其次硬件級虛擬化的虛擬機初始化很慢,而操作系統級虛擬化幾乎不需要時間;第三就是硬件全虛擬化性能較低,半虛擬化又需要修改客戶操作系統(全虛擬化和半虛擬化後面講),但操作系統級虛擬化就幾乎沒有開銷。以上幾個特性使操作系統級虛擬化非常適合雲計算場景。 一個典型的代表是Docker,其基於Linux的LXC,說白了就是cgroups。Docker最近兩年火得不要不要的,但實際上不是新鮮事物,而且一旦用上Docker就需要傳統的運維體系有巨大的變革,因此在大企業中很少見到用得好的(這個話題大了,以後再詳細講)。Docker的優點就是上述操作系統級虛擬化的優點,缺點也很明顯,首先宿主機和虛擬機都只能是linux,資源隔離比VMware這些也有差距,cpu和disk的管理較簡單。(當然在Docker間共享數據還是很容易的,用數據卷就行了,我不懂Docker都知道這玩意兒,上周一批懂Docker的磚家一起開會都沒想到這東西,我也是醉鳥)
庫支持級: 這種方案基於一個思路,大部分應用都是基於用戶庫API而不是系統級調用的,因此可以通過API鉤子控制應用程序和其他系統部分之間的連接,使得帶有庫接口的虛擬化成為可能。這種方式和網游脫機外掛其實異曲同工,難度是不高的。 一個典型的代表是WINE,其可以在Unix like系統上運行win32應用程序。當然其實是非常難用的,高中剛開始玩linux那會兒,總想著用WINE跑win上的游戲,但是除了一些簡單的exe可以運行,directx游戲都是跑不了的,原因是DLL依賴太復雜了,很多也不支持。這麼多年過去了問題越來越惡化,畢竟微軟幾千號人寫API,WINE的開發就那麼幾個,模擬得過來麼。
應用程序級: 這個級別的虛擬化是將一個應用程序虛擬化為一個虛擬機。最流行的方法是高級語言虛擬機,在這種情況下,虛擬化層作為一個應用程序處於操作系統之上,並且這一層抽象出一個虛擬機,其可以運行為特定的機器環境所編寫和編譯的程序。 典型的代表是Java虛擬機和微軟的.Net CLR,當然因為純應用程序級虛擬化效率很低,兩者現在都不是純的虛擬機,比如JVM中很關鍵的一部分就是JIT(即時編譯),當年Java1.0時代的純解釋執行才等同於應用程序級虛擬機,那個效率誰用誰知道。
以下是五種級別的對比,*越多越好(性能高,靈活性高,實現復雜度低,隔離性好):
實現級別 高性能 應用程序靈活性 實現復雜度 應用程序隔離性 應用程序級 ** ** * ***** 庫支持(用戶級API)級 *** ** **** ** 操作系統級 ***** ** *** ** 硬件抽象級 ***** *** * **** 指令集體系結構級 * ***** *** ***

2.機制 可根據是否需要修改客戶操作系統,分為硬件虛擬化和編譯器支持虛擬化。硬件虛擬化又分為:全虛擬化和基於主機的虛擬化(很多材料將兩者等同,是不對的)。編譯器支持虛擬化只有一種,稱為半虛擬化。
全虛擬化: 在全虛擬化中,非關鍵指令直接運行在硬件之上,而關鍵指令(特權指令、控制敏感指令、行為敏感指令)被替換為通過軟件模擬的陷入VMM/hypervisor的指令。即,(非x86系統中)VMM運行在環0,客戶操作系統運行在環1,用戶應用程序運行在環3,用戶應用程序的指令直接操作系統硬件,客戶操作系統的指令通過VMM二進制翻譯後操作系統硬件。見下圖。VMware就使用了這種機制。 \
基於主機的虛擬化: 這種機制是,宿主機的操作系統仍舊負責管理硬件,在宿主機操作系統上安裝一個虛擬化層,客戶操作系統安裝並運行在虛擬化層之上。可見這種機制下不論何種指令,都需要經虛擬化層轉發後由宿主機操作系統執行,並且當客戶操作系統的ISA與底層硬件的ISA不同時,還需要在虛擬化層做二進制翻譯,因此效率是很低的。也可見這種方式和全虛擬化是有區別的,所以必須分開講。
半虛擬化: 半虛擬化技術是後來才出現的技術,也叫做准虛擬化技術,現在比較熱門,它就是在全虛擬化的基礎上,把客戶操作系統進行了修改,增加了一個專門的API,這個API可以將客戶操作系統發出的指令進行最優化,即不需要VMM/Hypervisor耗費一定的資源進行翻譯操作,因此Hypervisor的工作負擔變得非常的小,整體性能也有很大的提高。不過缺點就是,要修改包含該API的操作系統,但是對於某些不含該API的操作系統(主要是windows)來說,就不能用這種方法。半虛擬化技術見下圖。 \

這些都說完,就可以來比較另兩種主流的虛擬化技術了:XEN和KVM。 XEN(參見 http://baike.baidu.com/link?url=J97539DMsA9HW2WZYsX7ZNliZUx9d2j3LarHw2yRd37Lh_ho6zAe1Gy5Xfh-z-TxuLH3Q6T2qfrNEBDmuMiAca)主要是為x86平台服務的,當運行修改的操作系統時可以使用半虛擬化機制,當CPU支持且操作系統無法修改時可使用全虛擬化機制。 KVM(參見http://baike.baidu.com/link?url=kV4fSyYs0tw-bhBpp6Fofh4C6c5nQDKmY1eTmIR-BPbliDsX0uYOF97ypPAsCqmsM96xt85ai4q89rO8XaEe8_,這裡說KVM是全虛擬化,又是錯的)不針對特定架構,但針對特定宿主操作系統,因為它是linux內核2.6.20後內置的,代碼量比XEN少得多。當運行修改的操作系統時使用半虛擬化機制,當CPU支持時可使用改進的基於主機的虛擬化機制,即Hypervisor雖然位於主操作系統上,但在內核上打了個洞,如果CPU支持如Intel VT之類的技術,虛擬機操作系統的關鍵指令可直接映射到物理硬件上,從而大大提升性能,如圖所示(盜自 http://www.linuxidc.com/Linux/2015-03/114462.htm )。 \
如果硬要比較的話,在編譯器支持虛擬化(半虛擬化)時XEN優於KVM,在硬件虛擬化時KVM優於XEN。
(本文參考《雲計算與分布式系統》,但是原書的相關章節有些混亂,也有一些跟不上形勢的地方,一並修改了)

Copyright © Linux教程網 All Rights Reserved