KVM 是業界最為流行的 Hypervisor,全稱是 Kernel-based Virtual Machine。它是作為 Linux kernel 中的一個核心子產品而存在,子產品名為 kvm.ko,也可以看作是一個程序,被核心排程并管理,從 Linux 2.6.20 版本開始被完全正式加入到核心的主幹開發和正式釋出代碼中。 KVM 主要用于管理 CPU 和記憶體的虛拟化,IO 裝置的虛拟化則是由 Qemu 來完成。為什麼會有這樣的分工,請繼續往下看。
Qemu 是一個純軟體實作的開源「模拟」軟體,它能夠模拟整套虛拟機的實作,包括 CPU、記憶體、各種 IO 裝置、滑鼠、鍵盤、USB 、網卡、聲霸卡等等,基本上沒有它不能模拟的。有人可能會比較疑惑它跟 KVM 之間到底有何關系,我們可以把它們看成是合作關系,好基友,誰都離不開彼此。
KVM 離不開 Qemu。KVM 實作初期,為了簡化開發和代碼重用,在 Qemu 的基礎上進行了修改,主要是将比較耗性能的 CPU 虛拟化和記憶體虛拟化部分移到了核心中實作,保留 IO 虛拟化子產品在使用者空間實作。這樣的做法主要是考慮到性能的原因,CPU 和 記憶體虛拟化是非常複雜的虛拟化子產品,而且使用非常頻繁,如果實作在使用者空間的話,使用者态和核心态的頻繁切換勢必會對性能造成很大的影響。那為什麼要單獨保留 IO 虛拟化在使用者空間呢,這個也是權衡之下的結果,首先 IO 裝置太多了,其次 IO 虛拟化相對其他兩個子產品使用不是很頻繁,開銷會小一些,是以,為了盡可能保持核心的純淨性,才有了這樣的配置設定。
Qemu 離不開 KVM。上面也說了,Qemu 是一個純軟體的實作,運作在使用者空間,性能非常低下,是以,從 Qemu 的角度,可以說是 Qemu 使用了 KVM 的虛拟化功能,為自身虛拟機提供加速。
早期兩者還沒有區分(沒有同居),KVM 修改的子產品叫 qemu-kvm,到 Qemu1.3 版本之後,兩者就合二為一了(同居啦),如果我們在用 Qemu 建立虛拟機時,要加載 KVM 子產品,需要為其指定參數 --enable-kvm。

KVM 是基于硬體虛拟化(Intel VT 或 AMD-V)實作的一套虛拟化解決方案,通過以上一個與 Qemu 關系的分析,我們基本上知道它在虛拟化領域處在一個什麼樣的地位。它其實隻負責 CPU 和記憶體的虛拟化,不負責任何裝置的模拟,而是提供接口給使用者空間的 Qemu 來模拟。這個接口是 /dev/kvm,
Qemu 通過 /dev/kvm 接口設定一個虛拟機的位址空間,然後向它提供模拟好的 I/O 裝置,并将相關的裝置回顯操作映射到主控端,完成整個 I/O 裝置的虛拟化操作。
/dev/kvm 接口是 Qemu 和 KVM 互動的“橋梁”,基本的原理是:/dev/kvm 本身是一個裝置檔案,這就意味着可以通過 ioctl 函數來對該檔案進行控制和管理,進而可以完成使用者空間與核心空間的資料互動。在 KVM 與 Qemu 的通信過程主要就是一系列針對該裝置檔案的 ioctl 調用。
我就拿建立虛拟機舉個例子,虛拟機本質上是主控端的一個程序,包括使用者态資料結構和核心态資料結構,使用者态部分由 Qemu 建立并初始化,核心态部分則由 KVM 來完成,完成後會傳回一個檔案句柄來代表所建立的虛拟機,針對該檔案句柄的 ioctl 調用就可以對虛拟機進行相應的管理,比如建立虛拟機位址空間和主控端位址空間的映射關系,建立多個線程(虛拟處理器,vCPU)來供虛拟機使用等,對于建立出的 vCPU,也會生成相應的檔案句柄,同樣,對 vCPU 的檔案句柄的 ioctl 調用就可以對 vCPU 進行管理。
關于這塊的具體細節,後面會有文章來專門讨論。
目前,虛拟化這個領域可以說是百花齊放,針對不同的場景提出了很多的虛拟化解決方案,KVM、Xen、VMware、VirtualBox、Hyper-V 等等,具體的這些方案有什麼特點,可以看前文「虛拟化技術總覽」。這麼多方案勢必有很多通用的子產品,不同之處可能在于,與不同硬體廠商的适配上,為了支援更多廠商,以及應用更多的領域,有很多 IaaS 解決方案需要融合多種虛拟化技術。這個時候如果有一個平台類的管理工具就會非常友善,libvirt 就是這樣一個工具。
libvirt 除了能夠支援多種虛拟化方案之外,還支援 OpenVZ、LXC 等容器虛拟化系統。它提供一套完善的虛拟機管理工具,支援 GUI 和指令行的形式,如 virsh、virt-install、virt-manager。由于它的通用性和易管理,很多雲計算架構平台都在底層使用 libvirt 的 API 來管理虛拟機,比如 OpenStack、OpenNebula、Eucalyptus 等。這個工具我們僅僅提一下,有興趣的可以裝個玩玩。
下面給出 KVM 和 Qemu 的 git 路徑,有興趣的可以把源碼下下來研究下。
我的部落格即将入駐“雲栖社群”,誠邀技術同仁一同入駐。
PS:對雲計算感興趣的小夥伴可以關注我的微信公衆号:aCloudDeveloper,專注雲計算領域,堅持分享幹貨。