目錄
Libvirt 的 Live Migration
Libvirt 的 Live Migration 主要分爲兩個層面:html
網絡數據傳輸層
- 基於 Hypervisor 的傳輸,兩個 Hypervisor 之間直接創建數據傳輸鏈接。優勢:數據傳輸量少。缺點:須要額外配置 Hypervisor Network。須要在防火牆上面打開更多的端口來支持併發遷移,數據不必定支持加密(取決於 Hypervisor 實現)。

- 基於 libvirtd Tunnel 的傳輸,源主機和目標主機上運行的 libvirtd 之間創建 RPC 隧道來傳輸數據。數據要先拷貝到 libvirtd,再由 libvirtd 中繼到目標主機的 libvirtd。優勢:不須要從新配置網絡,防火牆上面只須要一個端口就能夠支持併發遷移,數據強加密。缺點:相關的數據拷貝多,全部流量都經過一個端口,容易形成網絡擁堵。

在 Tunnel 傳輸模式下,同一份數據須要被拷貝屢次,而且全部的流量都經過一個端口,在大內存、高業務(快速增長 RAM 髒數據)的場景下,一樣的網絡帶寬,Tunnel 傳輸模式遷移速率較慢。所以,對於大內存、業務繁忙的場景下,首選基於 Hypervisor 的傳輸。
控制層
- Client 控制:由 Libvirt Client 直接控制遷移。Client 跟源主機 libvirtd 鏈接,也跟目的主機 libvirtd 鏈接,當目的主機遷移過程出現異常會反饋給 Client,再由 Client 通知源 libvirtd。整個過程,由 Client 主導控制。

- 源主機 libvirtd 控制:由源主機 libvirtd 主導整個遷移過程。Client 僅做爲遷移指令的發起者,將遷移指令異步發送給源主機 libvirtd。若是目的主機遷移過程出現異常會反饋給源主機 libvirtd。這種方式的好處是,Client 故障也不會影響到整個遷移過程。

- Hypervisor 控制:有源主機 Hypervisor 控制整個遷移過程,Client 向源主機 Hypervisor 發送遷移指令,源主機和目的主機的 libvirtd 不參與控制。這種方式的前提是 Hypervisor 自身支持熱遷移,好處在於 Client 和 libvirtd 的故障不會影響到整個遷移過程。

經過 libvirt 庫實現虛擬機遷移的示例
import libvirt
import pprint
conn_src = libvirt.open('qemu+tcp://username@src_server/system')
conn_dest = libvirt.open('qemu+tcp://username@dest_server/system')
vm_domain = conn_src.lookupByName('instance_name')
vm_domain.migrate(conn_dest, True, 'instance_name', None, 0)
pprint.pprint(help(vm_domain.migrate))
KVM 的預拷貝(Pre-Copy)Live Migration 過程
Step 1. 系統驗證目標服務器的存儲器和網絡設置是否正確,並預保留目標服務器虛擬機的資源。
python
Step 2. 當虛擬機還在源服務器上運轉時,第一個循環內將所有內存鏡像複製到目標服務器上。在這個過程當中,KVM 依然會監視內存的任何變化。linux

Step 3. 之後的循環中,檢查上一個循環中內存是否發生了變化。 假如發生了變化,那麼 VMM 會將發生變化的內存頁即 dirty pages 從新複製到目標服務器中,並覆蓋掉先前的內存頁。在這個階段,VMM 依然會繼續監視內存的變化狀況。web

Step 4. VMM 會持續這樣的內存複製循環。隨着循環次數的增長,所須要複製的 dirty pages 就會明顯減小,而複製所耗費的時間就會逐漸變短,那麼內存就有可能沒有足夠的時間發生變化。最後,當源服務器與目標服務器之間的差別達到必定標準時,內存複製操做纔會結束,同時暫停源系統。服務器

Step 5. 在源系統和目標系統都停機的狀況下,將最後一個循環的 dirty-pages 和源系統設備的工做狀態複製到目標服務器。網絡

Step 6. 而後,將存儲從源系統上解鎖,並鎖定在目標系統上。啓動目標服務器,並與存儲資源和網絡資源相鏈接。併發

參考資料
https://www.ibm.com/developerworks/cn/linux/l-cn-mgrtvm1/index.htmldom