一.虛擬化介紹
在X86平台的虛擬化技術中,新引入的虛擬化層通常稱為虛擬化監控器(Virtual Machine Monitor,VMM),也叫Hypervisor。在虛擬化中,VMM必須能截獲計算元件到物理資源的直接訪問,並將其重定向到虛擬資源池中。根據VMM是用純軟件的方法還是利用物理資源提供的機制來“截獲重定向”,可分為軟件虛擬化和硬件虛擬化。
二:軟件虛擬化和硬件虛擬化
軟件虛擬化:QEMU,VMWare
QEMU采用動態二進制翻譯技術,客戶機的指令不能再物理機上直接執行,需要通過VMM翻譯,再轉換成可以在物理機上執行的指令,這通常會產生顯著的性能開銷,所以QEMU虛擬機用起來是相當慢的,但是QEMU的優點是平台無關性,可以在同一平台模擬不同架構平台的的虛擬機。這么好的優點真的是不應該被這么慢的性能拖住而不被廣泛使用,所以后面就搭配KVM一起用,QEMU提供I/O,KVM提供對硬件的訪問。
VMWare采用二進制翻譯和直接執行相結合的方案。客戶機用戶空間的代碼采用直接執行的方式,客戶機的內核代碼則采用二進制翻譯的方式,我們知道一個程序的大部分時間都是在用戶空間來完成的,大大的減少了翻譯所占的開銷,與QEMU相比,這樣做性能會大幅提升,但是失去了跨平台的能力。
硬件虛擬化:
說白了就是硬件提供了對特殊指令的截獲和重定向的支持,從而提升客戶機的性能。
三.半虛擬化和全虛擬化
在半虛擬化的方案中,通過改動客戶機的操作系統,使客戶機知道自己運行在虛擬化環境下,能夠與VMM進行協同工作。本質上,半虛擬化弱化了對虛擬機特殊指令的被動截獲要求,將其轉化為客戶機的操作系統主動通知。這個主動通知前提是需要修改客戶機的操作系統源代碼的。
全虛擬化:
全虛擬化為客戶機提供了完整的虛x86平台,包括處理器、內存和外設,客戶機認為自己運行在硬件之上,性能相對於半虛擬化低。
隨着廠商的cpu對虛擬化的支持越來越好,intel引入Intel-VT,AMD引入ADM-V技術,靠硬件輔助的全虛擬化性能越來越好,全虛擬化將成為虛擬化技術的核心
四.KVM
KVM(kernel-based Virtual Machine)是基於kernel的虛擬機,從Linux 2.6.20開始,KVM就被集成進內核,成為內核的可加載的模塊。關於KMV,總結如下:
1.KVM的模塊:
kvm-intel.ko #for Intel CPU
kvm-amd.ko #for AMD CPU
kvm.ko #主要的模塊
當三個模塊都加載后,會出現/dev/kvm字符設備,負責qemu和kvm的通訊
2. 在kvm架構中,每個虛擬的CPU顯示為一個常規的進程,有Linux調度程序進行調度,享受Linux內核所有的功能
3. KVM本身不提供模擬,運行在內核,提供CPU和內存的虛擬化,以及客戶機的I/O攔截,客戶機的I/O被KVM攔截后交給QEMU處理,為KVM修改過的QEMU運行在用戶空間,提供硬件的I/O虛擬化,通過IOCTL /dev/kvm字符設備和KVM進行交互。
當KVM模塊被加載的時候:
1)首先初始化內部的數據結構;
2)做好准備后,KVM 模塊檢測當前的 CPU,然后打開 CPU 控制及存取 CR4 的虛擬化模式開關,並通過執行 VMXON 指令將宿主操作系統置於虛擬化模式的根模式;
3)最后,KVM 模塊創建特殊設備文件 /dev/kvm 並等待來自用戶空間的指令
4. KVM的功能列表:
1)支持CPU和Memory超分(overcommit)
2)支持virtio
3)支持熱插拔(cpu,塊設備,網絡設備等)
4)支持SMP(Symmetric Multi-Processing對稱多處理器系統)
5)支持實時遷移(Live Migration)
6)支持PCI設備直接分配和單根I/O虛擬化(SR-IOV)
7)支持內核同頁合並(KSM)
8)支持非一致性內存訪問(NUMA)
5. KVM工具集合
1) libvirt: 操作管理kvm虛擬機虛擬化API
2) Virsh: 基於libvirt命令行工具
3) Virt-Manager: 基於libvirt的GUI工具
4) Virt-v2v:虛擬機遷移
5) Virt-*
6) Svirt: 安全工具
五.Qemu-KVM的簡單安裝和使用
1)查看CPU是否支持虛擬化
cat /proc/cpuinfo|egrep “vmx|svm”
2)現在的linux都帶有kvm 模塊,確保kvm模塊正確安裝
ls /dev/kvm
3) 安裝qemu
yum install qemu*
或者git clone https://git.qemu.org/git/qemu.git 下載最新的qemu
或者https://download.qemu.org/來下載想要的版本
4)創建img 文件,有一般有兩種方式
[a]. dd if=/dev/zero of=rhel7u4.img bs=1M count=8192
[b]. qemu-img create -f qcow2 rhel7u4.img 8G ; 推薦使用這種方式,這種方式創建出 來的img文件是稀疏文件,也就是剛創建出來並沒有8G,會隨着數據的增多而增加。
-f : 磁盤文件格式,一般有raw和qcow2, 通常用的較多的是qcow2,相比較raw格式來說,性能雖然差點,但是優點是稀疏文件,並且具有加密、壓縮、快照等功能
格式轉換:qemu-img convert -f raw input.img -O qcow2 output.qcow2
5)將客戶機os安裝到img中,img可以看成是qemu 客戶機啟動的硬盤。
安裝:
Qemu-system-x86_64 -m 2048 -smp 4 -vnc 10.239.181.192:12 -enable-kvm -boot order=cd -hda /root/kvm/rhel7u4.img -cdrom rhel7.4.iso
起guest:
taskset -c 0-4 qemu-system-x86_64 -name vm2 -enable-kvm -cpu host -smp cores=16,sockets=1, -m 77G -drive file=redhat.img -vnc :12 -netdev tap,id=ipvm1,ifname=tap3,script=/etc/qemu-ifup -device e1000,netdev=ipvm1,id=net0,mac=00:00:02:98:AC:62
taskset -c 1-4:綁定host的core,意思是用host的1-4 core來起這個guest
-name vm2 :客戶機的名字
-enable-kvm 開啟kvm加速
-cpu host:客戶機cpu 模型
-smp:客戶機cpu
-m 77G:客戶機的內存
-drive file=/home/redhat.img : 配置驅動器,也可以這樣寫 -boot order=cd -hda=redhat.img -cdrom=redhat.iso
-vnc :12 開啟vnc 5912端口,可以通過該端口連接到客戶機,也可以指定ip,例如-vnc 10.10.10.10:12,默認是127.0.0.1
-netdev tap,id=ipvm1,ifname=tap3,script=/etc/qemu-ifup 這是新版的net配置方式,這句話的意思是創建一個tap型的網絡設備,id=ipvm1 這個標識符可以隨便取,ifname=tap3 tap設備網卡的名字,script=/etc/qemu-ifup表示在創建的虛擬機的時候會先執行qemu-ifup這個腳本,事實上還有個downscript=/etc/qemu-ifdown,這個是自動調用的,不需要特意去指定,是在結束的時候調用。
-device e1000,netdev=ipvm1,id=net0,mac=00:00:02:98:AC:62 這個-netdev是在host端創建了一個tap網卡,網卡id為ipvm1, -device e1000是創建一個千兆的網卡,netdev=ipmi1,是與host端的tap設備網卡相對應的另外一端,id=net0是guest端網卡的標識符,mac是指定guest端網卡的mac
另外有種結合numa node來指定客戶端的smp,例如 -smp cores=4,threads=2,socket=2 -numa node, mem=1G,cpus=0-8,nodeid=0 -numa node,mem=1G,cpus=9-15,nodeid=1
更簡單的方式也可以寫成-smp 16,即指定guest的cpu 16 core
6)啟動guest后,按ctrl+alt+2 進入到(qemu)命令行,輸入info cpus 可以看到guest cpu對應在host中的線程ID
另外可以在起qemu的時候加入參數-monitor unix:/tmp/vm0.monitor,server,nowait
然后在host中輸入nc -U /tmp/vm0.monitor也可以進到monitor里
或者在host中ps -efL |grep qemu也可以看到
22288是qemu啟動客戶機的進程號,22290-22297是它產生的線程,作為客戶機的vCPU在運行。
7)進程處理器的親和性和vCPU的綁定
a. 查看vcpu在哪個core上運行
[root@xid]# taskset -p 3963
pid 3963′s current affinity mask: 4
這個4是16進制,即0100,即運行在core 3上
或者
[root@xid]# taskset -pc 3963
pid 3963′s current affinity core: 3
加-c的參數,就直接表示哪個core,是10進制的
b. 修改客戶機的qemu進程,使其運行在core 4上
[root@xid]# taskset -p 0x8 3963
pid 3963′s current affinity mask: 4
pid 3963′s new affinity mask: 8
或者
[root@xid]# taskset -pc 4 3963
pid 3963′s current core : 3
pid 3963′s new affinity core: 4