歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux服務器 >> 探索 Linux 內核虛擬機 KVM 架構及其優點

探索 Linux 內核虛擬機 KVM 架構及其優點

日期:2017/3/2 16:39:46   编辑:Linux服務器

Linux既有良好的靈活性,在虛擬化方面同樣出色。但是最近,隨著內核虛擬機(KVM)的出現,Linux 虛擬化的前景發生了變化。KVM 是構成主流 Linux 內核(V2.6.20)一部分的第一個虛擬化解決方案。KVM 支持 Linux 客戶操作系統的虛擬化 —— 甚至支持其硬件對虛擬化敏感的 Windows系統的虛擬化。了解 Linux KVM 的架構並了解它與內核的緊密集成為何會改變您使用 Linux 的方式。

簡介

虛擬化 概念很早就已出現。簡單來說,虛擬化就是使用某些程序,並使其看起來類似於其他程序的過程。將這個概念應用到計算機系統中可以讓不同用戶看到不同的單個系統(例如,一台計算機可以同時運行 Linux和Microsoft Windows)。這通常稱為全虛擬化(full virtualization)。

虛擬化也可以使用更加復雜的格式,其中單個計算機看上去具有多個架構(對於一個用戶來說,它是一個標准的 x86 平台;對於另外一個用戶來說,它是 IBM Power PC? 平台)。這種虛擬化形式通常被稱為 硬件仿真。

最後,更加簡單的一種虛擬化是操作系統虛擬化,其中一台計算機可以運行相同類型的多個操作系統。這種虛擬化可以將一個操作系統的多個服務器隔離開來(這意味著全都必須使用相同類型和版本的操作系統)。

虛擬化和准虛擬化(para-virtualization)

虛擬化最常使用的兩種方法是全虛擬化 和准虛擬化。使用全虛擬化,在虛擬化的操作系統和硬件之間存在一個層,用於決定訪問。這個層稱為系統管理程序 或虛擬機監視器(VMM)。准虛擬化與之類似,但是系統管理程序會以一種更具協作性的方式進行操作。這是因為每個客戶操作系統都了解自己正在虛擬化模式中運行,因此每個系統都與系統管理程序協作,來實現底層硬件的虛擬化。

全虛擬化的例子包括商業虛擬化解決方案 VMware,以及商業 IBM zSeries? 計算機上使用的 IBM System z9 Virtual Machine(z/VM)操作系統。准虛擬化的例子有 Xen 和 User-Mode-Linux (UML)。 KVM 也被認為是一個全虛擬化解決方案,不過我們稍後再介紹這個問題。

虛擬化的工作原理

我們首先簡要介紹一下虛擬化技術及其涉及的元素。虛擬化解決方案的底部是要進行虛擬化的機器。這台機器可能直接支持虛擬化,也可能不會直接支持虛擬化;那麼就需要系統管理程序 層的支持。系統管理程序,或稱為 VMM,可以看作是平台硬件和操作系統的抽象化。在某些情況中,這個系統管理程序就是一個操作系統;此時,它就稱為主機操作系統,如 圖 1 所示。

探索 Linux 內核虛擬機 KVM 架構及其優點(圖一)

圖 1. 虛擬化的分層抽象

系統管理程序之上是客戶機操作系統,也稱為虛擬機(VM)。這些 VM 都是一些相互隔離的操作系統,將底層硬件平台視為自己所有。但是實際上,是系統管理程序為它們制造了這種假象。

目前使用虛擬化解決方案的問題是,並非所有硬件都可以很好地支持虛擬化。較老的 x86 處理器根據執行范圍對特定指令會產生不同結果。這就產生了一個問題,因為系統管理程序應該只能在一個最受保護的范圍中執行。由於這個原因,諸如 VMWare 之類的虛擬化解決方案會提前掃描要執行的代碼,從而將這些指令替換為一些陷阱指令(trap instruction),這樣系統管理程序就可以正確地處理它們。Xen 可以支持一種協作的虛擬化方法,它不需要任何修改,因為客戶機知道自己正在進行虛擬化,並已經進行了修改。KVM 會簡單地忽略這個問題,如果您希望進行虛擬化,就強制必須在更新的硬件上運行。

剛開始會覺得這有些不方便,但是考慮到目前上市的較新機器都可以支持虛擬化(例如 Intel? VT 和 AMD SVM),用不了多久,這將成為標准方法而不是少數例外情況。

KVM 系統管理程序

考慮到虛擬化技術的發展時間並不長,KVM 實際上還是一種相對來說比較新的技術。目前存在各具功能的開源技術,例如 Xen、Bochs、UML、Linux-VServer 和 coLinux,但是 KVM 目前正在被大量使用。另外,KVM 不再僅僅是一個全虛擬化解決方案,而將成為更大的解決方案的一部分。

KVM 所使用的方法是通過簡單地加載內核模塊而將 Linux 內核轉換為一個系統管理程序。這個內核模塊導出了一個名為 /dev/kvm 的設備,它可以啟用內核的客戶模式(除了傳統的內核模式和用戶模式)。有了 /dev/kvm 設備,VM 使自己的地址空間獨立於內核或運行著的任何其他 VM 的地址空間。設備樹(/dev)中的設備對於所有用戶空間進程來說都是通用的。但是每個打開 /dev/kvm 的進程看到的是不同的映射(為了支持 VM 間的隔離)。

KVM 然後會簡單地將 Linux 內核轉換成一個系統管理程序(在安裝 kvm 內核模塊時)。由於標准 Linux 內核就是一個系統管理程序,因此它會從對標准內核的修改中獲益良多(內存支持、調度程序等)。對這些 Linux 組件進行優化(例如 2.6 版本內核中的新 O(1) 調度程序)都可以讓系統管理程序(主機操作系統)和 Linux 客戶操作系統同時受益。但是 KVM 並不是第一個這樣做的程序。UML 很久以前就將 Linux 內核轉換成一個系統管理程序了。使用內核作為一個系統管理程序,您就可以啟動其他操作系統,例如另一個 Linux 內核或 Windows 系統。

KVM

安裝 KVM 之後,您可以在用戶空間啟動客戶操作系統。每個客戶操作系統都是主機操作系統(或系統管理程序)的一個單個進程。 圖 2 提供了一個使用 KVM 進行虛擬化的視圖。底部是能夠進行虛擬化的硬件平台(目前指的是 Intel VT 或 AMD-SVM 處理器)。在裸硬件上運行的是系統管理程序(帶有 KVM 模塊的 Linux 內核)。這個系統管理程序與可以運行其他應用程序的普通 Linux 內核類似。但是這個內核也可以支持通過 kvm 工具加載的客戶操作系統。最後,客戶操作系統可以支持主機操作系統所支持的相同應用程序。

探索 Linux 內核虛擬機 KVM 架構及其優點(圖二)

圖 2. 使用 KVM 的虛擬化組件

記住 KVM 只是虛擬化解決方案的一部分。處理器直接提供了虛擬化支持(可以為多個操作系統虛擬化處理器)。內存可以通過 kvm 進行虛擬化(這在下一節中將會討論)。最後,I/O 通過一個稍加修改的 QEMU 進程(執行每個客戶操作系統進程的一個拷貝)進行虛擬化。

KVM 向 Linux 中引入了一種除現有的內核和用戶模式之外的新進程模式。這種新模式就稱為客戶 模式,顧名思義,它用來執行客戶操作系統代碼(至少是一部分代碼)。回想一下內核模式表示代碼執行的特權模式,而用戶模式則表示非特權模式(用於那些運行在內核之外的程序)。根據運行內容和目的,執行模式可以針對不同的目的進行定義。客戶模式的存在就是為了執行客戶操作系統代碼,但是只針對那些非 I/O 的代碼。在客戶模式中有兩種標准模式,因此客戶操作系統在客戶模式中運行可以支持標准的內核,而在用戶模式下運行則支持自己的內核和用戶空間應用程序。客戶操作系統的用戶模式可以用來執行 I/O 操作,這是單獨進行管理的。

在客戶操作系統上執行 I/O 的功能是由 QEMU 提供的。QEMU 是一個平台虛擬化解決方案,允許對一個完整的 PC 環境進行虛擬化(包括磁盤、圖形適配器和網絡設備)。客戶操作系統所生成的任何 I/O 請求都會被中途截獲,並重新發送到 QEMU 進程模擬的用戶模式中。

KVM 通過 /dev/kvm 設備提供了內存虛擬化。每個客戶操作系統都有自己的地址空間,並且是在實例化客戶操作系統時映射的。映射給客戶操作系統的物理內存實際上是映射給這個進程的虛擬內存。為了支持客戶物理地址到主機物理地址的轉換,系統維護了一組影子頁表(shadow page table)。處理器也可以通過在訪問未經映射的內存位置時使用系統管理程序(主機內核)來支持內存轉換進程。

實例化新客戶操作系統

新客戶操作系統的實例化是由一個名為 kvm 的工具提供的。這個工具可以與 kvm 模塊協同工作,使用 /dev/kvm 來加載客戶操作系統,將它與虛擬磁盤(主機操作系統中的一個普通文件)關聯起來,然後啟動客戶操作系統。

通過一組在 /dev/kvm 設備上執行的 ioctls 可以提供控制支持。當第一次打開這個特殊文件時,就會創建一個新的 VM 對象,它與一個虛擬 CPU 關聯在一起。您然後可以使用幾個 ioctls 來創建一個虛擬 CPU,檢查 kvm 版本,創建內存區域,然後啟動一個虛擬 CPU。您可以使用 kvm 命令實現這種功能。在接下來的幾節中,我們將介紹 kvm 命令,並給出幾個受支持的 ioctls 的示例。

使用 KVM

如果硬件支持的話,使用 KVM 實際上非常簡單。您需要一個具有虛擬化支持的處理器。通過查看 /proc/cpuinfo 可以知道系統是否支持虛擬化。這個文件指定了是否支持 vmx(Intel)或 svm(AMD)擴展。

接下來,您需要一個啟用了 KVM 支持的 Linux 內核。您可以在 Device Drivers > Virtualization 下的內核配置中完成這種配置。還必須啟用處理器對環境的支持。另外,還必須具有 kvm 和 qemu 用戶空間應用程序。

有了啟用了虛擬化支持的引導內核,接下來的一個步驟是為客戶操作系統創建一個磁盤映像。您可以使用 qeumu-img 來完成此操作,如下所示。注意這個映像的大小是 4GB,但是使用 QEMU 的寫時復制格式(copy-on-write,qcow)時,整個文件將根據需要增長,而不是完全占據這 4 GB 的空間。

$ qemu-img create -f qcow vm-disk.img 4G

在創建虛擬磁盤之後,就可以將客戶操作系統加載到其上。下面的例子假設客戶操作系統是在 CD-ROM 上。除了使用 CD-ROM ISO 映像來填充虛擬磁盤之外,還必須在結束時啟動這個映像。

$ kvm -no-acpi -m 384 -cdrom guestos.iso -hda vm-disk.img -boot d

Ari Kivity 已經編寫了一組測試工具來測試 KVM,而不需要全部的設備模型。下面的代碼片斷(來自於 kvm-12/user/main.c)從較高的層次上查看了 VM 的啟動(請參見 清單 1)。控制特性是由內核中的 ioctls 提供的(具體來說,在 ./linux-2.6.20/drivers/kvm/kvm_main.c 文件中)。

對 kvm_init 的調用會打開 /dev/kvm 設備,檢查版本號(由 KVM 內核模塊導出),然後分配一個 KVM 上下文對象並填充一些回調函數。kvm_create 函數會建立並映射兩個內存區域,然後使用 ioctl(KVM_CREATE_VCPU)創建一個虛擬 CPU(VCPU)。

load_file 函數然後會將映像加載到給定的 VM 的地址空間中,然後調用 kvm_run 執行該 VM(使用 ioctl KVM_RUN)。盡管這個過程非常簡單,但是它解釋了如何使用 KVM 實例化新客戶操作系統。

清單 1. 測試 KVM 系統管理程序的應用程序片斷

int main()
{
	void *vm_mem;
	kvm = kvm_init(&test_callbacks, 0);
	if (!kvm) {
	    fprintf(stderr, "kvm_init failed\n");
	    return 1;
	}
	if (kvm_create(kvm, 128 * 1024 * 1024, &vm_mem) < 0) {
	    kvm_finalize(kvm);
	    fprintf(stderr, "kvm_create failed\n");
	    return 1;
	}
	if (ac > 1)
	    if (strcmp(av[1], "-32") != 0)
		load_file(vm_mem + 0xf0000, av[1]);
	    else
		enter_32(kvm);
	if (ac > 2)
	    load_file(vm_mem + 0x100000, av[2]);
	kvm_show_regs(kvm, 0);
	kvm_run(kvm, 0);
	return 0;
}


結束語

KVM 是解決虛擬化問題的一個有趣的解決方案,但是由於它是第一個進入內核的虛擬化解決方案,很難想象它會很快用於服務器虛擬化。還有其他一些方法一直在為進入內核而競爭(例如 UML 和 Xen),但是由於 KVM 需要的修改較少,並且可以將標准內核轉換成一個系統管理程序,因此它的優勢不言而喻。

KVM 的另外一個優點是它是內核本身的一部分,因此可以利用內核的優化和改進。與其他獨立的系統管理程序解決方案相比,這種方法是一種不會過時的技術。KVM 兩個最大的缺點是需要較新的能夠支持虛擬化的處理器,以及一個用戶空間的 QEMU 進程來提供 I/O 虛擬化。但是不論好壞,KVM 位於內核中,這對於現有解決方案來說是一個巨大的飛躍。

Copyright © Linux教程網 All Rights Reserved