KVM淺析&基於Qemu創建Guest OS的測試

《KVM虛擬化技術:實戰與原理解析》作者寫作過程草稿連載http://smilejay.com/kvm_theory_practice/
KVM簡介
與xen開發了一套從VCPU調度到內存管理一應俱全的底層操作系統不同,Kernel-Based Virtual Machine是基於kernel的虛擬機,完全利用Linux內核來實現CPU的調度,內存管理的功能。KVM只能運行在支持硬件虛擬化的CPU上。
這裏寫圖片描述
KVM核心層僅有3個內核模塊:kvm,kvm_intel和kvm_amd(分別對應Intel和AMD的CPU);kvm驅動負責創建虛擬機,爲vcpu注入中斷和提供時鐘信號,使用KVM的io_ctl接口可以管理vcpu和vm。
KVM開發者選擇了已經成型的開源虛擬化軟件QEMU作爲用戶層管理Guest OS的接口。Qemu實現了I/O設備模擬,提供訪問外設的途徑。這種架構使得KVM避免了繁瑣的設備模擬和設備驅動(內核中80%以上的代碼就是驅動部分)。QEMU除了是一款虛擬化軟件以外還是一款仿真器,它可以模擬多種不同的CPU和平臺,例如x86,Power PC,S390 guest(IBM的一種大型機)經由kqemu這個開源的加速器,QEMU能模擬至接近真實電腦的速度。

KVM架構
使用modprobe命令裝載KVM模塊後,Linux內核就成爲了一個hypervisor,並且在Linux原有的Kernel mode和User mode的基礎上,新增加了Guest mode,Guest mode擁有自己的Kernel mode和User mode。在KVM模型中,每一個Gust OS都是作爲一個標準的Linux進程,都可以使用Linux進程管理命令管理。在虛擬機運行時,三種模式的工作各爲:

  • Guest mode: 執行非I/O的客戶代碼, Virtual Machine運行在這個模式下;
  • User mode:代表用戶執行I/O指令,Qemu運行在這個模式下;
  • Kernel mode:實現Guest mode的切換,處理因爲I/O或者其他指令引起的從客戶模式退出(VM_EXIT)的指令;kvm模塊工作在這個模式下。

這裏寫圖片描述
KVM 工作原理
User mode Qemu利用libkvm通過ioctl進入Kernel mode,kvm模塊爲Guest OS創建Virtual Memory,VCPU,然後執行VMLAUCH指令進入Guest mode,加載Guest OS並執行。如果Guest OS發生外部中斷或者影子頁表缺頁之類的情況,會暫停Guest OS的執行,退出Guest mode進行異常處理,之後重新進入Guest mode,執行客戶代碼。如果發生I/O事件或者信號隊列中有信號到達,就會進入User mode 處理。
這裏寫圖片描述
libvirt
libvirt是爲了安全高效的管理節點上的各個域,而提供一個公共的穩定的軟件層。它是目前使用最爲廣泛的對KVM虛擬機進行管理的工具和應用程序接口(API),而且一些常用的虛擬機管理工具(如virsh、virt-install、virt-manager等)和雲計算框架平臺(如OpenStack、OpenNebula、Eucalyptus等)都在底層使用libvirt的應用程序接口。

libvirt對多種不同的Hypervisor的支持是通過一種基於驅動程序的架構來實現的。libvirt對不同的Hypervisor提供了不同的驅動:對Xen有Xen的驅動,對QEMU/KVM有QEMU驅動,對VMware有VMware驅動。

libvirt作爲中間適配層,讓底層Hypervisor對上層用戶空間的管理工具是可以做到完全透明的,因爲libvirt屏蔽了底層各種Hypervisor的細節,爲上層管理工具提供了一個統一的、較穩定的接口(API)。通過libvirt,一些用戶空間管理工具可以管理各種不同的Hypervisor和上面運行的客戶機,它們之間基本的交互框架如下圖所示。
這裏寫圖片描述
在libvirt中涉及到幾個重要的概念,解釋如下:

  • Node:一個物理機器,上面可能運行着多個虛擬客戶機。Hypervisor和Domain都運行在Node之上。
  • Hypervisor:也稱虛擬機監控器(VMM),如KVM、Xen、VMware、Hyper-V等,是虛擬化中的一個底層軟件層,它可以虛擬化一個節點讓其運行多個虛擬客戶機(不同客戶機可能有不同的配置和操作系統)。
  • Domain:是在Hypervisor上運行的一個客戶機操作系統實例。域也被稱爲實例(instance,如亞馬遜的AWS雲計算服務中客戶機就被稱爲實例)、客戶機操作系統(Guest OS)、虛擬機(virtual machine),它們都是指同一個概念。

這裏寫圖片描述
KVM管理工具有兩組libvirt和Qemu
這裏寫圖片描述
virtio
http://www.ibm.com/developerworks/cn/linux/1402_caobb_virtio/
Virtio是對半虛擬化hypervisor中的一組通用模擬設備的抽象,virtio由Rusty Russell 開發,他當時的目的是支持自己的虛擬化解決方案 Lguest。Virtio該設置還允許hypervisor導出一組通用的模擬設備,並通過一個通用API讓它們變得可用。有了半虛擬化hypervisor之後,Guest OS能夠實現一組通用的接口,在一組後端驅動程序之後採用特定的設備模擬。後端驅動程序不需要是通用的,因爲它們只實現前端所需的行爲。
這裏寫圖片描述
下面基於VMware上CentOS6.4_X86_64安裝KVM軟件包組,並是否可以啓動測試一個微型Linux系統
安裝KVM,KVM是第一個整合到Linux主線內核的虛擬化技術(從2.6.20開始),紅帽收購了KVM,旗下的虛擬化業務也由XEN向KVM轉移。
KVM使用了QEMU的一部分,並稍加改造,就成了可控制KVM的用戶空間工具了。所以官方提供的KVM下載有兩大部分(qemu和kvm)三個文件(KVM模塊、QEMU工具以及二者的合集)。

[root@DQ ~]# yum groupinstall " Virtualization"   "Virtualization Client" " Virtualization Platform"

libvirtd 是一個作爲 libvirt 虛擬化管理系統中的服務器端的守護程序,如果要讓某個節點能夠用 libvirt 進行管理(無論是本地還是遠程管理),都需要在這個節點上運行着 libvirtd 這個守護進程,以便讓其他上層管理工具可以連接到該節點,libvirtd 負責執行其他管理工具發送它的虛擬化管理操作指令。而 libvirt 的客戶端工具(包括virsh、virt-manager等)可以連接到本地或遠程的 libvirtd 進程,以便管理節點上的客戶機(啓動、關閉、重啓、遷移等)、收集節點上的宿主機和客戶機的配置和資源使用狀態。

[root@DQ ~]# service libvirtd start   
[root@DQ ~]# chkconfig libvirtd on              

使用virt-install創建虛擬機並安裝GuestOS
virt-install是一個命令行工具,它能夠爲KVM、Xen或其它支持libvrit API的hypervisor創建虛擬機並完成GuestOS安裝;此外,它能夠基於串行控制檯、VNC或SDL支持文本或圖形安裝界面。安裝過程可以使用本地的安裝介質如CDROM,也可以通過網絡方式如NFS、HTTP或FTP服務實現。對於通過網絡安裝的方式,virt-install可以自動加載必要的文件以啓動安裝過程而無須額外提供引導工具。當然,virt-install也支持PXE方式的安裝過程,也能夠直接使用現有的磁盤映像直接啓動安裝過程。

virt-install命令有許多選項,這些選項大體可分爲下面幾大類,同時對每類中的常用選項也做出簡單說明。
一般選項:指定虛擬機的名稱、內存大小、VCPU個數及特性等;

  • -n NAME, –name=NAME:虛擬機名稱,需全局惟一;
  • -r MEMORY, –ram=MEMORY:虛擬機內在大小,單位爲MB;
  • –vcpus=VCPUS[,maxvcpus=MAX][,sockets=#][,cores=#[,threads=#]:VCPU個數及相關配置;
  • –cpu=CPU:CPU模式及特性,如coreduo等;可以使用qemu-kvm
  • -cpu ?來獲取支持的CPU模式;

安裝方法:指定安裝方法、GuestOS類型等;

  • -c CDROM, –cdrom=CDROM:光盤安裝介質;
  • -l LOCATION, –location=LOCATION:安裝源URL,支持FTP、HTTP及NFS等,如ftp://172.16.0.1/pub
  • –pxe:基於PXE完成安裝;
  • –livecd: 把光盤當作LiveCD;
  • –os-type=DISTRO_TYPE:操作系統類型,如linux、unix或windows等;
  • –os-variant=DISTRO_VARIANT:某類型操作系統的變體,如rhel5、fedora8等;
  • -x EXTRA, –extra-args=EXTRA:根據–location指定的方式安裝GuestOS時,用於傳遞給內核的額外選項,例如指定kickstart文件的位置,–extra-args “ks=http://172.16.0.1/class.cfg
  • –boot=BOOTOPTS:指定安裝過程完成後的配置選項,如指定引導設備次序、使用指定的而非安裝的kernel/initrd來引導系統啓動等;
    例如:
  • –boot cdrom,hd,network:指定引導次序;
  • –bootkernel=KERNEL,initrd=INITRD,kernel_args=”console=/dev/ttyS0”:指定啓動系統的內核及initrd文件;

存儲配置:指定存儲類型、位置及屬性等;
–disk=DISKOPTS:指定存儲設備及其屬性;
格式爲–disk /some/storage/path,opt1=val1,opt2=val2等;常用的選項有:

  • device:設備類型,如cdrom、disk或floppy等,默認爲disk;
  • bus:磁盤總結類型,其值可以爲ide、scsi、usb、virtio或xen;
  • perms:訪問權限,如rw、ro或sh(共享的可讀寫),默認爲rw;
  • size:新建磁盤映像的大小,單位爲GB;
  • cache:緩存模型,其值有none、writethrouth(緩存讀)及writeback(緩存讀寫);
  • format:磁盤映像格式,如raw、qcow2、vmdk等;
  • sparse:磁盤映像使用稀疏格式,即不立即分配指定大小的空間;
  • –nodisks:不使用本地磁盤,在LiveCD模式中常用;

網絡配置:指定網絡接口的網絡類型及接口屬性如MAC地址、驅動模式等;
-w NETWORK, –network=NETWORK,opt1=val1,opt2=val2
將虛擬機連入宿主機的網絡中,其中NETWORK可以爲:

  • bridge=BRIDGE:連接至名爲“BRIDEG”的橋設備;
  • network=NAME:連接至名爲“NAME”的網絡;

其它常用的選項還有:

  • model:GuestOS中看到的網絡設備型號,如e1000、rtl8139或virtio等;
  • mac:固定的MAC地址;省略此選項時將使用隨機地址,但無論何種方式,對於KVM來說,其前三段必須爲52:54:00;
  • –nonetworks:虛擬機不使用網絡功能;

圖形配置:定義虛擬機顯示功能相關的配置,如VNC相關配置;

  • –graphics TYPE,opt1=val1,opt2=val2:指定圖形顯示相關的配置,此選項不會配置任何顯示硬件(如顯卡),而是僅指定虛擬機啓動後對其進行訪問的接口;
  • TYPE:指定顯示類型,可以爲vnc、sdl、spice或none等,默認爲vnc;
  • port:TYPE爲vnc或spice時其監聽的端口;
  • listen:TYPE爲vnc或spice時所監聽的IP地址,默認爲127.0.0.1,可以通過修改/etc/libvirt/qemu.conf定義新的默認值;
  • password:TYPE爲vnc或spice時,爲遠程訪問監聽的服務進指定認證密碼;
  • –noautoconsole:禁止自動連接至虛擬機的控制檯;

設備選項:指定文本控制檯、聲音設備、串行接口、並行接口、顯示接口等;

  • –serial=CHAROPTS:附加一個串行設備至當前虛擬機,根據設備類型的不同,可以使用不同的選項,格式爲“–serialtype,opt1=val1,opt2=val2,…”,例如:
    –serial pty:創建僞終端;
    –serial dev,path=HOSTPATH:附加主機設備至此虛擬機;
    –video=VIDEO:指定顯卡設備模型,可用取值爲cirrus、vga、qxl或vmvga;

虛擬化平臺:虛擬化模型(hvm或paravirt)、模擬的CPU平臺類型、模擬的主機類型、hypervisor類型(如kvm、xen或qemu等)以及當前虛擬機的UUID等;

  • -v, –hvm:當物理機同時支持完全虛擬化和半虛擬化時,指定使用完全虛擬化;
  • -p, –paravirt:指定使用半虛擬化;
  • –virt-type:使用的hypervisor,如kvm、qemu、xen等;所有可用值可以使用’virsh capabilities’命令獲取;
    這裏寫圖片描述
    這裏寫圖片描述

其它:

  • –autostart:指定虛擬機是否在物理啓動後自動啓動;
  • –print-xml:如果虛擬機不需要安裝過程(–import、–boot),則顯示生成的XML而不是創建此虛擬機;默認情況下,此選項仍會創建磁盤映像;
  • –force:禁止命令進入交互式模式,如果有需要回答yes或no選項,則自動回答爲yes;
  • –dry-run:執行創建虛擬機的整個過程,但不真正創建虛擬機、改變主機上的設備配置信息及將其創建的需求通知給libvirt;
  • -d, –debug:顯示debug信息;

儘管virt-install命令有着類似上述的衆多選項,但實際使用中,其必須提供的選項僅包括–name、–ram、–disk(也可是–nodisks)及安裝過程相關的選項。此外,有時還需要使用括–connect=CONNCT選項來指定連接至一個非默認的hypervisor。

virsh uri:查看當前主機上hypervisor的連接路徑;可以使用virsh connect命令連接
這裏寫圖片描述
下面這個示例創建一個名爲self-made的虛擬機,因爲實驗環境在VMware中,沒有硬件支持,所以指定hypervisor爲qemu,內存大小爲512MB,磁盤爲80G的映像文件/var/lib/libvirt/images/selfmade.img,通過boot.iso光盤鏡像來引導啓動安裝過程。
說明:boot.iso是我之前基於rhel5.4製作的,功能沒有完全,在VMware上直接引導啓動時可以進行到Loading achi driver這一步,而後鏡像在使用過程中會斷開連接
這裏寫圖片描述
單擊虛擬機界面右下角光盤的圖標,選擇連接,然後返回安裝界面點OK,進行安裝又會自動斷開連接,目前還不知道是哪裏出錯
這裏寫圖片描述
下面先用這個不完整的boot.iso做測試,看kvm是否可以啓動
這裏寫圖片描述
在上述步驟中敲下Enter鍵,引導止步於
Loading vmlinuz…………………………..
Loading initrd.img…………………………………………………
Ready.
執行以下命令可以發現self-made已經運行
這裏寫圖片描述
下面創建虛擬磁盤文件,而後格式化掛載分別作爲Guest OS的/boot和/,製作一個微型Linux系統測試kvm能否啓動
這裏寫圖片描述
這裏寫圖片描述

[root@DQ ~]# mkfs.ext4 /dev/mapper/loop0p1
[root@DQ ~]# mkfs.ext4 /dev/mapper/loop0p2

安裝grub,爲其提供vmliuz和initramfs.img,grub安裝時沒有模擬出來BIOS設備
這裏寫圖片描述
將/sbin/init的任務精簡,複製二進制程序運行依賴的系統庫文件到虛擬磁盤映像文件掛載點/mnt中對應的路徑下;提供/sbin/init運行需要的配置文件rcS.conf以及配置文件依賴於的腳本/etc/rc.d/rc.sysinit
這裏寫圖片描述
安裝一個名爲CentOS6.4的虛擬機,直接導入
這裏寫圖片描述
由上圖可知測試止步於Booting……(從磁盤引導)可能由於實驗環境是在VMware中,強行基於Qemu創建虛擬機對於kvm來說可能有些難度,目前我還不是太清楚
virsh define: 創建一個虛擬機,根據事先定義的xml格式的配置文件;創建以後不會自動啓動;
virsh create: 創建一個虛擬機,創建完成後會自動啓動;
virsh undefine: 刪除一個虛擬機
這裏寫圖片描述
每個虛擬機創建後,其配置信息保存在/etc/libvirt/qemu目錄中,文件名與虛擬機相同,格式爲XML
這裏寫圖片描述

下面的示例將創建一個名爲rhel6的虛擬機,其有兩個虛擬CPU,安裝方法爲FTP,並指定了ks文件的位置,磁盤映像文件爲稀疏格式,連接至物理主機上的名爲brnet0的橋接網絡:

# virt-install \
    --connect qemu:///system \
    --virt-type kvm \
    --name rhel6 \
    --ram 1024 \
    --vcpus 2 \
    --network bridge=brnet0 \
    --disk path=/VMs/images/rhel6.img,size=120,sparse \
    --location ftp://172.16.0.1/rhel6/dvd \
    --extra_args “ks=http://172.16.0.1/rhel6.cfg” \
    --os-variant rhel6 \
    --force 

下面的示例將創建一個名爲rhel5.8的虛擬機,磁盤映像文件爲稀疏模式的格式爲qcow2且總線類型爲virtio,安裝過程不啓動圖形界面(–nographics),但會啓動一個串行終端將安裝過程以字符形式顯示在當前文本模式下,虛擬機顯卡類型爲cirrus:

# virt-install \
--connect qemu:///system \
--virt-type kvm \ 
--name rhel5.8 \ 
--vcpus 2,maxvcpus=4 \
--ram 512 \ 
--disk path=/VMs/images/rhel5.8.img,size=120,format=qcow2,bus=virtio,sparse \ 
--network bridge=brnet0,model=virtio
--nographics \
--location ftp://172.16.0.1/pub \ 
--extra-args "ks=http://172.16.0.1/class.cfg  console=ttyS0  serial" \
--os-variant rhel5 \
--force  \
--video=cirrus

下面的示例則利用已經存在的磁盤映像文件(已經有安裝好的系統)創建一個名爲rhel5.8的虛擬機:

# virt-install \
    --name rhel5.8
    --ram 512
    --disk /VMs/rhel5.8.img
    --import
發佈了88 篇原創文章 · 獲贊 17 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章