虛擬化系列(一) - 初探KVM與QEMU

前言 


本系列文章前面幾章應該都是着重虛擬化技術原理的介紹,並不涉及到具體的代碼。因爲本人認爲
你如果連虛擬化的原理和組成部分都分不清楚的話,那麼現在直接討論代碼簡直是天方夜譚。但是後面
文章小編也會跟着大家一起從搭建一個虛擬化環境開始一步一步深入到代碼和調試。所以前幾章不會涉及到
代碼的層面。

最近越來越感覺到程序員到了中年後,一定要成爲要在一個領域型的研發人員,如果那時候還只是會點什麼c++、java語言那是很尷尬的。所謂的領域就是類似於雲計算、qemu、TCPIP協議,分佈式、計算機圖形等等這樣的領域。這是我工作的一位前輩跟我說。我現在越來越認同。因爲語言只是輔助工具。這也是我爲什麼想寫這一系列文章的原因。(當然小編還年輕哈,嘿嘿)

1 KVM 簡介 


KVM全稱是Kernel Virtual Machine(內核虛擬機)。KVM虛擬機是由一個以色列的創業公司Queranet開發的。作爲他們的VDI產品的虛擬機。爲了簡化開發,KVM的開發人員並沒有從底層開始新寫一個Hypervisor,而是選擇了基於Linux kernel,通過加載KVM的模塊使得LinuxKernel本生變成了一個Hypervisor即VMM。所以KVM是實現架構是宿主模式(關於宿主模式不懂,請參考前一章虛擬化技術總覽)。


1.1 KVM架構 


前面已經說了KVM是作爲特殊內核模塊加載到linux內核中,所以我們可以將KVM看做操作系統功能的擴張。因此其最大的優勢在於可以充分利用現有的操作系統,不必自己實現物理資源的管理和調度算法,所以實現起來比較簡潔。但是,正所謂“成也蕭何,敗也蕭何”。既然KVM依賴操作系統實現管理和調度,就同樣也會受到宿主操作系統的一些限制。例如,通常無法僅僅爲了虛擬化的優化,而對操作系統做出修改。

而XEN框架的虛擬機是專門爲虛擬化開發一個微內核,所以其資源和調度策略完全是針對虛擬機的特性而開發,所以XEN框架的VMM可以完全修改內核來達到虛擬機性能的優化。

架構圖 1-1-1:

說到這裏我想起了在工作中碰到的一個實例:
假如你同時使用過KVM架構的VDI平臺和Ctrix Xen架構VDI平臺,你會發現在在宿主(host)機CPU佔有率高達70以上後,KVM的時鐘頻率有所延遲。而XEN框架是有所不會的。還記得在我服的時候,我服的VDI產品會碰到一個問題就是當Host機在CPU高負債的時候,VDI聲音會產生一些滋滋的雜音。而ctrix的VDI產品卻不會。Ctrix專門爲XEN框架做了時鐘方面的優化,從內核成就保證時鐘頻率的正確性。

原本10ms採樣一次音頻數據會因爲高負債導致12秒採樣一次,因此會導致聲音採集的數據不準。當初解決這個問題是我一個同事。爲了這個問題頭髮都快沒了。最後還是解決了,但是由於保密,方案就不跟大家在這裏分享了。只是拿這個來舉一個例子來說明XEN架構的優勢。當然XEN架構也是有劣勢的,因爲XEN架構什麼都需要自己實現,開發難度和成本都很大。


1.2 KVM功能概覽 


前面已經說到KVM時作爲Linux kernel中的一個內核模塊而存在,模塊名爲KVM.KO。所以KVM也可以看做是一個進程只是被Linux內核模塊管理並調度。所以在KVM架構中,virtual machine的實現爲常規的Linux進程,是由表中Linux調度程序進行調讀。

但是KVM本身不執行任何模擬,需要用戶空間程序通過/dev/kvm接口設置一個guest機的地址空間,向它提供模擬I/O,並將它的視頻顯示映射回host機的顯示屏。在目前業界通常是用qemu來充當上文提到的用戶空間程序。

此外KVM還支持混合虛擬化,其中的半虛擬化驅動程序安裝在guest機操作系統中,允許虛擬機使用優化過IO接口,而不是模擬的設備,從而爲網絡和塊設備提高性能的I/O。KVM半虛擬化驅動程序使用IVM和Red Hat聯合Linux社區開發的VirtIo標準,它是一個與虛擬機管理程序獨立的、構建設備驅動程序接口。允許爲多個虛擬機使用一組相同的設備驅動程序,能夠實現更爲初設虛擬機交互性。


2 Qemu程序 


Qemu本身並不是KVM的一部分,其自身就是著名的開源虛擬機軟件。與KVM不同的是QEMU虛擬機是一個軟件虛擬化架構。所以其性能非常低下。但是其優勢是它能夠模擬整套虛擬機的實現,包括 各種 IO 設備、鼠標、鍵盤、USB 、網卡、聲卡等等,以及KVM也能模擬CPU、內存設備。

2.1 KVM和qemu的關係 


在KVM實現初期,爲了簡化開發和代碼服用,KVM並沒有實現所有的設備模擬,只是在qemu的基礎上進行了修改,只有對性能要求比較高的虛擬設備的模擬放到內核KVM模塊,比如CPU和內存,大部分的輸入輸出設備還是會交給上文介紹用戶態程序QEMU來負責。那爲什麼要單獨保留 IO 虛擬化在用戶空間呢,這個也是權衡之下的結果,首先 IO 設備太多了,其次 IO 虛擬化相對其他兩個模塊使用不是很頻繁,開銷會小一些,所以,爲了儘可能保持內核的純淨性,纔有了這樣的分配。所以目前業界KVM和qemu已經緊密的結合在了一起。也就是KVM離不開QEMU,QEMU也脫離不了KVM.

反過來,從qemu的角度來看,也可以說是QEMU使用了KVM模塊的CPU和內存虛擬化的功能,爲自己虛擬機提供硬件虛擬機化的加速,從而極大的提高了虛擬機的性能。初次之外,虛擬機的配置和創建,虛擬機運行依賴的外設,以及針對虛擬機的特殊技術(比如動態遷移)都是qemu自己實現的。

目前KVM已經與QEMU合二爲一,所有特定於KVM的代碼也都合入了QEMU,當需要與KVM模塊配合使用的時候,只需要在QEMU命令行加上 --enable-kvm就可以。


2.2 KVM與QEMU調用關係(QEMU-KVM) 


KVM模塊與用戶空間QEMU的通信接口主要是一系列針對特殊塊文件(/dev/kvm)IOCTL調用,所以說/dev/kvm接口是qemu和KVM交互橋樑。那麼這個特殊塊文件(/dev/kvm)是誰創建的呢,當然是KVM。在KVM加載後,其會創建一個特殊設備文件/dev/kvm(例如上文提到架構圖 1-1-1)並等待來自上層QEMU的IOCTL調用。

我們就拿創建虛擬機舉個例子,虛擬機本質上是宿主機的一個進程,包括用戶態數據結構和內核態數據結構,用戶態部分由 Qemu 創建並初始化,內核態部分則由 KVM 來完成,完成後會返回一個文件句柄來代表所創建的虛擬機,針對該文件句柄的 ioctl 調用就可以對虛擬機進行相應的管理,比如建立虛擬機地址空間和宿主機地址空間的映射關係,創建多個線程(虛擬處理器,vCPU)來供虛擬機使用等,對於創建出的 vCPU,也會生成相應的文件句柄,同樣,對 vCPU 的文件句柄的 ioctl 調用就可以對 vCPU 進行管理。

下面我來看一張QEMU-KVM架構圖就更加明白KVM與QEMU交互了:
 


這個時候我們再仔細想一下,在QEMU-KVM中,KVM只負責模擬CPU和內存,QEMU負責模擬其他所有IO設備,衆所周知網卡設備和磁盤設備對性能的要求也十分高,那麼QEMU-KVM是不是做過優化呢?當然,QEMU-KVM爲了優化Network,Disk等耗性能的設備,於是引入pass through半虛擬化設備(virio_blk,virio_net)來提高性能。我們前文提到的半虛擬化驅動就是爲這些設備來服務的,目的是提高這些設備性能。


從上圖中看到我們可以利用virio_blk,virio_net這些半虛擬化設備直接在其驅動中將網絡訪問和磁盤訪問直接轉到Linux kernel中的Virtio驅動,而不再經過QEMU和KVM的IOCTL調用。這樣性能會大大提升。(爲什麼會提升會在以後文章中講到,這個需要你去詳細瞭解KVM和qemu調用過程)


 結束語 


這篇文章主要是介紹KVM,還有KVM和QEMU前世今生以及KVM和QEMU工作流程。相信大家讀完這盤文章後會對KVM和qemu有一個大概的認識。接下來的一下就是跟着大家一起從構建KVM環境來玩玩一KVM了。因此你提前準備一臺Linux host主機哦。其中會涉及到KVM編譯與安裝、qemu-kvm編譯與安裝哦。


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章