初探KVM虛擬化技術(shù):新手指南
首先了解一下虛擬化的概念
虛擬化是指對資源的邏輯抽象、隔離、再分配、管理的一個過程,通常對虛擬化的理解有廣義狹義之分。廣義包括平臺虛擬化、應(yīng)用程序虛擬化、存儲虛擬化、網(wǎng)絡(luò)虛擬化、設(shè)備虛擬化等等。狹義的虛擬化專門指計算機(jī)上模擬運(yùn)行多個操作系統(tǒng)平臺。
虛擬化的目的是通過對硬件資源的抽象和管理,實現(xiàn)資源的高效利用、靈活性、隔離和安全性,從而提供更高效、可靠和可擴(kuò)展的計算環(huán)境。
虛擬化技術(shù)和云計算的關(guān)系:
維基百科云計算定義:云計算是一種通過因特網(wǎng)以服務(wù)的方式提供動態(tài)可伸縮的虛擬化的資源的計算模式。
云計算是建立在虛擬化技術(shù)的基礎(chǔ)上,通過互聯(lián)網(wǎng)提供按需的計算資源和服務(wù)。云計算提供了虛擬化技術(shù)的更高層次的抽象和服務(wù),如虛擬機(jī)實例、容器服務(wù)、函數(shù)計算等。它提供了多租戶環(huán)境、自動化管理和彈性擴(kuò)展等特性,使用戶可以根據(jù)實際需求快速獲取和釋放計算資源。
虛擬化技術(shù)為云計算提供了基礎(chǔ)的資源池和資源管理能力,使云計算可以實現(xiàn)資源的共享和動態(tài)分配。而云計算為虛擬化技術(shù)提供了更廣闊的應(yīng)用場景和服務(wù),使其得以更好地應(yīng)用于實際業(yè)務(wù)和服務(wù)交付。
KVM虛擬化技術(shù)
KVM全稱是Kernel-based Virtual Machine,即基于內(nèi)核的虛擬機(jī),是采用硬件輔助虛擬化技術(shù)的全虛擬化解決方案。對于I/O設(shè)備(如硬盤、網(wǎng)卡等),KVM即支持QEMU仿真的全虛,也支持virtio方式的半虛。KVM從誕生開始就定位于基于硬件虛擬化支持的全虛實現(xiàn),由于其在Linux內(nèi)核2.6版本后被集成,通過內(nèi)核加載模式使得Linux內(nèi)核變成一個事實上的Hypervisor(虛擬機(jī)管理器,也叫VMM(Virtual Machine Monitor)),但是硬件管理還是由Linux Kernel來完成。
Hypervisor和VMM:
可以把hypervisor和VMM(virtual machine monitor)理解為同一樣?xùn)|西,它們都是用于監(jiān)控和控制虛擬機(jī)操作系統(tǒng)。在創(chuàng)建虛擬機(jī)的過程中,會虛擬出一整套的硬件資源,例如硬盤、內(nèi)存、CPU、網(wǎng)絡(luò)設(shè)備等,這些工作都是由hypervisor負(fù)責(zé),除此之外,它還負(fù)責(zé)虛擬系統(tǒng)運(yùn)行過程的資源分配和虛擬機(jī)的生命周期管理等。
一個KVM客戶機(jī)就對應(yīng)一個Linux進(jìn)程,每個vCPU對應(yīng)這個進(jìn)程下的一個線程,還有單獨處理I/O的線程,屬于同一個進(jìn)程組。所以,宿主機(jī)上Linux Kernel可以像調(diào)度普通Linux進(jìn)程一樣調(diào)度KVM虛擬機(jī),這種機(jī)制使得Linux Kernel的進(jìn)程優(yōu)化和調(diào)度功能優(yōu)化等策略,都能用于KVM虛擬機(jī)。比如:通過進(jìn)程權(quán)限限定功能可以限制KVM客戶機(jī)的權(quán)限和優(yōu)先級等。
由于KVM嵌入Linux內(nèi)核中,除了硬件輔助虛擬化(如VT-d)的硬件設(shè)備能被虛擬機(jī)看見外,其他的I/O設(shè)備都是QEMU模擬出來的,所以QEMU是KVM天生的好基友。
可以說KVM就是在硬件輔助虛擬化技術(shù)之上構(gòu)建起來的VMM。但并非要求所有硬件虛擬化技術(shù)都支持才能運(yùn)行KVM虛擬化,KVM對硬件最低的依賴是CPU的硬件虛擬化支持(比如:Intel的VT-x技術(shù)和AMD的AMD-V技術(shù)),而其他的內(nèi)存和I/O的硬件虛擬化支持,會讓整個KVM虛擬化下的性能得到更多的提升。所以在虛擬機(jī)部署KVM功能時,首先就是要查看宿主機(jī)Host(也就是主機(jī)上的虛擬機(jī),這里是在VMware Workstations的虛擬機(jī)打開CPU虛擬化功能。

然后在Linux系統(tǒng)中可以通過如下命令確定支持VT-x功能:
如果什么輸出都沒有,那說明你的系統(tǒng)并沒有支持虛擬化的處理 ,不能使用KVM。

"vmx" 是 Intel CPU 的虛擬化技術(shù)標(biāo)識,"svm" 是 AMD CPU 的虛擬化技術(shù)標(biāo)識。
安裝KVM及相關(guān)的工具:
-?qemu-kvm
:KVM虛擬化的基本包
-?libvirt-daemon-system
:libvirt守護(hù)程序,提供API和管理虛擬化功能
-?libvirt-clients
:包含用于與libvirt守護(hù)程序通信的客戶端實用程序
-?bridge-utils
:用于創(chuàng)建和管理網(wǎng)絡(luò)橋接的工具集
-?virt-manager
:用于管理虛擬機(jī)的圖形化工具
確認(rèn)libvirtd服務(wù)已啟動并運(yùn)行:
通過virt-manger(圖形化工具)來創(chuàng)建或者管理虛擬機(jī)

或者通過virsh(命令行工具)來創(chuàng)建或者管理虛擬機(jī)

下面是一些常用的virsh命令:
virsh list
: 列出當(dāng)前運(yùn)行的虛擬機(jī)virsh start <domain>
: 啟動指定名稱的虛擬機(jī)virsh shutdown <domain>
: 關(guān)閉指定名稱的虛擬機(jī)virsh reboot <domain>
: 重啟指定名稱的虛擬機(jī)virsh create <xmlfile>
: 根據(jù)指定的XML文件創(chuàng)建虛擬機(jī)virsh destroy <domain>
: 強(qiáng)制停止指定名稱的虛擬機(jī)virsh undefine <domain>
: 刪除指定名稱的虛擬機(jī)配置virsh console <domain>
: 進(jìn)入指定名稱的虛擬機(jī)控制臺virsh dominfo <domain>
: 顯示指定名稱的虛擬機(jī)信息virsh domstate <domain>
: 顯示指定名稱的虛擬機(jī)狀態(tài)
接下來分析一下kvm的Makefile :


可以看出kvm的Makefile主要生成三個模塊,kvm.o和kvm-intel.o、kvm-amd.o。
kvm.o是kvm的核心模塊,kvm基本只實現(xiàn)硬件輔助虛擬化相關(guān)部分,而不支持的用Qemu來模擬實現(xiàn)。
kvm-intel.o是intel平臺架構(gòu)虛擬化模塊,平臺相關(guān)
kvm-amd.o是amd架構(gòu)虛擬化模塊,平臺相關(guān)
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ?


KVM架構(gòu)
KVM是在硬件虛擬化支持下的全虛擬化技術(shù),所以它能在相應(yīng)硬件上運(yùn)行幾乎所有的操作系統(tǒng),KVM虛擬化的核心主要由以下兩個模塊組成:
1)KVM內(nèi)核模塊,它屬于標(biāo)準(zhǔn)Linux內(nèi)核的一部分,是一個專門提供虛擬化功能的模塊,主要負(fù)責(zé)CPU和內(nèi)存的虛擬化,包括:客戶機(jī)的創(chuàng)建、虛擬內(nèi)存的分配、CPU執(zhí)行模式的切換、vCPU寄存器的訪問、vCPU的執(zhí)行。
2)QEMU用戶態(tài)工具,它是一個普通的Linux進(jìn)程,為客戶機(jī)提供設(shè)備模擬的功能,包括模擬BIOS、PCI/PCIE總線、磁盤、網(wǎng)卡、顯卡、聲卡、鍵盤、鼠標(biāo)等。同時它通過ioctl系統(tǒng)調(diào)用與內(nèi)核態(tài)的KVM模塊進(jìn)行交互。

如上圖中,在KVM虛擬化架構(gòu)下,每個客戶機(jī)就是一個QEMU進(jìn)程,在一個宿主機(jī)上有多少個虛擬機(jī)就會有多少個QEMU進(jìn)程??蛻魴C(jī)中的每一個虛擬CPU對應(yīng)QEMU進(jìn)程中的一個執(zhí)行線程,一個宿主機(jī)Host中只有一個KVM內(nèi)核模塊,所有虛擬機(jī)都與這個內(nèi)核模塊進(jìn)行交互。
KVM內(nèi)核模塊
VM內(nèi)核模塊是KVM虛擬化的核心模塊,它在內(nèi)核中由兩部分組成:一個是處理器架構(gòu)無關(guān)的部分,用lsmod命令中可以看到,叫作kvm模塊;另一個是處理器架構(gòu)相關(guān)的部分,在Intel平臺上就是kvm_intel這個內(nèi)核模塊。如下圖所示,KVM的主要功能是初始化CPU硬件,打開虛擬化模式,然后將虛擬機(jī)運(yùn)行在虛擬環(huán)境下,并對虛擬機(jī)的運(yùn)行提供一定的支持。

以Intel CPU架構(gòu)服務(wù)器為例,KVM打開并初始化硬件以支持虛擬機(jī)運(yùn)行的過程如下:
Step1:在被內(nèi)核加載的時候,KVM模塊會先初始化內(nèi)部的數(shù)據(jù)結(jié)構(gòu)。
Step2:做好準(zhǔn)備之后,KVM模塊檢測系統(tǒng)當(dāng)前的CPU,然后打開CPU控制寄存器CR4中的虛擬化模式開關(guān),并通過執(zhí)行VMXON指令將宿主操作系統(tǒng)(包括KVM模塊本身)置于CPU虛擬化模式中的根模式root operation。
Step3:KVM模塊創(chuàng)建特殊設(shè)備文件/dev/kvm并等待來自用戶空間的命令。
Step4:后續(xù)虛擬機(jī)的創(chuàng)建和運(yùn)行,其本質(zhì)上就是是一個用戶空間的QEMU和內(nèi)核空間的KVM模塊相互配合的過程。
這里面的/dev/kvm這個設(shè)備比較關(guān)鍵,它可以被當(dāng)作一個標(biāo)準(zhǔn)的字符設(shè)備,用來緩存用戶空間與內(nèi)核空間切換的上下文,也就是ioctl調(diào)用上下文,是KVM模塊與用戶空間QEMU的通信接口。:
QEMU用戶態(tài)設(shè)備模擬
QEMU原本就是一個著名的開源虛擬機(jī)軟件項目,既是一個功能完整的虛擬機(jī)監(jiān)控器,也在QEMU-KVM的軟件棧中承擔(dān)設(shè)備模擬的工作。
QEMU最初實現(xiàn)的虛擬機(jī)是一個純軟件的實現(xiàn),也就是我們常說的通過二進(jìn)制翻譯來實現(xiàn)虛擬機(jī)的CPU指令模擬,所以性能比較低。但是,其優(yōu)點是跨平臺,甚至可以支持客戶機(jī)與宿主機(jī)并不是同一個架構(gòu),比如在x86平臺上運(yùn)行ARM客戶機(jī)。同時,QEMU能與主流的Hypervisor完美契合,包括:Xen、KVM、Hyper-v,以及VMware各種Hypervisor等,為上述這些Hypervisor提供虛擬化I/O設(shè)備。
而QEMU與KVM密不可分的原因,就是我們常說的QEMU-KVM軟件協(xié)議棧。虛擬機(jī)運(yùn)行期間,QEMU會通過KVM內(nèi)核模塊提供的系統(tǒng)調(diào)用ioctl進(jìn)入內(nèi)核,由KVM內(nèi)核模塊負(fù)責(zé)將虛擬機(jī)置于處理器的特殊模式下運(yùn)行。一旦遇到虛擬機(jī)進(jìn)行I/O操作時,KVM內(nèi)核模塊會從上次的系統(tǒng)調(diào)用ioctl的出口處返回QEMU,由QEMU來負(fù)責(zé)解析和模擬這些設(shè)備。除此之外,虛擬機(jī)的配置和創(chuàng)建,虛擬機(jī)運(yùn)行依賴的虛擬設(shè)備,虛擬機(jī)運(yùn)行時的用戶操作環(huán)境和交互,以及一些針對虛擬機(jī)的特殊技術(shù),比如動態(tài)遷移,都是由QEMU自己實現(xiàn)的。
總之,KVM 本身不執(zhí)行任何模擬,需要用戶空間應(yīng)用程序?QEMU
?通過?/dev/kvm
?接口設(shè)置一個客戶機(jī)虛擬服務(wù)器的地址空間,向它提供模擬的 I/O,KVM 模塊實現(xiàn)處理器的虛擬化和內(nèi)存虛擬化。在硬件虛擬化技術(shù)的支持下,內(nèi)核的 KVM 模塊與 QEMU 的設(shè)備模擬協(xié)同工作,構(gòu)成一套和物理計算機(jī)系統(tǒng)完全一致的虛擬化計算機(jī)軟硬件系統(tǒng)。
監(jiān)控KVM事件
bcc程序中提供了一個例子用來監(jiān)控kvm相關(guān)事件
源碼:
kvm_hypercall.pyhttps://github.com/iovisor/bcc/blob/master/examples/tracing/kvm_hypercall.py
運(yùn)行結(jié)果如下:


這個程序使用了kvm相關(guān)的以下幾個tracepoint靜態(tài)跟蹤點:
kvm_entry:當(dāng)虛擬機(jī)的vCPU(虛擬中央處理單元)從主機(jī)CPU切換到虛擬機(jī)CPU并開始執(zhí)行虛擬指令時,觸發(fā)kvm_entry跟蹤點,vcpu_id用于標(biāo)識特定的虛擬CPU。
kvm_exit:當(dāng)虛擬機(jī)的vCPU執(zhí)行完一段虛擬指令并從虛擬機(jī)CPU切換回主機(jī)CPU時,觸發(fā)kvm_exit跟蹤點,exit_reason表示虛擬cpu推出到主機(jī)cpu的具體原因。
kvm_hypercall:用于跟蹤虛擬機(jī)中的超級調(diào)用(hypercall)。當(dāng)虛擬機(jī)的Guest OS需要執(zhí)行一些更高權(quán)限的操作(如:頁表的更新、對物理資源的訪問等)時,由于自身在非特權(quán)域無法完成這些操作,于是便通過超級調(diào)用交給Hypervisor來完成這些操作,其中nr代表超級調(diào)用號。
kvm_exit中的exit_reason:
上圖中的12,18,32分別代表訪問任務(wù)優(yōu)先級寄存器(TP),操作系統(tǒng)特定事件,處理器處于AP復(fù)位保持狀態(tài)。

hypercall_nr(超級調(diào)用號):
5號超級調(diào)用表示請求Hypervisor程序?qū)⑻幱谛菝郀顟B(tài)的 vCPU 喚醒。

原文作者:南帥波
