進行虛擬化 就是要將某種形式的東西以另外一種形式呈現出來。對計算機進行虛擬化就是要將計算機以多台計算機或一台完全不同的計算機的形式呈現出來。
虛擬化也可以將多台計算機組合成一台計算機的形式呈現出來。這通常稱為服務器聚合或網格計算。
下面讓我們首先來看一下虛擬化的起源。
虛擬化的歷史
虛擬化並不是什麼新主題;實際上,它的存在已經超過 40 年了。虛擬化技術最早的一些用法包括 IBM® 7044、麻省理工學院(MIT)在 IBM 704 上開發的 CTSS(Compatible Time Sharing System)以及曼徹斯特大學的 Atlas 項目(世界上最早的超級計算機之一),這些都是請求頁面調度和監管進程調用的先驅。
硬件虛擬化
IBM 早在 20 世紀 60 年代開發 System/360™ Model 67 大型機時就認識到了虛擬化的重要性。Model 67 通過 VMM(Virtual Machine Monitor)對所有的硬件接口都進行了虛擬化。在早期計算中,操作系統被稱為 supervisor。能夠在其他操作系統上運行的操作系統被稱為 hypervisor(這個術語是在 20 世紀 70 年代出現的)。
VMM 可以直接在底層硬件上運行,允許運行多個虛擬機(VM)。每個 VM 都可以運行一個自己私有操作系統的實例 —— 在早些時候,這稱為 CMS(或 Conversational Monitor System)。之後 VM 繼續發展,現在您可以在 System z9™ 大型機上發現 VM。這提供了很好的向後兼容性,甚至是對 System/360 產品線的兼容性。
處理器虛擬化
虛擬化早期的另外一種用法(在本例中是對處理器的仿真)是 P-code(或偽碼)機。P-code 是一種機器語言,運行於虛擬機而不是實際硬件。P-code 早在 20 世紀 70 年代就已在加州大學聖地亞哥分校(UCSD)Pascal 系統上頗有名氣了,它將 Pascal 程序編譯成 P-code,然後在一個 P-code 虛擬機上運行。這就使 P-code 程序具有了高度的可移植性,而且,只要有可用的 P-code 虛擬機,P-code 程序就可以運行。
Java 虛擬機(JVM)Java™ 語言對自己的虛擬機沿用了這種 P-code 模型。這樣只需要通過簡單地移植 JVM 就可以將 Java 程序廣泛地分布到無數的體系架構上。20 世紀 60 年代對 BCPL(Basic Combined Programming Language)的設計中也采用了相同的概念,C 語言即由 BCPL 發展而來。在這種用法中,編譯器會將 BCPL 代碼編譯成稱為 O-code 的中間機器代碼。接下來的第二個步驟是將 O-code 編譯成目標機器的原始語言。現代編譯器所使用的這種模型為將編譯器移植到新目標體系結構上提供了很大的靈活性(通過一種中間語言將前端和後端分隔開來)。
指令集虛擬化
虛擬化最新的發展稱為指令集虛擬化,或者二進制轉換。在這種模型中,虛擬指令集被轉換成底層硬件的物理指令集,這個過程通常都是動態的。當代碼執行時,就會對代碼的某個段進行轉換。如果出現分支情況,就會導入新代碼集並進行轉換。這使它與緩存操作非常類似,後者是將指令塊從內存移動到本地快速緩存中執行。
這種模型最近在 Transmeta 設計的 Crusoe 中央處理單元(CPU)中得到了使用。二進制轉換由 Code Morphing 的專利技術實現。類似的一個例子是完全虛擬化解決方案通過運行時代碼掃描來查找和重定向特權指令(用來解決特定處理器指令集的一些問題)。
虛擬化和游戲一篇有關虛擬化的文章如果不提一下 MAME(Multiple-Arcade Machine Emulator),就不算完整。顧名思義,MAME 就是以前很多 arcade 游戲的一個完整的機器模擬器。除了對這些游戲中使用的處理器進行虛擬化之外,還可以對整個機器進行虛擬化,包括聲音、圖形處理硬件和控制單元。MAME 是一個非常不錯的應用程序,不過要理解它們究竟實現了哪些功能,研讀一下它的源代碼會非常有幫助。虛擬化的類型
實現虛擬化的方法不止一種。實際上,有幾種方法都可以通過不同層次的抽象來實現相同的結果。本節將介紹 Linux 中常用的 3 種虛擬化方法,以及它們相應的優缺點。業界有時會使用不同的術語來描述相同的虛擬化方法。本文中使用的是最常用的術語,同時給出了其他術語以供參考。
硬件仿真
毫無疑問,最復雜的虛擬化實現技術就是硬件仿真。在這種方法中,可以在宿主系統上創建一個硬件 VM 來仿真所想要的硬件,如圖 1 所示。
圖 1. 硬件仿真使用 VM 來模擬所需要的硬件 仿真和開發硬件仿真的應用之一是進行固件和硬件的協作開發。固件開發人員可以使用目標硬件 VM 在仿真環境中對自己的實際代碼進行驗證,而不需要等到硬件實際可用的時候。正如您所能預見的一樣,使用硬件仿真的主要問題是速度會非常慢。由於每條指令都必須在底層硬件上進行仿真,因此速度減慢 100 倍的情況也並不稀奇。若要實現高度保真的仿真,包括周期精度、所仿真的 CPU 管道以及緩存行為,實際速度差距甚至可能會達到 1000 倍之多。
硬件仿真也有自己的優點。例如,使用硬件仿真,您可以在一個 ARM 處理器主機上運行為 PowerPC® 設計的操作系統,而不需要任何修改。您甚至可以運行多個虛擬機,每個虛擬器仿真一個不同的處理器。
更多內容請看系統管理專題,或 完全虛擬化
完全虛擬化(full virtualization),也稱為原始虛擬化,是另外一種虛擬化方法。這種模型使用一個虛擬機,它在客戶操作系統和原始硬件之間進行協調(參見圖 2)。“協調”在這裡是一個關鍵,因為 VMM 在客戶操作系統和裸硬件之間提供協調。特定受保護的指令必須被捕獲下來並在 hypervisor 中進行處理,因為這些底層硬件並不由操作系統所擁有,而是由操作系統通過 hypervisor 共享。
圖 2. 完全虛擬化使用 hypervisor 來共享底層硬件 老硬件上的 hypervisor有些比較老的硬件,例如 x86,會給完全虛擬化帶來一些問題。例如,需要 VMM 處理的一些特定敏感指令並沒有捕獲。因此,hypervisor 必須要動態掃描並捕獲這些特權模式代碼來解決這一問題。雖然完全虛擬化的速度比硬件仿真的速度要快,但是其性能要低於裸硬件,因為中間經過了 hypervisor 的協調過程。完全虛擬化的最大優點是操作系統無需任何修改就可以直接運行。惟一的限制是操作系統必須要支持底層硬件(例如 PowerPC)。
超虛擬化
超虛擬化(paravirtualization)是另外一種流行的虛擬化技術,它與完全虛擬化有一些類似。這種方法使用了一個 hypervisor 來實現對底層硬件的共享訪問,還將與虛擬化有關的代碼集成到了操作系統本身中(參見圖 3)。這種方法不再需要重新編譯或捕獲特權指令,因為操作系統本身在虛擬化進程中會相互緊密協作。
圖 3. 超虛擬化與客戶操作系統共享進程正如前面介紹的一樣,超虛擬化技術需要為 hypervisor 修改客戶操作系統,這是它的一個缺點。但是超虛擬化提供了與未經虛擬化的系統相接近的性能。與完全虛擬化類似,超虛擬化技術可以同時支持多個不同的操作系統。
操作系統級的虛擬化
我們要介紹的最後一種技術是操作系統級的虛擬化,它使用的技術與前面所介紹的有所不同。這種技術在操作系統本身之上實現服務器的虛擬化。這種方法支持單個操作系統,並可以將獨立的服務器相互簡單地隔離開來(參見圖 4)。
圖 4. 操作系統級虛擬化實現服務器的隔離操作系統級的虛擬化要求對操作系統的內核進行一些修改,但是其優點是可以獲得原始性能。
為什麼虛擬化如此重要?
在了解目前 Linux 可以使用的虛擬化方法之前,讓我們先來了解一下虛擬化的優點。
從商業角度來看,使用虛擬化技術有很多原因。大部分原因都可以歸結於服務器的鞏固(server consolidation)。簡單來說,如果您可以對一個服務器上多個未經充分利用的系統進行虛擬化,由於服務器的數量少了,顯然可以節省大量電力、空間、制冷和管理成本。由於很難確定服務器的利用情況,虛擬化技術支持稱為動態遷移的技術。動態遷移(Live migration)允許操作系統及其應用程序遷移到新的服務器上,從而實現負載在可用硬件上的均衡。
虛擬化技術對於開發人員來說也非常重要。Linux 內核占據了一個單一的地址空間,這意味著內核或任何驅動程序的故障都會導致整個操作系統的崩潰。虛擬化技術意味著您可以運行多個操作系統,如果其中一個系統由於某個 bug 而崩潰了,那麼 hypervisor 和其他操作系統都依然可以繼續運行。這可以使內核的調試非常類似於用戶空間應用程序的調試。
與 Linux 有關的虛擬化項目
表 1 給出了幾個 Linux 系統上的虛擬化項目,並著重介紹了其中的開源解決方案。
表 1. 與 Linux 有關的虛擬化項目 項目 類型 許可證 Bochs 仿真 LGPL QEMU 仿真 LGPL/GPL VMware 完全虛擬化 私有 z/VM 完全虛擬化 私有 Xen 超虛擬化 GPL UML 超虛擬化 GPL Linux-VServer 操作系統級虛擬化 GPL OpenVZ 操作系統級虛擬化 GPL
有關其他解決方案的信息,請參看 參考資料 部分。
Bochs(仿真)
庫級虛擬化盡管在正文中沒有討論,庫級虛擬化是另外一種可以通過庫對操作系統部分進行仿真的虛擬化技術。這種虛擬化技術的例子包括 Wine(Linux 上使用的一個部分 Win32 API)和 LxRun(Solaris 上使用的一個部分 Linux API)。
Bochs 是一個 x86 計算機仿真器,它在很多平台上(包括 x86、PowerPC、Alpha、SPARC 和 MIPS)都可以移植和運行。使 Bochs 更為有趣的是它不僅可以對處理器進行仿真,還可以對整個計算機進行仿真,包括計算機的外圍設備,比如鍵盤、鼠標、視頻圖像硬件、網卡(NIC)等。
Bochs 可以配置作為一個老式的 Intel® 386 或其後繼處理器使用,例如 486、Pentium、Pentium Pro 或 64 位處理器。它甚至還可以對一些可選的圖形指令進行仿真,例如 MMX 和 3DNow。
使用 Bochs 仿真器,您可以運行任何 Linux 上的 Linux 發行版、Linux 上的 Microsoft® Windows® 95/98/NT/2000(以及各種應用程序),甚至 Linux 上的 BSD(Berkeley Software Distribution)操作系統(FreeBSD、OpenBSD 等)。
更多內容請看系統管理專題,或
QEMU(仿真)
QEMU 是另外一個仿真器,它與 Bochs 非常類似,不過也有一些值得一提的區別。QEMU 支持兩種操作模式。第一種是 Full System Emulation(完全系統仿真)模式。 這種模式與 Bochs 非常類似,它可以對一個具有處理器和外圍設備的完整個人計算機(PC)進行仿真。這種模式可以仿真很多處理器架構,例如 x86、x86_64、ARM、SPARC、PowerPC 和 MIPS,其動態轉換的速度也比較理想。使用這種模式,您可以在 Linux、Solaris 和 FreeBSD 上仿真 Windows 操作系統(包括 XP)和 Linux。很多其他操作系統的組合也都可以得到支持(更多信息請參看 參考資料 部分)。
QEMU 還可以支持第二種模式,稱為 User Mode Emulation(用戶模式仿真)。這種模式只能宿主於 Linux,在這種模式下,可以啟動不同體系結構的二進制文件。例如,在 x86 平台上運行的 Linux 系統上可以執行為 MIPS 體系架構編譯的二進制文件。這種模式支持的其他體系結構還包括 ARM、SPARC 和 PowerPC,而且還有很多尚在開發之中。
VMware(完全虛擬化)
VMware 是完全虛擬化的一個商業解決方案。在客戶操作系統和裸硬件之間有一個 hypervisor 作為抽象層使用。這個抽象層允許任何操作系統在硬件上運行,而不需要了解任何其他客戶操作系統。
VMware 也會對可用的 I/O 硬件進行虛擬化,並將一些高性能的設備驅動程序加入到 hypervisor 中。
整個虛擬化後的環境都作為一個文件保存,這意味著整個系統(包括客戶操作系統、VM 和虛擬硬件)可以很容易地快速遷移到新宿主機器上進行負載均衡。
z/VM (完全虛擬化)
盡管 IBM System z™ 是一個新品牌,不過它實際上已經有很長的一段歷史,可以一直追溯到 20 世紀 60 年代。System/360 在 1965 年就可以支持使用虛擬機進行虛擬化。有趣的是,System z 保留了對之前的 System/360 產品線的向後兼容性。
z/VM® 是 System z 上的操作系統 hypervisor。其核心是 Control Program(CP),它為客戶操作系統,包括 Linux,提供了物理資源的虛擬化(參見圖 5)。這樣,多個處理器和其他資源就可以在多個客戶操作系統上被虛擬化。
圖 5. 使用 z/VM 的操作系統級虛擬化
z/VM 也可以為想要相互通信的客戶操作系統仿真一個客戶局域網(LAN)。仿真完全是在 hypervisor 中進行的,因此相當安全。
Xen(超虛擬化)
Xen 是一個來自於 XenSource 的操作系統級超虛擬化的免費開源解決方案。回想一下在超虛擬化中,hypervisor 和操作系統會共同協作,雖然操作系統需要進行一些更改,但卻可以帶來接近於原始系統的性能。
就像 Xen 需要進行協作(對客戶操作系統進行修改)一樣,只有那些修補過的操作系統才可以通過 Xen 進行虛擬化。Linux 本身就是開源的,所以從 Linux 角度來看,這是一個很合理的折衷,因為最終可以獲得比完全虛擬化更好的性能。但是從廣泛支持的角度來看(例如對其他非開源操作系統的支持),這顯然是一個缺點。
Windows 可以在 Xen 上作為一個客戶操作系統運行,但是它只能在運行 Intel Vanderpool 或 AMD Pacifica 的系統上使用。支持 Xen 的其他操作系統包括 Minix、Plan 9、NetBSD、FreeBSD 和 OpenSolaris。
User-mode Linux(超虛擬化)
User-mode Linux(UML)允許 Linux 操作系統在其他操作系統的用戶空間中運行。每個客戶 Linux 操作系統都存在於宿主 Linux 操作系統中的一個進程中(參見圖 6)。這就允許 Linux 內核(使用自己的相關用戶空間)在單個 Linux 內核中運行。
圖 6. User-mode Linux 中的 Linux
在 2.6 版本的 Linux 內核中,UML 駐留於主內核樹內,但它必須提前啟用,然後再重新編譯才能使用。這些變化除了常見的虛擬化功能之外,還可以提供設備的虛擬化。這樣一來,客戶操作系統就可以共享可用的物理設備,例如塊設備(比如軟盤、CD-ROM 和文件系統)、控制台、NIC 設備、聲音硬件等。
注意由於客戶內核是在應用程序空間中運行的,因此它們必須為這種用法而被特殊編譯(不過它們可以是不同的內核版本)。這樣就產生了主機內核(硬件上的內核)和客戶內核(在主機內核的用戶空間中運行)。這些內核甚至可以是嵌套的,這樣就允許一個客戶內核在另外一個運行於主機內核的客戶內核上運行。
Linux-VServer(操作系統級虛擬化)
Linux-VServer 是一個操作系統級虛擬化解決方案。Linux-VServer 對 Linux 內核進行虛擬化,這樣多個用戶空間環境 —— 又稱為 Virtual Private Server(VPS) —— 就可以單獨運行,而不需要互相了解。Linux-VServer 通過修改 Linux 內核實現用戶空間的隔離。
要將各個用戶空間與其他用戶空間隔離開來,就需要從上下文的概念入手。上下文 是給定 VPS 進程使用的一個容器,這樣通過諸如 ps 之類的工具就可以了解 VPS 的進程。內核為最初的引導定義了一個缺省的上下文。另外管理端還能查看所有的上下文(所有的執行進程)。正如您可能猜到的那樣,內核和內部數據結構也需要進行修改來支持這種虛擬化方法。
Linux-VServer 還使用了一種 chroot 格式來為每個 VPS 隔離 root 目錄。雖然 chroot 允許指定新 root 目錄,但還是需要其他一些功能(稱為 Chroot-Barrier)來限制 VPS 脫離其隔離的 root 目錄回到上級目錄。給定一個隔離的 root 目錄之後,每個 VPS 就可以擁有自己的用戶列表和 root 密碼。
2.4 和 2.6 版本的 Linux 內核支持 Linux-VServer,它可以運行於很多平台之上,包括 x86、x86-64、SPARC、MIPS、ARM 和 PowerPC。
OpenVZ(操作系統級虛擬化)
OpenVZ 是另外一個操作系統級的虛擬化解決方案,它與 Linux-VServer 類似,不過也有一些有趣的區別。OpenVZ 是一個支持虛擬化的內核(修改過的),可以支持用戶空間隔離、VPS 和一組用戶管理工具。例如,您可以簡單地從命令行創建一個新的 VPS:
清單 1. 從命令行創建 VPS
$ vzctl create 42 --ostemplate fedora-core-4 Creating VPS private area VPS private area was created $ vzctl start 42 Starting VPS ... VPS is mounted
另外還可以使用 vzlist 命令顯示目前創建的 VPS,該命令與標准 Linux ps 命令類似。
為了對進程進行調度,OpenVZ 還包括了兩級 CPU 調度器。首先,調度器確定哪個 VPS 應該獲得 CPU。在這個步驟完成之後,第二級調度器會根據給定的標准 Linux 優先級挑選進程來執行。
OpenVZ 還包括了所謂的 beancounters。beancounter 包括很多參數,這些參數為給定的 VPS 定義了資源分配。這為 VPS 提供了一定層次上的控制,定義了有多少內存可用,有多少進程間通信(IPC)對象可用等。
OpenVZ 的一個特性是檢查點功能和將 VPS 從一個物理服務器遷移到其他物理服務器上的能力。檢查點 意味著正在運行的 VPS 的狀態被凍結並存儲到一個文件中。然後可以將這個文件遷移到一個新服務器上並加以還原以使 VPS 恢復運行。
OpenVZ 支持很多硬件體系結構,包括 x86、x86-64 和 PowerPC。
更多內容請看系統管理專題,或
對完全虛擬化和超虛擬化的硬件支持
回想一下 IA-32(x86)體系結構在進行虛擬化時會產生的一些問題。特定的特權模式指令無法捕獲,基於所使用的模式還可能返回不同的結果。例如,x86 STR 指令可以檢索安全狀態,但是所返回的值要取決於請求者特定的特權級別。在嘗試在不同的層次對不同的操作系統進行虛擬化時,這會出現問題。例如,x86 支持 4 環保護,其中級別 0 (最高特權)通常運行操作系統,級別 1 和 2 支持操作系統服務,級別 3(最低級別)支持應用程序。不過硬件供應商已經認識到了這種缺陷(以及其他一些問題),並且已經開發了一些支持並加速虛擬化的新設計。
Intel 正在開發新虛擬化技術,能在 x86(VT-x)和 Itanium®(VT-i)體系架構上支持 hypervisor。VT-x 支持兩種格式的操作,一種用於 VMM(root),另外一種用於客戶操作系統(非 root)。root 格式完全是特權級的,而非 root 格式是非特權級的(即使對環 0 來說也是如此)。這種體系架構支持定義指令來使 VM(客戶操作系統)退出到 VMM 和保存處理器狀態。此外還添加了許多其他的功能,請參看 參考資料 部分。
AMD 也開發了硬件輔助虛擬化技術,稱為 Pacifica。除了其他一些特性之外,Pacifica 還為在特殊指令執行時保存的客戶操作系統維護了一個控制塊。VMRUN 指令允許虛擬機(及其相關的客戶操作系統)一直運行,直到 VMM 重新獲得控制權為止(這也是可配置的)。這種可配置能力允許 CMM 為每個客戶操作系統定制特權指令。Pacifica 還可以使用宿主和客戶內存管理單元(MMU)表來進行地址轉換。
這些新技術也可以應用到此處討論的很多其他虛擬化技術中,包括 Xen、VMware、User-mode Linux 等。
Linux KVM(內核虛擬機)
Linux 傳出的最新消息是將 KVM 合並到 Linux 內核中(2.6.20)。KVM 是一種完全虛擬化解決方案,它有一個方面非常獨特:它將 Linux 內核轉換為一個使用內核模塊的 hypervisor。這個模塊允許使用其他客戶操作系統,然後在宿主 Linux 內核的用戶空間中運行(參見圖 7)。內核中的 KVM 通過 /dev/kvm 字符設備來公開虛擬化後的硬件。客戶操作系統使用為 PC 硬件仿真修改過的 QEMU 進程與 KVM 模塊接口。
圖 7. 使用內核虛擬機(KVM)的虛擬化
KVM 模塊向內核中引入了一個新的執行模塊。普通內核支持內核 模式和用戶 模式,而 KVM 則引入了一種客戶 模式。客戶模式用來執行所有非 I/O 客戶代碼,而普通用戶模式支持客戶 I/O。
KVM 的引入是 Linux 的一個有趣革新,因為它代表了作為主流 Linux 內核一部分的第一個虛擬化技術。它已經存在於 2.6.20 樹中,不過也可以作為 2.6.19 內核的一個內核模塊使用。當在支持虛擬化的硬件上運行時,KVM 支持 Linux(32 位和 64 位)和 Windows(32 位)客戶機。有關 KVM 的更多信息,請參看 參考資料 部分。
結束語
如果 40 年前出現的技術還可以算是“新”技術的話,那麼虛擬化就是一個重要的新技術領域。虛擬化技術已經在很多場合中應用過了,但現在主要的關注點是服務器和操作系統的虛擬化。與 Linux 非常類似,虛擬化為性能、可移植性和靈活性提供了很多選項。這意味著您可以選擇最適合於您自己應用程序的虛擬化方法。
獲得產品和技術
Bochs 和 QEMU 是 PC 仿真器,它們允許諸如 Windows 或 Linux 之類的操作系統在 Linux 操作系統的用戶空間中運行。 VMware 是一個流行的完全虛擬化的商業解決方案,它可以對未經修改的操作系統進行虛擬化。 z/VM 是 64 位 z/Architecture 使用的最新的 VM 操作系統。z/VM 通過硬件輔助提供了完全虛擬化功能,並且可以支持很多操作系統,包括 Linux。 Xen 是一個開源的超虛擬化解決方案,它雖然需要對客戶操作系統進行修改,但可以通過與 hypervisor 的協作獲得接近原始系統的性能。 User-mode Linux 是另外一個超虛擬化解決方案,也是開源的。每個客戶操作系統都是作為主機操作系統的一個進程執行的。 coLinux 或 Cooperative Linux,是一個允許兩個操作系統協作式共享底層硬件的虛擬化解決方案。 Linux-Vserver 是一個 GNU/Linux 系統使用的操作系統級虛擬化解決方案,它安全地隔離了各個客戶服務器。 OpenVZ 是一個操作系統級虛擬化解決方案,可以支持檢查點和動態遷移。 Linux KVM 是第一個集成到主流 Linux 內核中的虛擬化技術。通過一個可加載的內核模塊,運行於可虛擬化的硬件上的 Linux 內核可以充當 hypervisor 並可支持未經修改的 Linux 和 Windows 客戶操作系統。原文鏈接:http://www.ibm.com/developerworks/cn/linux/l-linuxvirt/
更多內容請看系統管理專題,或