KVM原理及使用

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類操做;事實上,它被稱做虛擬機的用戶模式更貼切.html

  

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

node

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。linux

    

     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的中斷機制相似。
    http://www.javashuo.com/article/p-cifgpuad-cc.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顯示啓動菜單.git

        

       -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
shell


  #(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編程

相關文章
相關標籤/搜索