Qemu 和 Qemu-kvm
Qemu: http://qemu-project.org/Download
Qemu-kvm:https://sourceforge.net/projects/kvm/files/qemu-kvm/
自2012年低時,Qemu1.3.0版本發布后,qemu-kvm中針對KVM的修改已全部加入到普通的Qemu代碼庫中,
從此之后可完全使用純qemu來與kvm配合使用(命令行僅需添加-enable-kvm參數),而無需專門使用
qemu-kvm代碼庫了,並且qemu-kvm的更新自2012年9月已經停止更新,到2016年5月30日,最新的QEMU穩定版
已經到2.6.0版了。
另外Qemu的漏洞也需要多加關注,截止16年5月已經發現的Qemu 漏洞已經有149個:
http://www.cnnvd.org.cn/vulnerability/index/vulcode2/qemu/vulcode/qemu/cnnvdid/fbsjs/p/2/
KVM簡介
KVM (名稱來自英語: Kernel-basedVirtual Machine 的縮寫,即基於內核的虛擬機),是一種用於Linux
內核中的虛擬化基礎設施,可以將Linux內核轉化為一個hypervisor。KVM誕生於以色列的一家創業公司Qumranet
員工Avi Kivity等人手中,於2006年8月完成開源並推向Linux內核社區,當年10月被Linux社區接受.2007年2月發布的
Linux2.6.20是第一個包含KVM模塊的內核版本.2008年9月Redhat收購Qumranet公司,並開始投入較多資源開發
KVM虛擬化.2011年11月Redhat發布RHEL6中將原先RHEL5的默認企業級虛擬化Xen徹底去掉改用KVM.
KVM要求CPU必須支持HVM(硬件虛擬化)即:Intel的CPU要支持VT-x或AMD的CPU必須支持AMD-V的功能;
若硬件支持內存的虛擬化,如EPT/NPT及I/O設備的虛擬化,如:VT-d/SR-IOV的支持則會對KVM的虛擬化效率有
很大的提高。KVM也被移植到S/390,PowerPC與IA-64平台上。在Linux內核3.9版中,加入ARM架構的支持。
目前KVM的開源社區也非常活躍,其Redhat的工程師在KVM、QEMU、libvirt等開源社區中成為核心開發成員.
除Redhat外,還有IBM、Intel、Novell、AMD、Siemens、華為以及一些小公司 和 個人獨立開發者活躍在
KVM開源社區,為KVM開發代碼或者做測試工作。
在硬件方面的虛擬化支持和軟件方面的功能開發、性能優化的共同作用下,目前KVM虛擬化技術已經擁有
非常豐富的功能和非常優秀的性能。且KVM的上層管理工具如:libvirt、Ovirt、Virt-Manager、OpenStack
(雲計算平台)等也在日漸成熟, KVM將逐漸成為虛擬化開源領域的主力。
KVM由兩部分組成: 內核模塊和管理接口
內核模塊
ls -1 /lib/modules/`uname -r`/kernel/arch/x86/kvm/
kvm-amd.ko #KVM對AMD CPU所提供的虛擬化驅動
kvm-intel.ko #KVM對Intel CPU所提供的虛擬化驅動
kvm.ko #KVM的核心模塊
管理接口
yum install qeum-kvm #此為KVM為用戶提供的管理VM的接口。
#它是針對KVM的需要定制的Qemu軟件.
KVM模塊載入后的系統運行模式:
內核模式:GuestOS執行I/O類操作,或其它的特殊指令的操作.
用戶模式:代表GuestOS請求I/O類操作;
來賓模式:GuestOS的非I/O類操作;事實上,它被稱作虛擬機的用戶模式更貼切.
KVM的兩類組件:
/dev/kvm: 它是一個字符設備,工作於Hypervisor(Linux Kernel)層,在用戶空間可通過ioctl()
系統調用來完成VM創建、啟動等管理功能.【注:當裝載了kvm.ko 和 kvm-intel或amd.ko后,才會有此設備.】
具體職責:
創建VM、為VM分配內存、讀寫VCPU寄存器、向VCPU注入中斷、調度GuestOS-APP到VCPU上運行等.
qemu進程:工作於用戶空間, 主要用於實現模擬PC機的IO設備;
下圖是KVM虛擬機中APP運行方式圖:
在非虛擬化的環境中,APP(應用程序)運行時,它實際是直接運行在CPU上的,僅當它需要調用特權指令時,
如:訪問I/O設備、關機等特權指令時,它會發起系統調用,然后,APP被調入內存等待,內核中的一段代碼將被
調度到CPU執行,完成操作后,內核代碼會喚醒APP繼續運行. 那么在虛擬化的環境中,GuestOS中的APP運行時
是否會被調度到CPU執行?當然,答案是肯定的,KVM在進行CPU虛擬化時,會為GuestOS模擬一顆或多顆CPU,
這些CPU實際是綁定在某個物理核心上的線程,當GuestOS的APP運行時,它被調度到虛擬CPU上,而這些虛擬CPU
實際是映射到某個物理核心上的,因此實際上GuestOS的APP是運行在CPU上的.
下面三幅圖要說的是同一個問題, 當GuestOS中的APP運行時,因為虛擬架構和物理架構是相同的,因此
GuestOS中的APP是可以直接運行在物理CPU上的,若虛擬架構與物理架構不同,則GuestOS的APP是無法直接
運行在物理CPU上的,因為,物理CPU根本就無法理解GuestOS的APP所調用的CPU環3上的普通指令,所以肯定
是無法執行的,因此需要VMM來作為中間的翻譯代GuestOS的APP執行它所需要物理CPU執行的代碼.
另外GuestOS中APP執行時,當執行非特權指令時它是直接運行於物理CPU上,但若執行特權指令時,一定
是由VMM(虛擬機監視器)代為執行,此時的執行流程是GuestOS的APP先向GuestOS的kernel發起系統調用
GuestOS的Kernel再向VMM請求,最終VMM根據GuestOS-APP的請求,來決定如何處理,如它所發出的特權指令
是訪問物理I/O設備,則VMM將代為向物理CPU發起請求,若該特權指令是關機、重啟則VMM將直接返回告訴
GuestOS-APP已經完成操作,然后,VMM再切斷該GuestOS的電源,而非物理機的電源.
KVM的特性:
內存管理:
(1) 將分配給VM的內存交換至SWAP;
(2) 支持使用Huge Page(大內存頁),故而可實現更高性能的內存分配.
(3) 支持使用Intel 的EPT(擴展頁表) 或 AMD的RVI(快速虛擬索引:也叫NPT(嵌套頁表))技術完成內存地址映射。
此映射指: 直接從VM中APP的虛擬線性地址空間直接映射為宿主機的物理內存地址空間.
同時EPT和RVI都實現了tagging-TLB,即對虛擬線性地址與物理地址轉換結果的緩存標記功能.
簡單說: tagging-TLB:
VM標簽 | VM虛擬線性地址 | Host物理內存地址
VM-A | 0x0000001 | 0x0101FF011
VM-B | 0x0000001 | 0x01FFF2982
若沒有EPT或RVI則VM中APP訪問宿主機的物理內存就必須借助影子頁表來實現.
即: GuestOS-APP的虛擬線性地址--->
GuestOS-Kernel的虛擬物理地址--->
Shadow Page Table將GuestOS的虛擬物理地址轉為Host的物理內存地址--->
宿主機的物理內存地址.
(4) 支持KSM(Kernel Same-page Merging:相同內存頁合並) :它可以將相同內存塊進行合並以便節省內存空間
當一個被合並的塊需要修改時,KSM會啟動CoW(寫時復制)的機制來創建一個內存塊的副本,以完成修改.
KVM對硬件的支持:
KVM對硬件的支持取決於Linux Kernel對硬件的支持.因為KVM實際上是一個內核模塊,它一旦被Kernel裝載,則
Linux Kernel將即刻變成Hypervisor,來向VM提供CPU、內存、及I/O設備的虛擬化支持。
KVM的存儲支持:
(1) 支持本地存儲: IDE、SATA、SCSI、CDROM等
(2) 支持網絡附加存儲:NFS/Samba,iSCSI
(3) 支持存儲區域網絡:FCoE
(4) 支持分布式存儲:GlusterFS等
KVM支持實現遷移:
KVM支持的GuestOS:
Linux, Windows(KVM還通過了微軟的虛擬化應用認證,即:KVM環境中的Windows出現問題,若系統是正版的,微軟還會提供技術支持),
OpenBSD, FreeBSD, OpenSolaris等.
KVM的設備驅動:
IO設備的完全虛擬化:
硬件模擬,這些模擬的硬件是運行在KVM宿主機的用戶空間中的線程.
IO設備的半虛擬化:
在GuestOS中安裝驅動:virtio; virtio是Redhat和IBM聯合研發的開源虛擬化IO驅動。它已經支持
virtio-blk,virtio-net,virtio-pci,virtio-console,virtio-balloon(內存動態大小調整)。
KVM的局限性:
一般局限性:
CPU overcommit(過載):
即KVM在給VM分配資源時,盡量避免超過宿主機的物理CPU的資源數,如:物理CPU
有6顆,那么分配給VM的VCPU的總和應該為6,若超過,則這些VCPU將會在物理CPU間調度以
實現獲得CPU資源,但這將對性能造成一定影響。
時間記錄難以精確:
這是因為操作系統在啟動時,會讀取一次硬件時鍾,作為系統啟動時的系統時鍾,隨后,
OS將通過CPU的頻率來計時,如CPU的主頻為2GHz,則OS會檢測CPU的晶振次數若到達2G次,
則認為已經過了1秒,以此來更新時鍾.但在虛擬化環境中,GuestOS是不可獨占CPU的,因此它統計
的CPU晶振次數是不精確的,這也導致GuestOS的時鍾不可能非常精確.它必須依賴與時鍾服務器來同步時間.
MAC地址:
VM數量特別多時,存在沖突的可能。
實時遷移:
(1) GuestOS的磁盤映像文件必須放在共享存儲上,並且源和目標KVM掛載共享的位置必須一致.
(2) 遷移的目標KVM的版本必須相互兼容。
(3) CPU必須是相同的.
(4) I/O透傳將不支持遷移,因為:若A端使用一個磁盤分區做為GuestOS的系統分區,就無法遷移到B端.
(5) 兩端的時間必須同步。
(6) 兩端的網絡配置必須一樣,如: A端GuestOS橋接在br0上,但B端沒有br0就會出現錯誤。
性能局限性:【注:都是相對於物理硬件而言】
(1) 完全虛擬化中CPU的MMU的性能僅7%
半虛擬化中CPU支持EPT或RVI則性能可達97%
(2) 磁盤I/O的虛擬化性能
模擬磁盤: 40%
I/O半虛擬化: 85%
I/O透傳技術:95%
(3) 顯卡完全虛擬化的性能: 45%,它不支持半虛擬化.
(4) 完全虛擬化的時間:快或慢5%, 半虛擬化可以做到精確,因為有輔助模塊的支持。
KVM的工具棧:
qemu:
qemu-kvm: 此為qemu專為KVM而設計的虛擬機管理工具,qemu本身也是一個虛擬化工具,不過它是模擬器,
支持物理硬件和虛擬硬件不同,但在虛擬環境和物理環境相同時,qemu會與KVM結合來提供虛擬化.
qemu-img: 此工具是專門用來創建虛擬磁盤映像文件的.
libvirt:
GUI: virt-manager(一個圖形管理虛擬機的工具)、virt-viewer(它僅是一個查看虛擬機的監視器)
CLI: virt-install(僅用來創建、刪除VM等), virsh(可用來管理VM的整個生命周期,但創建VM需要提供xml文件,不是很方便.)
libvirt工具在使用時,必須啟動一個進程libvirtd,這使得virt-manager、virt-install、virsh都可以支持遠程管理VM.
QEMU主要提供了以下幾個部分:
(1) 處理器 模擬
(2) 仿真I/O設備
(3) 關聯模擬的設備至真實設備
(4) 調試器
(5) 與模擬器交互的用戶接口
使用KVM的條件
(1) 確保CPU支持硬件虛擬化: grep --color -E 'svm|vmx' /proc/cpuinfo #svm: AMD的AMD-v,vmx: Intel的VT-x
(2)只要內核裝載了 kvm 、kvm-intel(intel CPU需要加載) 則當前Linux的kernel就即刻變成KVM Hypervisor了。
接着就只需要驗證下 ls /dev/kvm 若存在,則說明KVM Hypervisor已經成功寄宿到Kernel了。
注: 若是AMD的CPU則需要裝載: kvm-amd
IO半虛擬化驅動:virtio
下載地址:
https://fedorapeople.org/groups/virt
I/O半虛擬化:
前端驅動(Virtio前半段):virtio-blk,virtio-net,virtio-balloon,virtio-console
Linux:CentOS4.8及以后版本/5.3及以后版本/6全系列及以上版本都支持Virtio前端驅動
virtio:虛擬隊列,通過virt-ring實現
transport:負責從前端隊列中取出請求,交由后端處理程序進行處理。
后端處理程序(virt backend drivers):它在QEMU中實現。
virtio-balloon:
ballooning:讓VM中運行的GuestOS的內存可在開機狀態下動態套裝內存大小。
基本過程為:
(1) 增加GuestOS內存:從A向外擴,從B向外收,來增加GuestOS內存。
(2) 減少GuestOS內存:從B向內擴,從A向內收, 擠出GuestOS內存,回收給Host。
qemu-kvm -balloon virtio
手動在QEMU-monitor中查看balloon使用情況
info balloon
balloon MemSize #動態調整KVM虛擬機內存的大小,默認單位:MB
#注: VM源分配內存512MB, 調小100M,則MemSize=412
virtio-net :
qemu-kvm -net nic,model=?
qemu-kvm -net nic,model=virtio
#查看KVM虛擬機是否使用了virtio
ethtool -i eth1
Host中關閉網卡的GSO,TSO,可能提高網卡性能。
ethtool -K $IF gso off
ethtool -K $IF tso off
ethtool -k $IF
注:TSO(TCP Segmentation Offload TCP分片):
網卡支持TSO則 系統會延遲大數據段的在TCP層分段,而是將大數據段交給網卡來進行分段,
然后在調用IP層根據MTU來分片,減輕CPU負荷。(注:此時分片中只有第一個分片包有TCP頭,
后續只有IP頭,這使得第一個分片丟失,則整個報文必須重傳!)【注:這是TSO和GSO最大的區別】
UFO(UDP Fragmentation Offload UDP分片):
UDP不支持分片,它需要在IP層進行分片。
GSO(Generic Segmentation Offload 通用分片):
它支持多種協議,它的設計思想是盡可能在發往硬件驅動前延遲數據分片盡可能讓網卡硬件
來調用Linux內核做分片工作,減輕CPU負擔,在使用中GSO會先判斷網卡是否支持TSO,支持則
GSO會控制着TCP層分段前將數據發給網卡驅動由網卡芯片來執行分段,隨后再調用IP層分片,
不需要CPU參與(注:此時分片中只有第一個分片包有TCP/UDP頭,后續只有IP頭,這使得第一個
分片丟失,則整個報文必須重傳!)。
若不支持TSO,則Linux內核來調用GSO,由它來調用TCP/UDP的回調函數來分段,接着
發給下層IP層,注意TCP分段的大小是按照MSS(Max Segment Size:最大段大小) 來分段的,
因此到IP層后,若分段加上IP頭部后超過MTU(Max Transmission Unit:最大傳輸單元),則
IP層還要在進行分片,最后交給網卡發出。 (注:這里是每個包都有TCP/UDP頭和IP頭)
收數據
LRO(Large Receive Offload:)
它是接收TSO發出的分片數據包,並將多個TCP分段聚合成一個skb結構,當合並多個skb后,
一次發給網絡棧,減小上層協議棧的skb開銷。
它使用發送方IP,目的地IP,IP封包ID,L4協議四者來區分段,這會導致從同一個LAN里面的兩台
PC要往同一目的IP發包時,到達對端的包若被分片了,在將分片包組合為完整包時,要區分那些
分片報文是一組時,可能會出現三者都一樣的問題,因為LAN中的兩台PC訪問的目的IP和
發送者IP都一樣(SNAT后,LAN中PC的LAN IP被換成了互聯網IP), 而IP封包ID又非全局分配,可能一樣,
L4協議可能都是TCP。這就可能出現"卷繞"的BUG。
GRO(Generic Receive Offloading) :
它接收GSO發出的分段報文。並使用發送方和目的方IP,源/目的端口,L4協議三者來區分分段報文,
完成分段報文的拼接,最后一股腦全部將拼接后的報文送到網絡棧。對於現在來說基本都使用GRO
而不使用LRO來接收分段數據。
性能影響
GuestOS和HostOS都打開GSO/TSO/UFO > GuestOS打開,HostOS關閉 > GuestOS,HostOS都關閉
對TCP來說:CPU資源充足時, TSO/GSO開不開意義不大。
CPU資源不足時, TSO/GSO帶來的性能提升會較明顯。
對UDP來說:改進效果一般,性能提升不超過20%
但在VxLAN隧道中,其實是可以關閉GSO,從而避免它帶來一些潛在問題。
潛在問題
1.網絡傳輸延遲,因為包大小增加,會增大driver queue的容量(capacity)。這會導致一些交互式應用發的
小包和等待分片的大包在driver queue隊列中等待排隊發出,造成交互式應用出現無法忍受的網絡延時。
所以若網絡出現一些莫名其妙的問題時可以嘗試關閉offloading技術。
GSO和TSO封包說明:
1.系統先判斷網卡是否支持GSO(注:Guest中的Virtio NIC是支持的),支持並且啟用了GSO則Guest會直接將
沒有分段的GSO大幀傳遞給Virtio-net驅動.
2.當Virtio-net驅動會通過Virtio-ring將GSO大幀傳給Host上的Virtio backend dirver.
3.Host上的tap和bridge都會原封不動的轉發這個GSO大幀(注:包結構為:Payload,inner-tcp,inner-ip,inner-ethernet)
4.Host上的VxLAN driver在原GSO大幀上添加VxLAN幀頭,則包結構變為:Payload,inner-tcp,inner-ip,inner-ethernet,vxlan
5.若Host上不支持GSO,則Host的IP層將直接對UDP層分片(注:只有第一個分片有UDP頭,其余只有IP頭)
分片1包結構:Payload,inner-tcp,inner-ip,inner-ethernet,vxlan,outer-udp,outer-ip
分片2包結構:Payload,inner-tcp,inner-ip,inner-ethernet,vxlan,outer-ip
6.若Host支持GSO,再看物理網卡,若支持TSO,則直接將大幀(即:Payload,inner-tcp,inner-ip,inner-ethernet,vxlan)
轉發給物理網卡的TSO去硬件分片。若不支持TSO,則Linux系統將調用GSO軟件執行分片,而GSO由於會調用
UDP的回調函數,但沒有VxLAN的回調函數,所以這里的GSO分片應該每一個都有UDP頭,但只有第一個有VxLAN頭。
分片1包結構:Payload,inner-tcp,inner-ip,inner-ethernet,vxlan,outer-udp,outer-ip
分片2包結構:Payload,inner-tcp,inner-ip,inner-ethernet,outer-udp,outer-ip
7.但Host的物理網卡是根據MSS(最大段大小)來確定即發給遠端的包大小是由Guest的MSS值設定,而非MTU值.
Host上打開GSO后,又增加了outer-udp,會造成包大小大於MSS值,從而繼續在outer-ip時進行IP分片。
【注:所以Redhat的最佳實踐是關閉host上的GSO特性】
從Host到GuestOS的包流向
以OpenStack的網絡節點為例:
Internet--->eth0--->br-ex--->qg-XXX--->qr-XXX--->br-int(OVS-bridge)--->ovs-patch-ports--->
br-tun(for STT Tunnel)--->eth1--->OpenStack的管理網絡
注:若eth0,eth1的MTU=9000,則Host的GRO打開,則eth0收到的數據會分段重組為一個大GRO幀。
路由器:
數據包在通過Router時,conntrack需要將分片重組后,使用防火牆規則檢查,避免攻擊,但Router有一個特性,
就是它對重組的包有一個重組定時器,若超時依然沒有重組完成,則Router將丟棄並清理該分段數據包,這就會
導致丟包,網絡不通的情況出現。
若將Linux配置為一台路由器的話,要查看Router分段重組超時的設置,以及分段重組所能使用的最大內存量:
cat /proc/sys/net/ipv4/ipfrag_low_thresh #這是分段重組最少可以使用的內存量
cat /proc/sys/net/ipv4/ipfrag_high_threst #可用的最大內存量
cat /proc/sys/net/ipv4/ipfrag_time #分段重組超時的默認值
LinuxBridge上關閉防火牆功能:
net.bridge.bridge-nf-call-arptables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-ip6tables = 0
1.若Host上的GRO打開,則Host上的物理網卡要先將分片重組為一個大GRO包。
2.若br-ex是LinuxBridge,且防火牆開啟了,則netfilter conntrack為了做二層的防欺騙檢查,需重組分片,檢測通過后,
再重新分片(注:此時分片采用出去的網絡接口上的MTU進行分片, 這和Guest向Host發包時用Guest的TCP/UDP
協議棧上的MSS不同。),重新分片時將使用qg-xxx的MTU來分片,一般MTU值為1500,這是標准默認值。
3.即使br-ex不是LinuxBridge,eth0在重組分片后,做完防火牆檢查后,再使用9000重新分片,再傳到后面MTU為1500
的虛擬設備又會先分片再重組,所以若MTU設置不當,還不如將Host上的TSO/GSO/GRO關閉更好。
4.最后virtio會將大幀傳入Guest。
VMware STT隧道
STT:它是加了偽裝TCP頭,通過網卡的TSO特性,讓網卡硬件來對數據包做分片以便加速CPU性能的技術。
注: OVS(OpenVSwitch) bridge支持STT,但LinuxBridge不支持。
NSX Bridge:它是用OVS實現的,它不具有LinuxBridge的bridge-nf-call-iptables的特性。但它和OpenStack的neutron
集成時依然可以這樣用:
tap--->qbr--->qvr--->br-int--->ovs-patch-port--->phy-br-eth0
這里的qbr和phy-br-eth0均有可能是LinuxBridge。
OpenStack的問題:
創建Windows實例成功,但RDP連接總被取消或關閉。嘗試過關閉NIC中的TSO/GSO/GRO沒能解決,
修改了WindowsNIC校驗和也沒有解決。
可參看以下解決方法:
1.若用隧道,則Guest中需要修改MTU
2.關閉LinuxBridge的防火牆功能
3.若需要使用conntract特性沒有關閉LinuxBridge防火牆功能,則關閉Host上的GSO/TSO/GRO。
4.重點關注Host上物理網卡與LinuxBridge上的MTU,其它虛擬網卡的MTU默認即可。
5.也可嘗試關閉Offload的rx和tx特性。(ethtool --offload eth0 rx off tx off sgo off tso off)
注:當Tx和Rx打開時,Chksum是在硬件網卡處做的。
Virtio:
在Virtio中Guest的Virtio的前端驅動要訪問后端驅動的流程:
virtio-net/virtio-pci---->virtio-queue--->發送notify的trap中斷給Hypervisor---->Hypervisor調用
Host中面向Guest的前端驅動API接口----->由API接口訪問后端驅動----->后端驅動再訪問到物理設備。
注:
Guest內核中的tx0和rx0兩個隊列與Host中的rx和tx兩個隊列是通過共享內存交換數據的。
VxLAN實現:
從Guest出來的TCP數據段到達Host的VxLAN設備時,它會給該數據段計算TOS,TTL,df,src_port,dst_port,md,Flags等,
並設置GSO參數后,傳到給UDP Tunnel協議棧繼續處理,然后再送入IP層處理。
【不是很確定,僅做參考】
此時若網卡硬件支持TSO和UFO,則由網卡芯片來做UDP 分片,然后由硬件做IP分片,最后送到網卡。
若網卡不支持,則送入Device Driver Queue(設備驅動隊列)時,由Linux內核調用UDP GSO分片,再IP分片,再到網卡。
注:
Guest上TCP協議棧設置的TCP MSS是始終保持不變的,網卡硬件對UDP所做的UDP GSO分片數據報的大小還是根據
TCP MSS來定的。所以VxLAN協議有一個問題就是Host的IP分片是根據Guest中TCP連接的MSS來進行的。簡單說
就是傳入到IP層的數據報文大小只要超過物理網卡的MTU,就必須進行IP分片。
vhost-net :
區別:
》virtio-net:工作於用戶空間的Qemu進程,來模擬后端驅動.
》vhost-net:工作於內核空間的內核模塊,來模擬后端驅動。
優劣:
》virtio-net: 不存在VM處理網絡流量的快慢問題,因為Virtio-ring是virtio實現的收發緩沖器,
它是像一個環,發送或接收數據會先放到環中的一個槽位中,等待發送或處理,並且
后端驅動是在用戶空間模擬,它是可以直接訪問物理網卡的,並受Linux控制。
》vhost-net:它運行於內核空間,處理速度非常快,並且當vnet_hdr標識打開后,該標識會允許
對數據包的校驗和僅做部分檢查,這將允許大數據包發送,並且也變相提高了吞吐量。
而VM在處理網絡流量時,若無法跟上vhost-net的速度,就會出現VM正在處理接收的數據,
但vhost-net已經發完了需要發送的數據,並且也已經接收完了返回的數據,導致宿主機的
接收緩沖區快速被占滿; TCP還好,它的窗口滑動機制可逐漸控制發送速度變慢,並且還有
丟包重傳機制保護; 但UDP就不行了,它一旦丟了就丟了.而緩沖區滿后,后來的UDP可能
將全部丟掉,這將大大降低整體性能。
#啟動vhost-net的方法。
# vnet_hdr: on強制啟用vnet的hdr標識,不啟用可能會出錯。
# HDR標識:它是TAP/TUN虛擬設備的“IFF_VNET_HDR”標識,它打開后,
# 將允許發送或接受大數據包時僅做部分校驗和檢查,從而變相提高網絡吞吐量。
# vhostforce=[on|off] 設置是否強制使用vhost作為非MSI-X中斷方式的virtio客戶機的后端處理程序.
注: MSI-X: PCIe總線引出MSI-X機制的主要目的是為了擴展PCIe設備使用中斷向量的個數,
同時解決MSI中斷機制要求使用中斷向量號連續所帶來的問題。
MSI-X Capability中斷機制與MSI Capability的中斷機制類似。
https://www.cnblogs.com/helloworldspace/p/6760718.html
#
-net tap[,vnet_hdr=on|off [,vhost=on|off]]
示例:
qemu-kvm -name rhel64-03 -m 512 -smp 2 -hda /images/kvm/rhel6.4.img \
-net nic,model=virtio,macaddr=52:54:... \
-net tap,vnet_hdr=on,vhost=on,script=/etc/kvm/if-up,downscript=no \
-vnc :5
注:
#在使用libvirt創建VM時,若不想使用vhost,則修改VM的xml配置文件:
<interface type="network">
....
<model type="virtio"/>
<driver name="qemu"> #若使用vhost-net,則修改qemu為vhost。
</interface>
virtio-blk:
kvm_clock: 半虛擬化時鍾
# VM的時鍾不同步對於Web應用中Cookie或Session有效期計算、VM遷移,
# 等依賴時間戳的應用都會造成影響。
# Constant TSC(Constant Time Stamp Counter:不變的時鍾計數器),它是一個恆定
# 不變的CPU頻率計算器,無論CPU核心是否因省電策略改變頻率,它都始終保持不變,
# 此功能在較新的CPU中得到了支持,這是對VM精確計時提供的硬件支持.
#查看本機是否支持kvm_clock:
grep 'constant_tsc' /proc/cpuinfo
#查看CPU是否支持Censtant TSC
# 注:"TSC deadline"模式是通過軟件設定"deadline(最后期限)"的閾值,當CPU的時間戳計數器
# 大於或等於deadline闕值,則本地高級可編程中斷控制器(Local APIC)就會產生一個時鍾中斷請求
# (IRQ),來保障VM時間的精確。
# 另注:
# KVM在Linux3.6以后才對TSC Deadline Timer提供支持。
# qemu-kvm是從0.12版開始支持, qemu-kvm -cpu host 來向VM輸入TSC Deadline Timer特性.
grep 'tsc_deadline_timer' /proc/cpuinfo
#查看Linux內核是否編譯了對kvm_clock的支持
grep -iE 'paravirt|KVM_CLOCK' /boot/config-*
CONFIG_PARAVIRT_CLOCK=y #y:編譯進內核
#默認KVM已經讓kvm_clock成為時間源,所以無需顯示指定加載。
demsg |grep -i --color 'kvm-clock' #在VM中使用此命令即可看到kvm-clock已經加載.
Intel和AMD的I/O虛擬化技術規范
Intel VT-d(Virtualization Technology for Directed I/O) 和 AMD Vi(也叫IOMMU) :
PCI硬件設備對VT-d技術的支持與否,決定了VM是否可獨占使用該物理設備.並且這種使用
幾乎是不需要Hypervisor參與的。但是要真正實現VM直接使用物理設備,還需要中斷重映射
(Interrupt Remapping) 和 DMAR(DMA虛擬化,其核心芯片為IOMMU)的支持。
#檢查VT-d在宿主機上是否啟用:
dmesg |grep -i 'DMAR' #Intel VT-d搜此關鍵字
dmesg |grep -i 'IOMMU' #AMD Vi搜此關鍵字
#注: GRUB的Kernel默認沒有啟用IOMMU,可grub.conf的kernel項后追加"intel_iommu=on"來啟用.
#若要將物理設備分配給VM獨占使用,還需要將該設備在宿主機中隱藏,
#使其他VM和宿主機不能再使用該設備.
#pci_stub可實現隱藏宿主機中的物理設備,以便VM獨占使用.
modprobe pci_stub
grep -i 'pci_stub' /boot/config-*
CONFIG_PCI_STUB=y #這表示PCI_STUB已經編譯到內核了。
#若該模塊以經編譯到Kernel中了,則檢查以下目錄是否存在,則說明pci_stub已經編譯到內核中了.
ls /sys/bus/pci/drivers/pci-stub
#綁定PCI設備的方法:
(1) 查看PCI設備的vendor ID(廠商ID) 和 device ID(設備ID)
lspci |grep -i 'eth' #注:假設是綁定網卡,用此命令找出該網卡的BDF(Bus:Device.Function)信息.
02:01.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)
02:05.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)
[root@node2 ~]# ethtool -i eth1
driver: e1000
version: 7.3.21-k8-NAPI
firmware-version:
bus-info: 0000:02:05.0
lspci -Dn -s 02:05.0 #假設08:00.0是該網卡的PCI總線地址(BDF信息).
0000:02:05.0 0200: 8086:100f (rev 01)
注:8086即為vendor ID, 100f就是device ID.
0000:表示PCI設備的域,一般為0,當有多個Host PCI Bridge時,其值范圍為:0~0xffff。
08: bus
00: slot
0: function
(2) 綁定設備到pci_stub驅動.
echo -n "8086 100f" > /sys/bus/pci/drivers/pci-stub/new_id
#注:下面兩個是一樣的,1是一個軟連接,2是真實路徑
1.echo '0000:02:05.0' > /sys/bus/pci/devices/0000\:02\:05.0/driver/unbind
2. echo '0000:02:05.0' > /sys/bus/pci/drivers/e1000/0000\:02\:05.0/driver/unbind
echo '0000:02:05.0' > /sys/bus/pci/drivers/pci-stub/bind
#查看綁定后的效果
lspci -k -s 02:05 .0 #查看kernel當前使用此PCI設備的驅動和Kernel中可支持該設備的模塊.
....
Kernel driver in use: pci-stub #Kernel當前使用的網卡驅動已經改成pci-stub了.
Kernel modules:e1000 #[注:這里我還不是很明白,內核使用了pci-stub做網卡驅動,這與隔離網卡有什么關系.]
(3) qemu-kvm命令創建VM時,綁定物理設備給VM.
qemu-kvm -device ? #查看qemu-kvm支持的設備驅動.
qemu-kvm -device pci-assign,? #查看pci-assign驅動的屬性值.
# 注:id:為Qemu Monitor中info pci輸出信息時的標識, addr:為該設備的在VM中的PCI slot編號.
qemu-kvm -device pci-assign,host=02:05.0,id=myEth0,addr=0x6
(4) 解除綁定物理網卡的綁定
echo -n "8086 100f" > /sys/bus/pci/drivers/e1000/new_id
echo '0000:02:05.0' > /sys/bus/pci/devices/pci-stub/0000\:02\:05.0/driver/unbind
echo '0000:02:05.0' > /sys/bus/pci/drivers/e1000/bind
#========================================================#
#分配物理磁盤
ls -l /dev/disk/by-path/pci-0000\:16\:00.0-sas-0x.....
lspci -Dn -s 16:00.0
echo -n "VendorID DericeID" > /sys/bus/pci/drivers/pci-stub/new_id
echo "0000:16:00.0" > /sys/bus/pci/devices/0000:16:00.0/driver/unbind
echo "0000:16:00.0" > /sys/bus/pci/drivers/pci-stub/bind
qemu-kvm -device pci-assign,host=00:16.0,addr=0x6 ...
#將宿主機的整個USB控制器分配給VM
# 通過U盤來確定將宿主機的那個USB控制器設備分配給VM
ls -l /dev/disk/by-path/pci-0000:00:ld.0-usb-0\:1.2\:1.0-scsi...
# 隔離USB控制的方法與物理磁盤一樣.
#分配
qemu-kvm -device pci-assign,host=00:ld.0,addr=0x5 ...
#分配單獨USB設備給VM
# 首先也是先隔離該USB設備.
#分配給VM
lsusb
Bus 001 Device 002 : ID 0781:5567 SanDisk Corp. Cruzer Blade
qemu-kvm -usbdevice host:0781:5567 ...
或
qemu-kvm -usbdevice host:001.002 ....
SR-IOV虛擬化前端后端思想的硬件實現
SR-IOV(Single Root I/O Virtualization and Sharing)概況:
VT-d使VM可直接獨占使用物理硬件,VM性能提升了,但成本也升高了; SR-IOV是在這種
機會之下催生的產物,它是PCI-SIG組織發布的規范,它實現了將支持SR-IOV技術的物理硬件
划分為管理器(PF:Physical Function)和虛擬功能(VF:Virtual Function)兩部分, 管理器將物理
硬件中的數據傳送和處理功能虛擬成多份,就類似與CPU按時間片被虛擬化為多個vCPU. 然后,
將這種虛擬功能輸出給VM,實現PCI物理設備的復用。
安照前端后端來說, VM中使用的虛擬功能就是前端驅動,物理設備就是后端驅動.
支持SR-IOV技術的PCI硬件多是網卡,如:Intel 82576(igb驅動)、X540(ixgbe驅動)等.
支持SR-IOV的虛擬化軟件: Qemu/kvm(2009年發布)、Xen、VMware、Hyper-V等.
SR-IOV的基本原理:
SR-IOV為VM使用虛擬功能提供了獨立的內存空間、中斷、DMA(直接內存訪問)流,無需
Hypervisor的軟件交換機的介入傳輸.
一個有SR-IOV功能的設備 在其PCI配置空間中可被配置為多種功能包括一個PF和多個VF,
每個VF都有自己獨立的配置空間和完整的BAR(Base Address Register:基址寄存器),Hypervisor
將VF的配置空間映射給VM,使VM可以看到設備的配置空間,來實現將一個或多個VF分配給一個VM.
另外Intel VT-x和VT-d等硬件輔助虛擬化技術提供的內存轉換技術,使DMA可直接將數據發送到VM
的內存空間,也允許VM直接將數據通過DMA傳送到宿主機的內存空間.
一個VF同一時間僅能分配給一個VM,在VM中看到的VF就是一個普通的完整的設備。
SR-IOV的優劣:
優:實現了一個物理設備被多VM共享復用,降本提性.
劣:無法動態遷移,支持SR-IOV技術的設備有限,設備依賴性高.
#查看本機是否有支持SR-IOV的設備
lspci |grep 'SR-IOV'
#Intel支持SR-IOV設備的驅動:igb, ixgbe的示例
# 查看igb 或 ixgbe啟用VF功能的參數
modinfo igb |grep 'parm'
modprobe -r igb #若當前沒有啟動VF功能可先卸載.
modprobe igb max_vfs=7 #igb最大支持7個VF.
lspci |grep 'Eth' #啟動后,將可看到物理網卡被虛擬為7個VF網卡.
# 假如上面加載網卡的PCI總線地址為: '0000:0d:00.0'
#查看該網卡為VF設備分配的PCI總線地址.假設為"0000:0e:10.0"
ls -l /sys/bus/pci/devices/0000\:0d\:00.0/virtfn*
ls -l /sys/bus/pci/devices/0000\:0e\:10.0/phsfn #查看PF的PCI總線地址.
# 讓系統開機后,自動加載igb驅動,並啟用VF功能.
cat /etc/modprobe.d/igb.conf
option igb max_vfs=7
# 將VF綁定給VM的方法
(1) 先隔離其中的一個VF,在使用 qemu-kvm -device pci-assign,host=0e:10.0 .. 即可.
KVM工具的使用
qemu-kvm是最核心的工具.它是libvirt工具棧底層調用的工具。
yum install qemu-kvm
ln -sv /usr/libexec/qemu-kvm /bin
qemu-kvm 命令行選項:
標准選項:
-M :指定模擬的主機架構【qemu-kvm-1.5.3-160.el7_6.2, 沒有找到此項】
-cpu :指定CPU的架構,如: Intel, AMD
-smp :指定CPU顆數、核心數、線程數、插槽數
n,[maxcpus=cups] :指定cpu顆數,最大多少顆
cores=n :指定核心數
threads=n: 指定線程數
sockets=n: 指定有幾個CPU插座
-name: 指定VM的名稱
-m : 指定內存的大小
-boot:指定啟動選項
order: 指定啟動順序:a(軟盤), c(磁盤), d(CDROM), n(網絡)
once: 僅設置時使用一次,a, c, d, n
menu=[on |off] :可在啟動VM時,提示按F12顯示啟動菜單.
-drive option[,option[,option[,....]]]
file=/path/to/somefile :磁盤映像文件路徑
if=interface :指定磁盤設備所連接的接口類型,即控制器類型,如: IDE/SCSI/SD/MTD/Floppy/Pflsh/virtio等
index=index: 設定同一種控制器類型中不同設備的索引號、即標識號,如:sda,sda1,sda2....;
media=[disk | cdrom] : 定義介質類型為硬盤或光盤.
snapshot=[on|off] :指定當前磁盤設備是否支持快照功能.
#注: 啟用snapshot后,Qemu不會將磁盤數據的更改寫回鏡像文件中,而是寫入臨時文件,
# 當按Ctrl+ALT+1進入Qemu的monitor模式后,使用commit命令時,可強制將更改寫回后端磁盤鏡像。
cache=[none|writeback|unsafe|writethrough] :定義如何使用物理機緩存來訪問塊數據.
unsafe:不安全的緩存(性能最好) > writeback: 回寫緩存(性能較好) > writethrough:通寫緩存(安全性高,性能次之)
writeback:僅將數據寫入磁盤緩存就返回完成,緩存中的數據在即將被換出時,才寫入磁盤.
writethrough: 將數據寫入磁盤緩存的同時也寫入磁盤,都完成后返回完成。
none:讀寫都不使用緩存,而writeback 和 writethrough默認都優先使用緩存。
format=FMT :指定映像文件的格式.
aio=[threads | native] :設置使用異步IO的方式.
# threads : 默認值, 即讓一個線程池來處理異步IO.
# native :僅在cache=none時可用,它使用Linux原生的AIO來處理異步IO.
readonly=[ on | off] :設定驅動器是否可讀。
serial=SERIAL_# #指定分配給設備的序列號。
addr=ADDR #分配給驅動器控制器的PCI地址, 僅適用於virtio接口。
id=ID_Name #在Qemu Monitor模式下查看info blk時,顯示的磁盤id標識。
-iscsi [user=USER][,password=PASSWD]\
[,header-digest=CRC32C|CR32C-NONE|NONE-CRC32C|NONE]\
[,initiator-name=iqn]
示例:
qemu-kvm -iscsi initiator-name=iqn.2000-11.com.example:my-initiator \
-cdrom iscsi://192.168.100.1/iqn.2012-11.com.example/2 \
-drive file=iscsi://192.168.100.1/iqn.2012-11.com.example/1
-mtdblock /path/to/file #將指定文件做為VM的Flash存儲器(即:U盤)
-sd /path/to/file #將指定文件做為VM的SD卡(Secure Digital Card)
-pflash /path/to/file #並行Flash存儲器
啟動VM:
qemu-kvm -m 128 -name cirros-001 -smp 2 -hda /image/kvm/cirros-*.img
補充:
關閉cirros-0.3.4的檢查更新的過程,但還需要注意Cirros還有三次等待DHCP分配地址的延時,
若有DHCP這很快就過去了:
# cat /etc/cirros-init/ds-ec2
MAX_TRIES=0
SLEEP_TIME=0
BURL="http://169.254.169.254/2009-04-04"
使用-drive指定磁盤映像文件:
qemu-kvm -m 128 -name cirros-002 -smp 2 \
-drive file=/images/kvm/cirros-0.3.4-i386-disk.img,if=virtio,\
media=disk,cache=writeback,format=qcow2
通過cdrom啟動winxp的安裝:
qemu-kvm -name WinXP-001 -smp 4,sockets=1,cores=2,threads=2 -m 512 \
-drive file=/images/kvm/winxp.img,if=ide,media=disk,cache=writeback,format=qcow2 \
-drive file=/root/winxp_ghost.iso,media=cdrom
設置使用VNC顯示VM的圖形界面
qemu-kvm -m 128 -name cirros-004 -smp 2 \
-drive file=/images/kvm/cirros.img,if=virtio,media=disk,cache=writeback,format=qcow2 \
-vnc :3 \ #啟動vnc,默認監聽所有接口,端口: 5900 + 3
-monitor stdio #啟動后直接在當前shell進入VM的監控控制台
-vnc :3,passwd -monitor stdio #VNC :3,passwd 是指定VNC連接需要密碼.
# 這樣就會啟動一個qemu的monitor界面,在monitor模式里可以設置VNC的密碼。
(qemu) change vnc passwd #這在Qemu的monitor模式中指定為VNC修改密碼的方式.
查看VM啟動情況:
ps aux |grep qemu-kvm
qeum-kvm的顯示選項:
-usbdevice tablet #此選項用於VNC連接后,鼠標軌跡與實際軌跡保持同步.
#默認Qemu使用SDL來顯示VGA輸出,此選項可禁用圖形接口,此時,qemu將為其仿真串口設備將被重定向到控制台.
-nographic:
-curses: 禁止圖形接口,並使用curses/ncurses作為字符交互終端接口;
-alt-grab: 使用Ctrl+Alt+shift組合鍵釋 放鼠標;
-ctrl-grab: 使用右Ctrl鍵釋放鼠標;
-sdl: 啟用SDL;
注: SDL(Simple DirectMedia Layer:簡單直接介質層) :它采用C語言開發,跨平台且開源的多媒體程序庫文件,用於簡單圖形
圖像聲音等多媒體信息輸出呈現的庫, 它被廣泛應用與各種操作系統,如:游戲開發/多媒體播放器/且被多種模擬器用來打開窗口等
-spice option[,option[,...]]: 啟用spice遠程桌面協議; 其有許多子選項.
-vga type: 指定要仿真的VGA接口類型,常見類型有:
cirrus: Cirrus Logic GD5446顯示卡;
std: 帶有Bochs VBI擴展的標准VGA顯卡
vmware: VMWare SVGA-II兼容的顯示適配器
qxl: QXL虛擬化顯示卡;與VGA兼容,在Guest中安裝QXL驅動后能以很好的方式工作,當使用spice協議時推薦使用.
none: 禁用VGA卡
-vnc display[,option[,....]] : 默認情況下,qemu使用SDL顯示VGA輸出,使用-vnc選項,可讓qemu監聽在VNC上,並將VGA輸出
重定向至VNC會話; 此選項必須使用-k選項指定鍵盤布局類型.
注:
VNC(Virtual Network Computing:遠程網絡計算),它使用RFB(Remote FrameBuffer:遠程幀緩存)協議遠程控制另外的主機。
display:
(1) host:N #1.1.1.1:2, 監聽於1.1.1.1主機的5900+2的端口上.
(2) unix:/path/to/socket_file
(3)none
opetions:[新版本中已經廢棄]
(1) password: 連接VNC的密碼
(2) reverse: "反向"連接至某個處於監聽狀態的vncview上。
-monitor stdio :表示在標准輸入輸出上顯示monitor界面.
-nographic 選項執行以下快捷鍵:
ctrl+a 松開快速再按 c :在console和mointor間切換.
ctrl+a 松開快速再按 h :顯示幫助信息.
網絡屬性相關選項:
-net nic[,vlan=n][,macaddr=MAC][,model=Type][,name=Name][,addr=Addr][,vectors=V]:
創建一個新的網卡設備,並連接到VLAN n中,PC架構上默認NIC為e1000;
qemu可模擬多種類型的網卡,如:virtio, i82551, i82557b, i82559er,
ne2k_isa, pcnet, rtl8139,e1000,smc91c111,lance及mcf_fec等;
不過不同平台架構上,其支持的類型可能只包含前述列表中的一部分,
可使用"qemu-kvm -net nic,model=?" 來獲取當前平台支持的類型;
-net tap[,vlan=n][,name=Name][,fd=h][,ifname=Name][,script=Sfile][,downscript=Dfile] :
通過物理機的TAP網絡(虛擬二層網絡設備)接口連接至VLAN n中,使用script=Sfile指定腳本
(默認為/etc/qemu-ifup)來配置當前網絡接口,並使用downscript=Dfile指定腳本
(默認為/etc/qemu-ifdown)來撤銷接口配置; 使用script=no和downscript=no可分別用來禁止直行腳本.
name:指定qemu monitor模式中顯示虛擬二層網絡設備的接口名
ifname:指定在宿主機上顯示虛擬二層網絡設備的接口名
注:
通常nic 和 tap需要聯合使用,nic用來創建VM的網卡,並為網卡配置IP,MAC,網卡芯片等;
而TAP用來指定VM如何連入虛擬網絡中,tap提供網絡的前半段和后半段.前半段在VM中,
與網卡關聯,后半段在宿主機上,並需要使用scirpt來指定一個腳本完成后半段接口
橋接到那個網橋上.以便完成復雜的網絡模型創建。
qemu-kvm會調用script指定的腳本,並將后半段網卡作為參數傳給該腳本,以便完成后半段加入指定網橋.
-net user[,option][,option][,...]:
在用戶模式配置網絡棧,其不依賴於管理權限,這得益於qemu-kvm實現了一個自有的tcp/ip協議棧
它可以不使用Kernel所提供的tcp/ip協議棧;它功能與tap類似,也是指定VM如何連入虛擬網絡,
所不同的是tap需要管理員權限. 有效選項有:
vlan=n : 連接至VLAN n, 默認n=0;
name=Name: 指定接口顯示名稱, 常用於監控模式中;
net=addr[/mask]: 設定GuestOS可見的IP網絡, 掩碼可選, 默認為:10.0.2.0/8
host=addr : 指定GuestOS中的本機IP,默認為net指定網段中的第二個IP,即:x.x.x.2
dhcpstart=addr: 指定DHCP服務的地址池中16個地址的起始IP,默認為x.x.x.16~x.x.x.31.
dns=addr : 指定GuestOS的DNS地址.默認為GuestOS所在網段中的第三個IP,即:x.x.x.3
tftp=dir: 激活內置的tftp服務器,並使用指定目錄作為tftp服務器的默認根目錄。
bootfile=file: BOOTP文件名, 用於PXE引導GuestOS. 如:
qemu-kvm -hda /kvm/linux.img -boot n -net user,tftp=/tftpserver/pub,bootfile=/pxelinux.0
-soundhw #開啟聲卡硬件支持
#如: qemu-kvm -soundhw ?
Qemu Monitor中實現物理設備的熱插拔
(1) CPU
#對CPU和內存的熱插拔技術,在RHEL6.3中已經得到支持.
qemu-kvm -smp 2,maxvcpus=8 ... #啟動時使用兩顆vCPU,最大可動態增加8個.
#按Ctrl+Alt+2切換到Qemu Monitor:
cpu_set 3 online #動態添加
cpu_set 3 offline #動態移除
#若動態添加后, vCPU在VM中沒有上線工作,可手動激活下:
echo 1 > /sys/devices/system/cpu/cpu3/online
(2) 內存
#Qemu-kvm的內存的熱插拔還沒有提供支持。
#目前僅可使用virtio-balloon技術來增大或減少內存。
qemu-kvm -balloon virtio ...
#手動在QEMU-monitor中查看balloon使用情況
#按Ctrl+Alt+2切換到Qemu Monitor:
info balloon
balloon MemSize #動態調整KVM虛擬機內存的大小
(3) SATA硬盤
#首先,還是需要先在宿主機中將物理設備隔離,在再Qemu Monitor中添加.
#按Ctrl+Alt+2切換到Qemu Monitor:
device_add pci-assign,host=00:1f.2,id=mysata,addr=0x06
info pci
device_del mystat
(4) USB
#假如在宿主機中查看lsusb為:
lsusb
Bus 001 Device 002 : ID 0781:5567 SanDisk Corp. Cruzer Blade
#按Ctrl+Alt+2切換到Qemu Monitor:
方法1: usb_add host:001.002 或 usb_add host:0781:5567
info usb
Device 0.2, Port 1, ...
usb_del 0.2
方法2: device_add pci-assign,host=00:1d.0,id=myusb
device_del myusb
(5) 網卡
#先在宿主機中隔離一個物理網卡 或 VF網卡.
#按Ctrl+Alt+2切換到Qemu Monitor:
device_add pci-assign,host=06:10.1,id=myNIC
device_del myNIC
VM Mirgration(遷移):
static migration
live migration
整體遷移時間
服務器停機時間
對服務的性能的影響
#遷移注意事項:
(1) 使用Samba、NFS等共享方式存放VM的磁盤映像文件,並在源和目的宿主機上掛載到相同目錄;
(2) 源和目的宿主機的軟件配置要盡量相同,如: 源和目的都有相同的網橋等。
(3) VM遷移到目的宿主機后,要保證VM的名稱在目的宿主機上唯一。
(4) 64位---遷移---64位; 32位----遷移----32位或64位
(5) Intel平台---遷移---Intel平台,AMD平台---遷移---AMD平台.
不建議:Intel平台---遷移---AMD平台,雖然有時不會出錯.
(6) 動態遷移的源和目的宿主機對NX位(Never eXecute)的設置是相同的.源和目的只能是同關閉或同打開.
cat /proc/cpuinfo |grep nx ,查看CPU是否支持NX.
補充:
NX bit(Never eXecute):
NX位是CPU特性的一種,它可讓OS將指定內存區域標記為不可執行,這樣CPU將不會執行該區域的
任何代碼。NX技術理論上可防止“緩沖區溢出(buffer overflow)”類型的黑客攻擊。
NX技術在不同的CPU上的稱呼:
Intel CPU:XD bit(eXecute Disable)
AMD CPU: EVP(Enhanced Virus Protection)
ARM CPU:XN(eXecute Never)
#Qemu-kvm來遷移VM,必須在Qemu Monitor中操作.
#在源VM上, 按Ctrl+Alt+2切換到Qemu Monitor:
# 遷移命令格式:
# migrate [-d] [-i] [-b] 目的主機的URI
# -d : 執行migrate命令后,不占用前台,即Qemu Monitor界面下依然可輸入命令.
# -i : 同時傳輸增量的磁盤映像文件到目的宿主機
# -b : 同時傳輸整個VM的磁盤映像文件到目的宿主機.
#
# 與遷移相關的命令:
# migrate_cancel :取消遷移.
# migrate_set_speed ?[B|K|G|T] #指定遷移占用多大的網絡帶寬,越大速度越快.
# migrate_set_downtime 1 #當KVM遷移到最后時,估算剩余完成時間 <= 1秒,則關閉源VM.
#
#(1) 源和目的宿主機都掛載了存放遷移VM磁盤映像的共享存儲.
源宿主機:
mount -t nfs 1.1.1.1:/kvm/image /kvm/images
qemu-kvm -name RHEL6-01 -m 512 -smp 2 -hda /kvm/images/rhel6.4.img -net nic
目的宿主機:
mount -t nfs 1.1.1.1:/kvm/image /kvm/images
#注:tcp:本地監聽地址:監聽端口, 0:監聽所有接口.
qemu-kvm -name RHEL6-01 -m 512 -smp 2 -hda /kvm/images/rhel6.4.img -net nic -incoming tcp:0:6666
#(2) 在源宿主機上操作遷移:
# 在源VM上, 按Ctrl+Alt+2切換到Qemu Monitor:
migrate -d tcp:DestiantionIP:6666
#(1) 同時遷移源VM的增量磁盤映像文件.
源宿主機:
# 注意: 通過后端文件創建的增量img文件,指定的大小似乎不起作用.增量img文件的容量是
# 后端img文件創建時的大小。
qemu-img create -f qcow2 -o backing_file=/kvm/image/rhel6.4.img,size=20G /tmp/rhel6u4.img
qemu-kvm -name RHEL6-01 -m 512 -smp 2 -hda /tmp/rhel6u4.img -net nic
目的宿主機:
qemu-img create -f qcow2 -o backing_file=/kvm/image/rhel6.4.img,size=20G /tmp/rhel6u4.img
qemu-kvm -name RHEL6-01 -m 512 -smp 2 -hda /tmp/rhel6u4.img -net nic -incoming tcp:0:6666
#(2) 在源宿主機上,按Ctrl+Alt+2切換到Qemu Monitor:
migrate -i tcp:DestinationIP:6666 #僅遷移增量的rhel6u4.img磁盤映像文件.
migrate -b tcp:DestIP:6666 #遷移整個rhel6.4.img磁盤.
附件1:
SMP(Symmetric Multi-Processor: 對稱多處理器):
在SMP系統中,多個進程可真正實現並行執行,且單個進程下的多個線程也可得到並行執行,
這極大地提高了計算機系統並行處理能力和整體性能。
SMP在硬件方面,早期的計算機系統多采用在一塊主板上集成多個物理CPU插槽來實現SMP系統;
后來隨着多核、超線程(Hyper-Threading)技術的出現,SMP逐漸采用多個物理CPU、多核或超線程等
技術中的一個或多個來實現。
SMP在操作系統(OS)方面,目前多數現代OS都已提供了對SMP系統的支持,如:主流的Linux(2.6及
以上Kernel對SMP支持更完善)、微軟的WinNT、Mac OS、BSD、HP-UX、IBM的AIX等。
在Linux中查詢是否支持超線程的方式:
#若物理CPU的核心數 大於 邏輯CPU的個數,則說明超線程是支持並啟用的。
# cat /proc/cpuinfo |grep 'core id' #物理CPU的核心個數.
core id : 0 #這表明CPU共4個核心,編號為0-3
core id : 1
core id : 2
core id : 3
# cat /proc/cpuinfo |grep 'siblings' #顯示每個物理CPU中邏輯CPU(可能是core、thread或兩者)的個數
siblings : 4
siblings : 4
siblings : 4
siblings : 4