天天看點

KVM&Libvirt基本概念及開發雜談

KVM包含:

使用KVM的前提條件:

使用qemu前提條件:

libvirt基本理念:

libivrt支援度:

虛拟技術:kvm/qemu,  XEN, LXC, OpenVZ, UserModeLinux, VB, ESX, HyperV, PowerVM, Parallels, Bhyre 虛拟網絡:橋接,NAT,VEPA,VNLINK 存儲:IDE、SCSI,USB,FC,LVM,ISCSI,NFS,FS

libvirt對各種開發語言的支援:

URI:用于連接配接或遠端連接配接到主控端的libvirt虛拟環境,類似資料庫的連接配接字元串

libvirt基本概念:

node:節點,主控端,一個node是一個單獨的實體機,用于運作虛機 hypervisor:一個軟體層,可以把一個實體機用不同的配置虛拟化為多個虛機的集合 domain:虛拟機,在容器級虛拟化情況中,是一個子系統,運作在由hypervisor提供的機器上 libvirt:提供一個通用的軟體層,安全高效的管理node上的domain,同時實作遠端管理功能。 *在windows系統中使用libvirt java綁定,需要使用libvirt java庫,jna.jar庫及對應平台的dll檔案,如果報錯:找不到dll或找不到相關子產品時,需要安裝virtviewer 在java代碼中加入: System.setProperty("jna.library.path", "c:\\program files\\VirtViewer\\bin"); 并需要在上面路徑放置一份virt-0.dll檔案副本,命名為virt.dll

SPICE:

SPICE服務端是一個用libspice實作的VDI庫,VDI定義了一系列接口來釋出虛拟裝置。(如:顯示裝置,鍵盤,滑鼠)并且能讓不同的spice元件和這些裝置互動,從一方面來說,服務端使用spice協定同用戶端通信,從另一方面來說,服務端同VDI主機應用進行互動如QEMU。 SPICE用戶端是最終使用者所面對的接口。

QXL裝置和驅動

當libspice與qemu結合使用時,QEMU QXL PCI裝置可以用來提升遠端顯示性能,增強客戶機的圖形系統。QXL裝置需要客戶機QXL驅動支援。 SPICE協定支援一種通信信道,此通道連接配接客戶和服務端的代理,當使用QEMU時,SPICE代理位于客戶機,VDI端口是一個QEMUPCI裝置,可以與此代理進行通信。

SPICE有六大通道:

主通道:控制與配置 顯示通道:圖形指令,圖形,視訊流 輸入通道:鍵盤和滑鼠輸入 光标通道:定位裝置的位置與光标形狀 回放通道:服務端的聲音在用戶端播放 錄制通道:從用戶端進行音頻捕獲

SPICE圖像壓縮功能:

SPICE本身提供了多種圖像壓縮算法,可以在伺服器初始化時進行選擇,也可以在運作期動态選擇. QUIC是SPICE專有的圖像壓縮算法,此技術基于SFALIC算法,Lempel_zip(LZ)算法同樣也是SPICE支援的算法。QUIC和LZ都是本地算法,獨立編碼每一個圖像。全局LZ(GLZ)是另一個SPICE專有算法,與LZ同基于曆史的全局字典表共同使用,GLZ可以在大量圖像之間使用重複表達式來降低流量消耗,進而儲存帶寬。特别适合在低帶寬的廣域網環境中使用。 SPICE同樣提供了一個針對每一個圖像自動選擇壓縮算法的工作模式,通過圖像屬性啟發式的選擇LZ,GLZ,QUIC算法。 從理論上講,LZ、GLZ更适合壓縮合成圖像,QUIC更适合壓縮真實圖像.

視訊壓縮:

SPICE使用低損壓縮算法壓縮發送到用戶端的圖像,但是視訊流卻是使用不同的方法來處理。SPICE服務端使用自啟發方式标記動态視訊區域并把他們作為視訊流發送出去,編碼使用mjpeg,這種處理方法在某種程度上節約了流量,提高了spice性能,尤其在廣域網環境中。可是在某些情況下,這種啟發行為可能會導緻低品質的圖像效果,比如把不斷更新的文本區域識别為視訊區域,進而導緻部分區域圖像效果品質低下。

從源代碼編譯,需要以下元件:

*qpixman:一個控制像素區域的通用庫,包括低級别像素控制程式,同時也被cairo庫使用,cairo是一個用于支援多輸出裝置的2D圖形庫,qpixman是pixman的輕量級修改版 *qcairo:cairo是一個矢量圖形裝置無關庫,qcairo是cairo的輕量級修改版 *celt:CELT是一種音頻壓縮算法,以高品質傳輸音樂,信号會有非常小的延遲 *ffmpeg:是一個用于音頻和視訊重編碼,轉換,流傳輸的庫。包括libarcodec音頻視訊編碼庫 *log4cpp是一個靈活的日志記錄庫,可以針對檔案,syslog等,繼log4j之後成型 *關于windows虛機安裝virtio硬碟驅動的問題,一種方式是在安裝系統的過程中加在virtio驅動CD光牒或軟碟(winxp),如果系統已經裝完,可以先建立一個小磁盤鏡像, qemu-img create -f qcow2 xxx.img 1G 編輯虛機配置檔案,加入此硬碟鏡像,設定參數dev='vdc' bus='virtio'啟動系統後會發現新硬體,選ISO鏡像中對應的virtiosto驅動選virtioscsi驅動關閉vm,修改虛機配置,删除小硬碟鏡像,把原磁盤改為dev='vda' bus='virtio'并删除位址部分,啟動系統檢視驅動情況。 *關于已有libvirt時自己編譯libvirt時導緻libvirt-sock不存在情況,該位置在/run/user/1000/libvirt/libvirt-sock或/usr/local/var/run/libvirt/libvirt-sock,編譯後加在libvirtd守護程序,用netstat檢視libvirt-sock是否在配置檔案制定位置偵聽。

使用java的libvirt開發API時注意:

* 在使用java程式編寫libvirt應用時,當虛機處于pmsuspended狀态時是無法擷取domainInfo資訊,會出現數組越界的錯誤提示。 * 使用attachDevice方法添加裝置時要注意,flag=0時,表示執行結果影響目前狀态,目前狀态為運作狀态,則隻有運作時存在,目前狀态為關閉狀态則影響關機配置檔案。flag=1時,表示影響運作時狀态,執行此方法時,虛機必須處于Active狀态。flag=2時,表示影響虛機持久配置檔案,但是在qemu環境中flag=1會不支援,程式會爆出不支援熱插拔,可以使用domainUpdateDeviceFlags進行換盤操作。 更新持久配置檔案後,需要關機重新啟動以使新配置生效。domain.getXMLDesc()方法擷取的是虛機的運作時配置,而不是持久化配置,是以會看到被删除的裝置仍然還在。 * 使用DomainUpdateDeviceFlags()方法更新虛機配置時,使用updateFlags 0或1都會更新處于Active狀态的虛機運作時配置,在虛機重新開機後會保持這種更新,因為重新開機虛機不會重新加載持久化配置,關機之後重新開機,配置會還原為原先配置。 當使用updateFlags為2時,會出現無法更新的情況,雖然方法會執行成功,但無法更新持久配置檔案。在關機狀态下,使用updateFlags=1時,會報錯,因為更新Live狀态隻能在domain的active狀态下執行。 * 需要注意的是Libvirt不支援cdrom、floppydisk驅動器的熱插拔,使用attachDevice()方法時,制定flags為0或1時,某些裝置類型如CDROM對運作時修改可能會傳回失敗,原因是hypervisor底層驅動不支援。如果對正在進行塊複制的裝置進行detach()方法操作,hypervisor可能會阻止detach()的操作,在這種情況下,需要先使用domainBlockJobAbort()方法先停止該複制操作即可。 * 根據hypervisor和裝置類型的不同,在一個處于active狀态的domain中去除一個裝置的操作可能是異步執行的,也就是說,當你執行detach()方法時,僅僅是請求去除一個裝置,實際去掉此裝置的時間可能是之後的一段時間,這是根據虛拟層與客戶os配合完成的。這往往容易被忽略,因為有時會看到在配置檔案中此裝置已經被删除了,但hypervisor可能還沒有真正删除這個裝置,這可能會導緻某些後續操作的失敗。想要檢查裝置是否真的被成功删除了,要麼重新使用domainGetXMLDesc()方法,要麼為DOMAIN_EVENT_ID_DEVICE_REMOVED增加一個事件處理器,如果當detachDeviceFlags()方法傳回時,裝置已經被删除,事件會在API CALL結束之前觸發。為了幫助現有的用戶端在大多數情況下更好的工作,這個API會嘗試把在請求之後過了一段時間才完成的異步删除操作轉變為同步删除操作,換句話說,API在異步操作的情況下會等待一會兒來讓删除操作得以完成。 注意,熱插拔裝置不會保持,一旦domain進入S4狀态即hibernation狀态,除非同樣修改了domain的持久配置檔案。 * 使用setMaxMemory()方法設定虛機最大記憶體時,預設使用的是AFFECT_CURRENT,也就是說當domain關閉時,修改持久化配置檔案,當domain處于active狀态時,修改運作時配置或運作時持久化配置都修改,這個要看hypervisor的行為而定。例如,在libvirt中當domain處于active狀态時,修改最大記憶體時會報錯,必須關閉domain再修改持久化配置。

在使用API開發虛機快照功能時,需要注意如下幾點:

如果某虛機建立快照時使用的是内部快照或系統檢查點,則該虛機所有硬碟都必須建立内部快照,qemu不支援建立混合快照,即一部分硬碟建立内部快照,一部分建立外部快照,當然隻讀盤如光驅預設是不建立快照的。 系統檢查點預設所有可讀寫硬碟使用内部快照(關機狀态下,會忽略disks标簽内容)。 如果在建立快照方法中指定了flags為16(disk-only),則沒有明确指定快照方式的硬碟預設使用外部快照,qemu目前不支援内外部混合快照。 使用系統檢查點快照時,對cpu特性集有要求,當domain配置中cpu特性集有invtsc特性時,在domain運作時執行系統檢查點快照會報錯,解決辦法,去掉invtsc特性或将cpu model改為custom。 當執行系統級快照時(開機狀态下),如果配置檔案标簽制定snapshot=internal則硬碟快照預設也會使用internal方式執行,反之如果标簽制定為external則硬碟預設也會使用external方式執行。這是因為qemu快照機制目前不支援内外部快照混合模式,libvirt内部機制會自動把硬碟快照方式調整為與記憶體相同方式。 使用外部快照要注意,執行外部快照檔案是指向原硬碟快照(base 盤)的從鏡像,執行完外部快照後,libvirt會将domain配置檔案中的硬碟鏡像改為新建立的外部快照檔案,這樣此檔案可以用來存儲執行快照後所有差異化内容,是以,libvirt不允許直接删除外部快照。 外部快照會與之前建立的外部快照形成一個差異存儲鍊,内部快照不會與外部快照形成一個差異存儲連。建立快照之後,快照配置檔案會包含虛機配置檔案的全部内容用于還原。 外部快照                               内部快照 win7------------------------->win7_snap-------------------->win7_snap2(包含在win7_snap檔案内部) vm                                     外部                          vm                                  |--------------------->win7_snap3                                                                      vm win7是win7_snap的backingstore,win7_snap2快照存在于win7_snap檔案中,win7_snap是win7_snap3的backingstore,記憶體外部快照可重複覆寫。 * 在關機狀态下,執行任何快照,不能包含有記憶體狀态,需要把記憶體snapshot設定為no,因為關機狀态下沒有記憶體運作狀态,記憶體都清空了。 *建立系統檢查點時,在關機狀态下,預設建立内部快照,而且必須使用内部快照,建立外部快照會報錯,但是使用disk-only模式快照,則在關機狀态下允許建立外部快照同時也允許建立内部快照。外部快照聲稱的預設檔案名稱為原始硬碟鏡像.快照名稱 * 使用disk-only方式針對正在運作的虛機建立快照,必須使用external方式,并且标簽的snapshot必須為no,使用内部快照會報錯,内部快照和系統檢查點快照要求所有硬碟都必須參與執行快照,使用disk-only和external方式并用執行快照才能針對不同硬碟單獨執行快照政策。 * 使用系統檢查點快照方式對處于active狀态的虛機執行快照,快照生成的是内部還是外部取決于memory标簽的snapshot值。 * 使用diskonly模式或關機狀态下建立快照,标簽snapshot必須為no,因為以上兩種快照都無法儲存記憶體狀态。

各種快照模式及虛機狀态的比對情況:

問答

記憶體快照,互斥特性很多,怎麼在各階段進行特性間的互斥?快照失敗會回退嗎?記憶體複用場景可以做快照嗎?大規格記憶體快照時間規格大約多久?

答:快照建議根據我列出的特性進行選擇,不建議把快照功能做得太多太複雜,快照多了會影響性能,如果必須要做外部快照,因為檔案使用backingstore方式存儲,最好對不用的快照進行commit,記憶體複用可以做快照,大規格記憶體做快照需要定制源碼做優化,其實kvm虛拟化隻是給我們一個基本功能,很多功能如果要滿足客戶需求需要對qemu和kvm源碼進行定制開發。

SPICE有探測識别USB裝置的功能嗎?就是在主控端的USB接口上插上USB裝置之後,KVM虛拟機能夠探測到嗎?

答:spice的usb裝置識别指的是将終端機上連接配接的裝置識别為虛機上裝置的功能,這是有spice的一個子功能usb redirect實作,至于主控端外設,這是對qemu配置的問題。

本文轉自Linux就該這麼學部落格園部落格,原文連結:http://www.cnblogs.com/linuxprobe/p/5450229.html,如需轉載請自行聯系原作者