云計(jì)算底層技術(shù)之 KVM 初探
KVM 是業(yè)界最為流行的 Hypervisor,全稱是 Kernel-based Virtual Machine。它是作為 Linux kernel 中的一個(gè)內(nèi)核模塊而存在,模塊名為 kvm.ko,也可以看作是一個(gè)進(jìn)程,被內(nèi)核調(diào)度并管理,從 Linux 2.6.20 版本開始被完全正式加入到內(nèi)核的主干開發(fā)和正式發(fā)布代碼中。 KVM 主要用于管理 CPU 和內(nèi)存的虛擬化,IO 設(shè)備的虛擬化則是由 Qemu 來(lái)完成。為什么會(huì)有這樣的分工,請(qǐng)繼續(xù)往下看。
KVM 與 Qemu 的前世今生
Qemu 是一個(gè)純軟件實(shí)現(xiàn)的開源「模擬」軟件,它能夠模擬整套虛擬機(jī)的實(shí)現(xiàn),包括 CPU、內(nèi)存、各種 IO 設(shè)備、鼠標(biāo)、鍵盤、USB 、網(wǎng)卡、聲卡等等,基本上沒(méi)有它不能模擬的。有人可能會(huì)比較疑惑它跟 KVM 之間到底有何關(guān)系,我們可以把它們看成是合作關(guān)系,好基友,誰(shuí)都離不開彼此。
KVM 離不開 Qemu。KVM 實(shí)現(xiàn)初期,為了簡(jiǎn)化開發(fā)和代碼重用,在 Qemu 的基礎(chǔ)上進(jìn)行了修改,主要是將比較耗性能的 CPU 虛擬化和內(nèi)存虛擬化部分移到了內(nèi)核中實(shí)現(xiàn),保留 IO 虛擬化模塊在用戶空間實(shí)現(xiàn)。這樣的做法主要是考慮到性能的原因,CPU 和 內(nèi)存虛擬化是非常復(fù)雜的虛擬化模塊,而且使用非常頻繁,如果實(shí)現(xiàn)在用戶空間的話,用戶態(tài)和內(nèi)核態(tài)的頻繁切換勢(shì)必會(huì)對(duì)性能造成很大的影響。那為什么要單獨(dú)保留 IO 虛擬化在用戶空間呢,這個(gè)也是權(quán)衡之下的結(jié)果,首先 IO 設(shè)備太多了,其次 IO 虛擬化相對(duì)其他兩個(gè)模塊使用不是很頻繁,開銷會(huì)小一些,所以,為了盡可能保持內(nèi)核的純凈性,才有了這樣的分配。
Qemu 離不開 KVM。上面也說(shuō)了,Qemu 是一個(gè)純軟件的實(shí)現(xiàn),運(yùn)行在用戶空間,性能非常低下,所以,從 Qemu 的角度,可以說(shuō)是 Qemu 使用了 KVM 的虛擬化功能,為自身虛擬機(jī)提供加速。
早期兩者還沒(méi)有區(qū)分(沒(méi)有同居),KVM 修改的模塊叫 qemu-kvm,到 Qemu1.3 版本之后,兩者就合二為一了(同居啦),如果我們?cè)谟?Qemu 創(chuàng)建虛擬機(jī)時(shí),要加載 KVM 模塊,需要為其指定參數(shù) --enable-kvm。
KVM 與 Qemu 的關(guān)系
KVM 架構(gòu)
KVM 是基于硬件虛擬化(Intel VT 或 AMD-V)實(shí)現(xiàn)的一套虛擬化解決方案,通過(guò)以上一個(gè)與 Qemu 關(guān)系的分析,我們基本上知道它在虛擬化領(lǐng)域處在一個(gè)什么樣的地位。它其實(shí)只負(fù)責(zé) CPU 和內(nèi)存的虛擬化,不負(fù)責(zé)任何設(shè)備的模擬,而是提供接口給用戶空間的 Qemu 來(lái)模擬。這個(gè)接口是 /dev/kvm ,
Qemu 通過(guò) /dev/kvm 接口設(shè)置一個(gè)虛擬機(jī)的地址空間,然后向它提供模擬好的 I/O 設(shè)備,并將相關(guān)的設(shè)備回顯操作映射到宿主機(jī),完成整個(gè) I/O 設(shè)備的虛擬化操作。
KVM 架構(gòu)
/dev/kvm 接口是 Qemu 和 KVM 交互的“橋梁”,基本的原理是:/dev/kvm 本身是一個(gè)設(shè)備文件,這就意味著可以通過(guò) ioctl 函數(shù)來(lái)對(duì)該文件進(jìn)行控制和管理,從而可以完成用戶空間與內(nèi)核空間的數(shù)據(jù)交互。在 KVM 與 Qemu 的通信過(guò)程主要就是一系列針對(duì)該設(shè)備文件的 ioctl 調(diào)用。
我就拿創(chuàng)建虛擬機(jī)舉個(gè)例子,虛擬機(jī)本質(zhì)上是宿主機(jī)的一個(gè)進(jìn)程,包括用戶態(tài)數(shù)據(jù)結(jié)構(gòu)和內(nèi)核態(tài)數(shù)據(jù)結(jié)構(gòu),用戶態(tài)部分由 Qemu 創(chuàng)建并初始化,內(nèi)核態(tài)部分則由 KVM 來(lái)完成,完成后會(huì)返回一個(gè)文件句柄來(lái)代表所創(chuàng)建的虛擬機(jī),針對(duì)該文件句柄的 ioctl 調(diào)用就可以對(duì)虛擬機(jī)進(jìn)行相應(yīng)的管理,比如建立虛擬機(jī)地址空間和宿主機(jī)地址空間的映射關(guān)系,創(chuàng)建多個(gè)線程(虛擬處理器,vCPU)來(lái)供虛擬機(jī)使用等,對(duì)于創(chuàng)建出的 vCPU,也會(huì)生成相應(yīng)的文件句柄,同樣,對(duì) vCPU 的文件句柄的 ioctl 調(diào)用就可以對(duì) vCPU 進(jìn)行管理。
關(guān)于這塊的具體細(xì)節(jié),后面會(huì)有文章來(lái)專門討論。
VMM 管理工具 —— libvirt
目前,虛擬化這個(gè)領(lǐng)域可以說(shuō)是百花齊放,針對(duì)不同的場(chǎng)景提出了很多的虛擬化解決方案,KVM、Xen、VMware、VirtualBox、Hyper-V 等等,具體的這些方案有什么特點(diǎn),可以看前文「虛擬化技術(shù)總覽 」。這么多方案勢(shì)必有很多通用的模塊,不同之處可能在于,與不同硬件廠商的適配上,為了支持更多廠商,以及應(yīng)用更多的領(lǐng)域,有很多 IaaS 解決方案需要融合多種虛擬化技術(shù)。這個(gè)時(shí)候如果有一個(gè)平臺(tái)類的管理工具就會(huì)非常方便,libvirt 就是這樣一個(gè)工具。

libvirt 架構(gòu)
libvirt 除了能夠支持多種虛擬化方案之外,還支持 OpenVZ、LXC 等容器虛擬化系統(tǒng)。它提供一套完善的虛擬機(jī)管理工具,支持 GUI 和命令行的形式,如 virsh、virt-install、virt-manager。由于它的通用性和易管理,很多云計(jì)算框架平臺(tái)都在底層使用 libvirt 的 API 來(lái)管理虛擬機(jī),比如 OpenStack、OpenNebula、Eucalyptus 等。這個(gè)工具我們僅僅提一下,有興趣的可以裝個(gè)玩玩。
下面給出 KVM 和 Qemu 的 git 路徑,有興趣的可以把源碼下下來(lái)研究下。
- kvm.git:
- git clone git://git.kernel.org/pub/scm/virt/kvm/kvm.git
- qemu.git(包括了 kvm):
- git clone git://git.qemu-project.org/qemu.git