深入淺出 kvm qemu libvirt




在所謂的kvm技術中,應用到的其實有2個東西:qemu+kvm
kvm負責cpu虛擬化+內存虛擬化,實現了cpu和內存的虛擬化,但kvm不能模擬其他設備;
qemu是模擬IO設備(網卡,磁盤),kvm加上qemu之后就能實現真正意義上服務器虛擬化。
因為用到了上面兩個東西,所以一般都稱之為qemu-kvm。
libvirt則是調用kvm虛擬化技術的接口用於管理的,用libvirt管理方便,直接用qemu-kvm的接口太繁瑣。



Qemu

Qemu是一個模擬器,它向Guest OS模擬CPU和其他硬件,Guest OS認為自己和硬件直接打交道,其實是同Qemu模擬出來的硬件打交道,Qemu將這些指令轉譯給真正的硬件。

 

由於所有的指令都要從Qemu里面過一手,因而性能較差wKiom1WdDYyjiVZiAAECBtAEQ5E590.jpg

KVM

 

KVM是linux內核的模塊,它需要CPU的支持,采用硬件輔助虛擬化技術Intel-VT,AMD-V,內存的相關如Intel的EPT和AMD的RVI技術,Guest OS的CPU指令不用再經過Qemu轉譯,直接運行,大大提高了速度,KVM通過/dev/kvm暴露接口,用戶態程序可以通過ioctl函數來訪問這個接口。見如下偽代碼:

 

1
2
3
4
5
6
7
8
9
10
open( "/dev/kvm" )
ioctl(KVM_CREATE_VM)
ioctl(KVM_CREATE_VCPU)
for  (;;) {
     ioctl(KVM_RUN)
         switch  (exit_reason) {
         case  KVM_EXIT_IO: 
         case  KVM_EXIT_HLT:
     }
}

 

 KVM內核模塊本身只能提供CPU和內存的虛擬化,所以它必須結合QEMU才能構成一個完成的虛擬化技術,這就是下面要說的qemu-kvm。

 

qemu-kvm

 

Qemu將KVM整合進來,通過ioctl調用/dev/kvm接口,將有關CPU指令的部分交由內核模塊來做。kvm負責cpu虛擬化+內存虛擬化,實現了cpu和內存的虛擬化,但kvm不能模擬其他設備。qemu模擬IO設備(網卡,磁盤等),kvm加上qemu之后就能實現真正意義上服務器虛擬化。因為用到了上面兩個東西,所以稱之為qemu-kvm。

 

Qemu模擬其他的硬件,如Network, Disk,同樣會影響這些設備的性能,於是又產生了pass through半虛擬化設備virtio_blk, virtio_net,提高設備性能。

 

 

 

 wKiom1WdDc2CEwy6AAGPf4VzQao172.jpg

 

 

libvirt

 

libvirt是目前使用最為廣泛的對KVM虛擬機進行管理的工具和API。Libvirtd是一個daemon進程,可以被本地的virsh調用,也可以被遠程的virsh調用,Libvirtd調用qemu-kvm操作虛擬機。

 

 

 

wKioL1WdD72RRy8mAAIuDm6sVAY591.jpg

 

 

 

 

簡單的講,openstack nova最核心的功能就是對一大堆的虛擬機進行管理,虛擬機可以是各種各樣(kvm, qemu, xen, vmware...),而且管理的方法也可以是各種各樣(libvirt, xenapi, vmwareapi...),因為我的電腦不支持CPU的VT,而且以前在visualbox中裝OpenStack,也只能使用qemu,所以這次測試的主要是qemu的使用,另外nova中默認使用的管理虛擬機的API是libvirt,所以這里的測試使用libvirt。

首先來簡單說一下我對libvirt和qemu這兩個的理解:

1. libvirt

libvirt是一套用C語言寫的API,旨在為各種虛擬機提供一套通用的編程接口,而且支持與JavaPython等語言的綁定。基於libvirt的虛擬機管理工具也有很多:virt-manager(GUI工具),virsh(命令行工具)。其架構示意圖如下:

(左圖是沒有使用libvirt的情況)

這里涉及到幾個概念:

(1)Domain:虛擬機的一個運行實例,簡單的理解,就是一個虛擬機虛擬出來的操作系統。它的叫法可是多種多樣:instance,guest OS,virsual machine,其實都指的同一個概念。

(2)Hypervisor:指的就是虛擬機本身,比如qemu, kvm, xen...

libvirt 由幾個不同的部分組成,其中包括應用程序編程接口 (API) 庫、一個守護進程 (libvirtd),以及一個默認命令行實用工具 (virsh),libvirtd守護進程負責對虛擬機的管理工作,在用各種工具對虛擬機進行管理的時候,這個守護進程一定要跑起來,而且這個進程可以分為兩種,一種是root權限的libvirtd,一種是普通用戶權限的libvirtd,前者權限大,可以虛擬計算機的各種設備。

開啟root權限的libvirtd守護進程要以root身份去運行:sudo libvirtd  --daemon

 

2. qemu

qemu是一個仿真器,即可用於來賓操作系統的虛擬化,也可以作為完整的機器仿真器使用,運行使用主機 CPU 或其他 CPU 架構的操作系統。

qemu 支持兩種操作模式:用戶模式仿真和系統模式仿真。用戶模式仿真 允許一個 CPU 構建的進程在另一個 CPU 上執行(執行主機 CPU 指令的動態翻譯並相應地轉換 Linux 系統調用)。系統模式仿真 允許對整個系統進行仿真,包括處理器和配套的外圍設備,這時就應該使用root權限的libvirtd。

qemu相關的命令:

 

[python]  view plain  copy
 
  1. $ qemu-img create -f qcow disk.img 128M  

創建一個名為disk.img的128M大小的qcow格式的磁盤映像文件,這個文件充當來賓操作系統的硬盤。

 

 

[plain]  view plain  copy
 
  1. $ qemu -hda disk.img -cdrom /root/cflinux-1.0.iso -boot d  

-hda指定磁盤映像文件,-cdrom指定光盤鏡像文件,-boot指定從哪里引導系統,d是從CD-ROM引導,c表示從硬盤引導

 

 

[plain]  view plain  copy
 
  1. $ qemu -hda disk.img  

開始啟動來賓操作系統

 

 

接下來,使用visual manager工具來模仿一下openstack中Flat模式的網絡,因為我在安裝openstack的時候,最后一步總是無法ping或ssh上實例,所以這里通過對實例的直接操作來進行演示,其網絡拓撲圖如下:

(網絡是我的一大浩劫,一遇到和網絡相關的東西,立馬就糾結了,網橋,路由,網關,網段,交換機,nat,dhcp等等,這些東西不實踐一下,完全弄不明白他們是干什么的,還好,通過這一段時間的學習,基本上知道了怎么回事,開學之后,一定要補一下網絡知識。)

從開始安裝,到今晚之前,在這個拓撲圖里,一直有一個不懂的東西,就是那個br100!原來它就是傳說中的網橋,網卡可以橋接到這個網橋上,來連接兩個局域網。網橋工作在物理鏈路層,相當於一個“低層”的路由器,通過mac幀來識別主機,所以橋接到這個網橋上的網卡是不需要配ip的,這解開了我“多年”的疑惑:為什么那個eth1不需要配ip啊?那兩個局域網是怎么連到一塊的?原來如此!

還有一個困惑就是多網卡的問題,一直不明白,為什么一台電腦要多個網卡,一個網卡不夠用嗎?原來真的不夠用!一個網卡只能負責接入到一個網絡,如果一個電腦要同時接入多個網絡的話,那么就得用多個網卡了,也就是說一台電腦可以同時處於不同的局域網中。那這樣的話,以前在我腦海中,一台電腦在網絡中的身份是唯一的,這樣的概念就不成立了啊,一台電腦也可以有多個身份,是由網卡決定的。

 

好了,吐槽完畢,下面是我模擬的簡單的拓撲圖:

我的目的就是讓host能ping通任意一個虛擬機,虛擬機之間能夠相互ping通,並且host能ssh上任意一個虛擬機。

1.  首先要做的就是建立br100網橋,在安裝nova時,這個網橋是自動創建的,這里來手動創建,創建網橋使用到的工具是bridge-utils,即使用brctl相關的命令:

[plain]  view plain  copy
 
  1. $ brctl addbr br100   #添加一個網橋  
  2. $ brctl addif br100 eth0   #把網卡橋接到網橋上  
  3. $ ifconfig eth0 0.0.0.0   
  4. $ ifconfig br100 10.0.0.1   #給網橋配ip  

eth0的ip可配可不配。這樣創建的網橋不是永久的,系統重啟的話,就會銷毀了。

 

2.  建立虛擬機:

用visual manager建立3個虛擬機,我用的系統鏡像是cflinux-1.0.iso,一個只有幾兆的linux發行版,磁盤映像是用virtual manager創建的raw格式的image。

需要注意的是在第5步選擇網絡的時候,要選“specify shared device name”,然后在下面的輸入框中輸入剛剛創建好的網橋的名字:br100,如下圖:

 

3.  改虛擬機的ip

不知道為什么visual manager創建的虛擬機初識狀態的ip都是一樣的,都是10.0.0.2,使用ifconfig命令把3個虛擬機的ip改為:

10.0.0.2       10.0.0.3        10.0.0.4

讓他們在同一個網段。

 

這樣,主機可以ping通實例,實例之間也可以相互ping通了,通過ssh root@10.0.0.2也能連上虛擬機了!

 

問題:

每次虛擬機啟動之后,用ifconfig在主機上查詢網絡信息,會看到vnet0, vnet1等這些信息,還有virbr0, virbr1等,后者我知道表示的是一個網段,但是前者是做什么用的呢?是虛擬機的虛擬出來的網卡嗎?

 

 

如果您願意花幾塊錢請我喝杯茶的話,可以用手機掃描下方的二維碼,通過 支付寶 捐贈。我會努力寫出更好的文章。 
(捐贈不顯示捐贈者的個人信息,如需要,請注明您的聯系方式) 
Thank you for your kindly donation!!

 

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM