一些關於KVM和VMware虛擬化原理的總結

感慨一下:VMware的官方文檔詳細到感人,足以見得VMware公司對技術的尊重!

一、KVM

(1)概述

KVM 全稱是基於內核的虛擬機(Kernel-based Virtual Machine),它是一個 Linux 的一個內核模塊,該內核模塊使得 Linux 變成了一個Hypervisor。

(1)它由 Quramnet 開發,該公司於 2008年被 Red Hat 收購。

(2)它支持 x86 (32 and 64 位), s390, Powerpc 等 CPU。

(3)它從 Linux 2.6.20 起就作爲一模塊被包含在 Linux 內核中。

(4)它需要支持虛擬化擴展的 CPU。

(5)它是完全開源的。

KVM 是基於虛擬化擴展(Intel VT 或者 AMD-V)的 X86 硬件的開源的 Linux 原生的全虛擬化解決方案。KVM 中,虛擬機被實現爲常規的 Linux 進程,由標準 Linux 調度程序進行調度;虛機的每個虛擬 CPU 被實現爲一個常規的 Linux 進程。這使得 KVM能夠使用 Linux 內核的已有功能。但是,KVM 本身不執行任何硬件模擬,需要客戶空間程序通過 /dev/kvm 接口設置一個客戶機虛擬服務器的地址空間,向它提供模擬的 I/O,並將它的視頻顯示映射回宿主的顯示屏。目前這個應用程序是 QEMU。

(1)客戶機:客戶機系統,包括CPU(vCPU)、內存、驅動(Console、網卡、I/O 設備驅動等),被 KVM 置於一種受限制的 CPU 模式下運行。

(2)KVM:運行在內核空間,提供CPU 和內存的虛擬化,以及客戶機的 I/O 攔截。Guest 的 I/O 被 KVM 攔截後,交給 QEMU 處理。

(3)QEMU:修改過的爲 KVM 虛機使用的 QEMU 代碼,運行在用戶空間,提供硬件 I/O 虛擬化,通過 IOCTL /dev/kvm 設備和 KVM 交互。

(2)KVM 實現攔截虛機的 I/O 請求的原理

現代 CPU 本身實現了對特殊指令的截獲和重定向的硬件支持,甚至新的硬件會提供額外的資源來幫助軟件實現對關鍵硬件資源的虛擬化從而提高性能。以 X86 平臺爲例,支持虛擬化技術的 CPU 帶有特別優化過的指令集來控制虛擬化過程。通過這些指令集,VMM 很容易將客戶機置於一種受限制的模式下運行,一旦客戶機試圖訪問物理資源,硬件會暫停客戶機的運行,將控制權交回給 VMM 處理。VMM 還可以利用硬件的虛級化增強機制,將客戶機在受限模式下對一些特定資源的訪問,完全由硬件重定向到 VMM 指定的虛擬資源,整個過程不需要暫停客戶機的運行和 VMM 的參與。由於虛擬化硬件提供全新的架構,支持操作系統直接在上面運行,無需進行二進制轉換,減少了相關的性能開銷,極大簡化了VMM的設計,使得VMM性能更加強大。從 2005 年開始,Intel 在其處理器產品線中推廣 Intel Virtualization Technology 即 IntelVT 技術。

(3)QEMU-KVM

其實 QEMU 原本不是 KVM 的一部分,它自己就是一個純軟件實現的虛擬化系統,所以其性能低下。但是,QEMU 代碼中包含整套的虛擬機實現,包括處理器虛擬化,內存虛擬化,以及 KVM需要使用到的虛擬設備模擬(網卡、顯卡、存儲控制器和硬盤等)。爲了簡化代碼,KVM 在 QEMU 的基礎上做了修改。VM 運行期間,QEMU 會通過 KVM 模塊提供的系統調用進入內核,由 KVM 負責將虛擬機置於處理的特殊模式運行。遇到虛機進行 I/O 操作,KVM 會從上次的系統調用出口處返回 QEMU,由 QEMU 來負責解析和模擬這些設備。從 QEMU 的角度看,也可以說是 QEMU 使用了 KVM 模塊的虛擬化功能,爲自己的虛機提供了硬件虛擬化加速。除此以外,虛機的配置和創建、虛機運行所依賴的虛擬設備、虛機運行時的用戶環境和交互,以及一些虛機的特定技術比如動態遷移,都是 QEMU 自己實現的。

(4)KVM

(1)KVM 內核模塊在運行時按需加載進入內核空間運行。KVM 本身不執行任何設備模擬,需要 QEMU 通過 /dev/kvm 接口設置一個 GUEST OS 的地址空間,向它提供模擬的 I/O 設備,並將它的視頻顯示映射回宿主機的顯示屏。它是KVM 虛機的核心部分,其主要功能是初始化 CPU 硬件,打開虛擬化模式,然後將虛擬客戶機運行在虛擬機模式下,並對虛機的運行提供一定的支持。

(2)以在 Intel 上運行爲例,KVM 模塊被加載的時候,首先初始化內部的數據結構,做好準備後,KVM 模塊檢測當前的 CPU,然後打開 CPU 控制及存取 CR4 的虛擬化模式開關,並通過執行 VMXON 指令將宿主操作系統置於虛擬化模式的根模式,最後,KVM 模塊創建特殊設備文件 /dev/kvm 並等待來自用戶空間的指令。接下來的虛機的創建和運行將是 QEMU 和 KVM 相互配合的過程。兩者的通信接口主要是一系列針對特殊設備文件 dev/kvm 的 IOCTL 調用。其中最重要的是創建虛機。它可以理解成KVM 爲了某個特定的虛機創建對應的內核數據結構,同時,KVM 返回一個文件句柄來代表所創建的虛機。

(3)針對該句柄的調用可以對虛機做相應地管理,比如創建用戶空間虛擬地址和客戶機物理地址、真實物理地址之間的映射關係,再比如創建多個 vCPU。KVM 爲每一個 vCPU 生成對應的文件句柄,對其相應地 IOCTL 調用,就可以對vCPU進行管理。其中最重要的就是“執行虛擬處理器”。通過它,虛機在 KVM 的支持下,被置於虛擬化模式的非根模式下,開始執行二進制指令。在非根模式下,所有敏感的二進制指令都被CPU捕捉到,CPU 在保存現場之後自動切換到根模式,由 KVM 決定如何處理。

(5)KVM功能列表

(1)支持CPU 和 memory 超分(Overcommit)

(2)支持半虛擬化I/O (virtio)

(3)支持熱插拔 (cpu,塊設備、網絡設備等)

(4)支持對稱多處理(Symmetric Multi-Processing,縮寫爲 SMP )

(5)支持實時遷移(Live Migration)

(6)支持 PCI 設備直接分配和 單根I/O 虛擬化 (SR-IOV)

(7)支持 內核同頁合併 (KSM )

(8)支持 NUMA (Non-Uniform Memory Access,非一致存儲訪問結構 )

(6)KVM工具集合

(1)libvirt:操作和管理KVM虛機的虛擬化 API,使用 C 語言編寫,可以由 Python,Ruby, Perl, PHP, Java 等語言調用。可以操作包括 KVM,vmware,XEN,Hyper-v, LXC 等 Hypervisor。

(2)Virsh:基於 libvirt 的 命令行工具 (CLI)。

(3)Virt-Manager:基於 libvirt 的 GUI 工具。

(4)virt-v2v:虛機格式遷移工具。

(5)virt-* 工具:包括 Virt-install (創建KVM虛機的命令行工具), Virt-viewer (連接到虛機屏幕的工具),Virt-clone(虛機克隆工具),virt-top 等。

(6)sVirt:安全工具。

(7)KVM 虛機的創建過程

qemu-kvm 通過對 /dev/kvm 的 一系列 ICOTL 命令控制虛機,一個 KVM 虛機即一個 Linux qemu-kvm 進程,與其他 Linux 進程一樣被Linux 進程調度器調度。KVM 虛機包括虛擬內存、虛擬CPU和虛機 I/O設備,其中,內存和 CPU 的虛擬化由 KVM 內核模塊負責實現,I/O 設備的虛擬化由 QEMU 負責實現。KVM戶機系統的內存是 qemu-kvm 進程的地址空間的一部分。KVM 虛機的 vCPU 作爲 線程運行在 qemu-kvm 進程的上下文中。

一些關於KVM和VMware虛擬化原理的總結

因爲 CPU 中的虛擬化功能的支持,並不存在虛擬的 CPU,KVM Guest 代碼是運行在物理 CPU 之上。通常來講,主機操作系統和 VMM 運行在 VMX root 模式中,客戶機操作系統及其應用運行在 VMX nonroot 模式中。因爲兩個模式都支持所有的 ring,因此,客戶機可以運行在它所需要的 ring 中(OS 運行在 ring 0 中,應用運行在 ring 3 中),VMM 也運行在其需要的 ring 中 (對 KVM 來說,QEMU 運行在 ring 3,KVM 運行在 ring 0)。CPU 在兩種模式之間的切換稱爲 VMX 切換。從 root mode 進入 nonroot mode,稱爲 VM entry;從 nonroot mode 進入 root mode,稱爲 VM exit。可見,CPU 受控制地在兩種模式之間切換,輪流執行 VMM 代碼和 Guest OS 代碼。對 KVM 虛機來說,運行在 VMX Root Mode 下的 VMM 在需要執行 Guest OS 指令時執行 VMLAUNCH 指令將 CPU 轉換到 VMX non-root mode,開始執行客戶機代碼,即 VM entry 過程;在 Guest OS 需要退出該 mode 時,CPU 自動切換到 VMX Root mode,即 VM exit 過程。可見,KVM 客戶機代碼是受 VMM 控制直接運行在物理 CPU 上的。QEMU 只是通過 KVM 控制虛機的代碼被 CPU 執行,但是它們本身並不執行其代碼。也就是說,CPU 並沒有真正的被虛擬化成虛擬的 CPU 給客戶機使用。

一些關於KVM和VMware虛擬化原理的總結

vSphere的CPU虛擬化與KVM有着非常相似的一致性:

一些關於KVM和VMware虛擬化原理的總結

二、CPU虛擬化

(1)爲什麼需要 CPU 虛擬化?

X86 操作系統是設計在直接運行在裸硬件設備上的,因此它們自動認爲它們完全佔有計算機硬件。x86 架構提供四個特權級別給操作系統和應用程序來訪問硬件。 Ring 是指 CPU 的運行級別,Ring 0是最高級別,Ring1次之,Ring2更次之…… 就 Linux+x86 來說,操作系統(內核)需要直接訪問硬件和內存,因此它的代碼需要運行在最高運行級別 Ring0上,這樣它可以使用特權指令,控制中斷、修改頁表、訪問設備等等。應用程序的代碼運行在最低運行級別上ring3上,不能做受控操作。如果要做,比如要訪問磁盤,寫文件,那就要通過執行系統調用(函數),執行系統調用的時候,CPU的運行級別會發生從ring3到ring0的切換,並跳轉到系統調用對應的內核代碼位置執行,這樣內核就爲你完成了設備訪問,完成之後再從ring0返回ring3。這個過程也稱作用戶態和內核態的切換。那麼,虛擬化在這裏就遇到了一個難題,因爲宿主操作系統是工作在 ring0 的,客戶操作系統就不能也在 ring0 了,但是它不知道這一點,以前執行什麼指令,現在還是執行什麼指令,但是沒有執行權限是會出錯的。所以這時候虛擬機管理程序(VMM)需要避免這件事情發生。 虛機怎麼通過 VMM 實現 Guest CPU 對硬件的訪問,根據其原理不同有三種實現技術:全虛擬化、半虛擬化、硬件輔助的虛擬化。

(2)基於二進制翻譯的全虛擬化(Full Virtualization with Binary Translation)

代表產品:VMware Workstation,QEMU,Virtual PC

客戶操作系統運行在 Ring 1,它在執行特權指令時,會觸發異常(CPU的機制,沒權限的指令會觸發異常),然後 VMM 捕獲這個異常,在異常裏面做翻譯,模擬,最後返回到客戶操作系統內,客戶操作系統認爲自己的特權指令工作正常,繼續運行。但是這個性能損耗,就非常的大,簡單的一條指令,執行完,了事,現在卻要通過複雜的異常處理過程。

(3)超虛擬化(半虛擬化/操作系統輔助虛擬化 Paravirtualization)

代表產品:VMware ESXi/Microsoft Hyper-V/Xen 3.0/KVM

半虛擬化的思想就是,修改操作系統內核,替換掉不能虛擬化的指令,通過超級調用(hypercall)直接和底層的虛擬化層hypervisor來通訊,hypervisor 同時也提供了超級調用接口來滿足其他關鍵內核操作,比如內存管理、中斷和時間保持。種做法省去了全虛擬化中的捕獲和模擬,大大提高了效率。所以像XEN這種半虛擬化技術,客戶機操作系統都是有一個專門的定製內核版本,和x86、mips、arm這些內核版本等價。這樣以來,就不會有捕獲異常、翻譯、模擬的過程了,性能損耗非常低。這就是XEN這種半虛擬化架構的優勢。這也是爲什麼XEN只支持虛擬化Linux,無法虛擬化windows原因,微軟不改代碼啊。

(4)硬件輔助的全虛擬化

代表產品:Xen

2005年後,CPU廠商Intel 和 AMD 開始支持虛擬化了。 Intel 引入了 Intel-VT (Virtualization Technology)技術。 這種 CPU,有 VMX root operation 和 VMX non-root operation兩種模式,兩種模式都支持Ring 0 ~ Ring 3 共 4 個運行級別。這樣,VMM 可以運行在 VMX root operation模式下,客戶 OS 運行在VMX non-root operation模式下。而且兩種操作模式可以互相轉換。運行在 VMX root operation 模式下的 VMM 通過顯式調用 VMLAUNCH 或 VMRESUME 指令切換到 VMX non-root operation 模式,硬件自動加載 Guest OS 的上下文,於是 Guest OS 獲得運行,這種轉換稱爲 VM entry。Guest OS 運行過程中遇到需要 VMM 處理的事件,例如外部中斷或缺頁異常,或者主動調用 VMCALL 指令調用 VMM 的服務的時候(與系統調用類似),硬件自動掛起 Guest OS,切換到 VMX root operation 模式,恢復 VMM 的運行,這種轉換稱爲 VM exit。VMX root operation 模式下軟件的行爲與在沒有 VT-x 技術的處理器上的行爲基本一致;而VMX non-root operation 模式則有很大不同,最主要的區別是此時運行某些指令或遇到某些事件時,發生 VM exit。也就說,硬件這層就做了些區分,這樣全虛擬化下,那些靠“捕獲異常-翻譯-模擬”的實現就不需要了。而且CPU廠商,支持虛擬化的力度越來越大,靠硬件輔助的全虛擬化技術的性能逐漸逼近半虛擬化,再加上全虛擬化不需要修改客戶操作系統這一優勢,全虛擬化技術應該是未來的發展趨勢。

(5)多 CPU 服務器架構:SMP,NMP,NUMA

從系統架構來看,目前的商用服務器大體可以分爲三類:

(1)多處理器結構 (SMP,Symmetric Multi-Processor):所有的CPU共享全部資源,如總線,內存和I/O系統等,操作系統或管理數據庫的複本只有一個,這種系統有一個最大的特點就是共享所有資源。多個CPU之間沒有區別,平等地訪問內存、外設、一個操作系統。SMP 服務器的主要問題,那就是它的擴展能力非常有限。實驗證明, SMP 服務器 CPU 利用率最好的情況是 2 至 4 個 CPU 。

(2)海量並行處理結構 (MPP,Massive Parallel Processing):NUMA 服務器的基本特徵是具有多個 CPU 模塊,每個 CPU 模塊由多個 CPU( 如 4 個 ) 組成,並且具有獨立的本地內存、 I/O 槽口等。在一個物理服務器內可以支持上百個 CPU 。但 NUMA 技術同樣有一定缺陷,由於訪問遠地內存的延時遠遠超過本地內存,因此當 CPU 數量增加時,系統性能無法線性增加。

(3)MPP 模式則是一種分佈式存儲器模式,能夠將更多的處理器納入一個系統的存儲器。一個分佈式存儲器模式具有多個節點,每個節點都有自己的存儲器,可以配置爲SMP模式,也可以配置爲非SMP模式。單個的節點相互連接起來就形成了一個總系統。MPP可以近似理解成一個SMP的橫向擴展集羣,MPP一般要依靠軟件實現。

(4)非一致存儲訪問結構 (NUMA : Non-Uniform Memory Access):它由多個 SMP 服務器通過一定的節點互聯網絡進行連接,協同工作,完成相同的任務,從用戶的角度來看是一個服務器系統。其基本特徵是由多個 SMP 服務器 ( 每個 SMP 服務器稱節點 ) 通過節點互聯網絡連接而成,每個節點只訪問自己的本地資源 ( 內存、存儲等 ),是一種完全無共享 (Share Nothing) 結構。

通過uname -a可以查看CPU架構:

Linux linux.blue 3.10.0-1062.4.1.el7.x86_64 #1 SMP Fri Oct 18 17:15:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

(6)客戶機系統的代碼是如何運行的?

一個普通的 Linux 內核有兩種執行模式:內核模式(Kenerl)和用戶模式 (User)。爲了支持帶有虛擬化功能的 CPU,KVM 向 Linux 內核增加了第三種模式即客戶機模式(Guest),該模式對應於 CPU 的 VMX non-root mode。KVM 內核模塊作爲 User mode 和 Guest mode 之間的橋樑:User mode 中的 QEMU-KVM 會通過 ICOTL 命令來運行虛擬機,KVM 內核模塊收到該請求後,它先做一些準備工作,比如將 VCPU 上下文加載到 VMCS (virtual machine control structure)等,然後驅動 CPU 進入 VMX non-root 模式,開始執行客戶機代碼。三種模式的分工爲:Guest 模式,執行客戶機系統非 I/O 代碼,並在需要的時候驅動 CPU 退出該模式;Kernel 模式,負責將 CPU 切換到 Guest mode 執行 Guest OS 代碼,並在 CPU 退出 Guest mode 時回到 Kenerl 模式;User 模式,代表客戶機系統執行 I/O 操作。

(7)QEMU-KVM 相比原生 QEMU 的改動

(1)原生的 QEMU 通過指令翻譯實現 CPU 的完全虛擬化,但是修改後的 QEMU-KVM 會調用 ICOTL 命令來調用 KVM 模塊。

(2)原生的 QEMU 是單線程實現,QEMU-KVM 是多線程實現。

(8)從客戶機線程到物理 CPU 的兩次調度

要將客戶機內的線程調度到某個物理 CPU,需要經歷兩個過程:

(1)客戶機線程調度到客戶機物理CPU 即 KVM vCPU,該調度由客戶機操作系統負責,每個客戶機操作系統的實現方式不同。在 KVM 上,vCPU 在客戶機系統看起來就像是物理 CPU,因此其調度方法也沒有什麼不同。

(2)vCPU 線程調度到物理 CPU 即主機物理 CPU,該調度由 Hypervisor 即 Linux 負責。

KVM 使用標準的 Linux 進程調度方法來調度 vCPU 進程。Linux 系統中,線程和進程的區別是 進程有獨立的內核空間,線程是代碼的執行單位,也就是調度的基本單位。Linux 中,線程是就是輕量級的進程,也就是共享了部分資源(地址空間、文件句柄、信號量等等)的進程,所以線程也按照進程的調度方式來進行調度。

此處應該說明Linux 進程調度原理和處理器親和性(可以設置 vCPU 在指定的物理 CPU 上運行)。

(9)支持的客戶機CPU結構和模型

KVM 支持 SMP 和 NUMA 多CPU架構的主機和客戶機。對 SMP 類型的客戶機,使用 “-smp”參數;對 NUMA 類型的客戶機,使用 “-numa”參數。CPU 模型定義了哪些主機的 CPU 功能,會被暴露給客戶機操作系統。爲了在具有不同 CPU 功能的主機之間做安全的遷移,qemu-kvm 往往不會將主機CPU的所有功能都暴露給客戶機。其原理如下:

一些關於KVM和VMware虛擬化原理的總結

每個 Hypervisor 都有自己的策略,來定義默認上哪些CPU功能會被暴露給客戶機。至於哪些功能會被暴露給客戶機系統,取決於客戶機的配置。qemu32 和 qemu64 是基本的客戶機 CPU 模型,但是還有其他的模型可以使用。你可以使用 qemu-kvm 命令的 -cpu 參數來指定客戶機的 CPU 模型,還可以附加指定的 CPU 特性。"-cpu" 會將該指定 CPU 模型的所有功能全部暴露給客戶機,即使某些特性在主機的物理CPU上不支持,這時候QEMU/KVM 會模擬這些特性,因此,這時候也許會出現一定的性能下降。

(10)客戶機 vCPU 數目的分配方法

(1)不是客戶機的 vCPU 越多,其性能就越好,因爲線程切換會耗費大量的時間;應該根據負載需要分配最少的 vCPU。

(2)主機上的客戶機的 vCPU 總數不應該超過物理 CPU 內核總數。不超過的話,就不存在 CPU 競爭,每個 vCPU 線程在一個物理 CPU 核上被執行;超過的話,會出現部分線程等待 CPU 以及一個 CPU 核上的線程之間的切換,這會有 overhead。

(3)將負載分爲計算負載和 I/O 負載,對計算負載,需要分配較多的 vCPU,甚至考慮 CPU 親和性,將指定的物理 CPU 核分給給這些客戶機。

三、內存虛擬化

(1)概念

通過內存虛擬化共享物理系統內存,動態分配給虛擬機。虛擬機的內存虛擬化很像現在的操作系統支持的虛擬內存方式,應用程序看到鄰近的內存地址空間,這個地址空間無需和下面的物理機器內存直接對應,操作系統保持着虛擬頁到物理頁的映射。現在所有的 x86 CPU 都包括了一個稱爲內存管理的模塊MMU(Memory Management Unit)和 TLB(Translation Lookaside Buffer),通過MMU和TLB來優化虛擬內存的性能。KVM 實現客戶機內存的方式是,利用mmap系統調用,在QEMU主線程的虛擬地址空間中申明一段連續的大小的空間用於客戶機物理內存映射。

(2)VMM內存虛擬化的實現方式

(1)軟件方式:通過軟件實現內存地址的翻譯,比如 Shadow page table (影子頁表)技術。

(2)硬件實現:基於 CPU 的輔助虛擬化功能,比如 AMD 的 NPT 和 Intel 的 EPT 技術。

在KVM 中,虛機的物理內存即爲 qemu-kvm 進程所佔用的內存空間。KVM 使用 CPU 輔助的內存虛擬化方式。在 Intel 和 AMD 平臺,其內存虛擬化的實現方式分別爲:

(1)AMD 平臺上的 NPT (Nested Page Tables) 技術。

(2)Intel 平臺上的 EPT (Extended Page Tables)技術。

EPT 和 NPT採用類似的原理,都是作爲 CPU 中新的一層,用來將客戶機的物理地址翻譯爲主機的物理地址。EPT的好處是,它的兩階段記憶體轉換,特點就是將 Guest Physical Address → System Physical Address,VMM不用再保留一份 SPT (Shadow Page Table),以及以往還得經過 SPT 這個轉換過程。除了降低各部虛擬機器在切換時所造成的效能損耗外,硬體指令集也比虛擬化軟體處理來得可靠與穩定。

KSM (Kernel SamePage Merging 或者 Kernel Shared Memory)

KSM 在 Linux 2.6.32 版本中被加入到內核中。其原理是,KSM 作爲內核中的守護進程(稱爲 ksmd)存在,它定期執行頁面掃描,識別副本頁面併合並副本,釋放這些頁面以供它用。因此,在多個進程中,Linux將內核相似的內存頁合併成一個內存頁。這個特性,被KVM用來減少多個相似的虛擬機的內存佔用,提高內存的使用效率。由於內存是共享的,所以多個虛擬機使用的內存減少了。這個特性,對於虛擬機使用相同鏡像和操作系統時,效果更加明顯。但是,事情總是有代價的,使用這個特性,都要增加內核開銷,用時間換空間。所以爲了提高效率,可以將這個特性關閉。其好處是,在運行類似的客戶機操作系統時,通過 KSM,可以節約大量的內存,從而可以實現更多的內存超分,運行更多的虛機。

KVM Huge Page Backed Memory (巨頁內存技術)

這是KVM虛擬機的又一個優化技術.。Intel 的 x86 CPU 通常使用4Kb內存頁,當是經過配置,也能夠使用巨頁。使用巨頁,KVM的虛擬機的頁表將使用更少的內存,並且將提高CPU的效率。最高情況下,可以提高20%的效率!

四、IO虛擬化

在 QEMU/KVM 中,客戶機可以使用的設備大致可分爲三類:

(1)模擬設備:完全由 QEMU 純軟件模擬的設備。

(2)Virtio 設備:實現 VIRTIO API 的半虛擬化設備。

(3)PCI 設備直接分配 (PCI device assignment) 。

(1)全虛擬化 I/O 設備

KVM 在 IO 虛擬化方面,傳統或者默認的方式是使用 QEMU 純軟件的方式來模擬 I/O 設備,包括鍵盤、鼠標、顯示器,硬盤 和 網卡 等。模擬設備可能會使用物理的設備,或者使用純軟件來模擬。模擬設備只存在於軟件中。

一些關於KVM和VMware虛擬化原理的總結

(1)客戶機的設備驅動程序發起 I/O 請求操作請求。

(2)KVM 模塊中的 I/O 操作捕獲代碼攔截這次 I/O 請求。

(3)經過處理後將本次 I/O 請求的信息放到 I/O 共享頁 (sharing page),並通知用戶空間的 QEMU 程序。

(4)QEMU 程序獲得 I/O 操作的具體信息之後,交由硬件模擬代碼來模擬出本次 I/O 操作。

(5)完成之後,QEMU 將結果放回 I/O 共享頁,並通知 KMV 模塊中的 I/O 操作捕獲代碼。

(6)KVM 模塊的捕獲代碼讀取 I/O 共享頁中的操作結果,並把結果放回客戶機。

注意:當客戶機通過DMA (Direct Memory Access)訪問大塊I/O時,QEMU 模擬程序將不會把結果放進共享頁中,而是通過內存映射的方式將結果直接寫到客戶機的內存中,然後通知KVM模塊告訴客戶機DMA操作已經完成。這種方式的優點是可以模擬出各種各樣的硬件設備;其缺點是每次 I/O 操作的路徑比較長,需要多次上下文切換,也需要多次數據複製,所以性能較差。

(2)QEMU 模擬網卡的實現

Qemu 純軟件的方式來模擬I/O設備,其中包括經常使用的網卡設備。Guest OS啓動命令中沒有傳入的網絡配置時,QEMU默認分配 rtl8139 類型的虛擬網卡類型,使用的是默認用戶配置模式,這時候由於沒有具體的網絡模式的配置,Guest的網絡功能是有限的。 全虛擬化情況下,KVM虛機可以選擇的網絡模式包括:默認用戶模式、基於網橋的模式和基於NAT的模式。

網橋模式如下:

一些關於KVM和VMware虛擬化原理的總結

(1)網絡數據從 Host 上的物理網卡接收,到達網橋。

(2)由於 eth0 與 tap1 均加入網橋中,根據二層轉發原則,br0 將數據從 tap1 口轉發出去,即數據由 Tap設備接收。

(3)Tap 設備通知對應的 fd 數據可讀。

(4)fd 的讀動作通過 tap 設備的字符設備驅動將數據拷貝到用戶空間,完成數據報文的前端接收。

(3)準虛擬化 (Para-virtualizaiton) I/O 驅動 virtio

在 KVM 中可以使用準虛擬化驅動來提供客戶機的I/O 性能。目前 KVM 採用的的是 virtio 這個 Linux 上的設備驅動標準框架,它提供了一種 Host 與 Guest 交互的 IO 框架。KVM/QEMU 的 vitio 實現採用在 Guest OS 內核中安裝前端驅動 (Front-end driver)和在 QEMU 中實現後端驅動(Back-end)的方式。前後端驅動通過 vring 直接通信,這就繞過了經過 KVM 內核模塊的過程,達到提高 I/O 性能的目的。純軟件模擬的設備和 Virtio 設備的區別:virtio 省去了純模擬模式下的異常捕獲環節,Guest OS 可以和 QEMU 的 I/O 模塊直接通信。Host 數據發到 Guest,KVM 通過中斷的方式通知 QEMU 去獲取數據,放到 virtio queue 中,KVM 再通知 Guest 去 virtio queue 中取數據。

一些關於KVM和VMware虛擬化原理的總結

Virtio 在 Linux 中的實現

Virtio 是在半虛擬化管理程序中的一組通用模擬設備的抽象。這種設計允許管理程序通過一個應用編程接口 (API)對外提供一組通用模擬設備。通過使用半虛擬化管理程序,客戶機實現一套通用的接口,來配合後面的一套後端設備模擬。後端驅動不必是通用的,只要它們實現了前端所需的行爲。因此,Virtio 是一個在 Hypervisor 之上的抽象API接口,讓客戶機知道自己運行在虛擬化環境中,進而根據 virtio 標準與 Hypervisor 協作,從而客戶機達到更好的性能。

(1)前端驅動:客戶機中安裝的驅動程序模塊。

(2)後端驅動:在 QEMU 中實現,調用主機上的物理設備,或者完全由軟件實現。

(3)virtio 層:虛擬隊列接口,從概念上連接前端驅動和後端驅動。驅動可以根據需要使用不同數目的隊列。比如 virtio-net 使用兩個隊列,virtio-block只使用一個隊列。該隊列是虛擬的,實際上是使用 virtio-ring 來實現的。

(4)virtio-ring:實現虛擬隊列的環形緩衝區。

Linux 內核中實現的五個前端驅動程序

(1)塊設備(如磁盤)

(2)網絡設備

(3)PCI 設備

(4)氣球驅動程序(動態管理客戶機內存使用情況)

(5)控制檯驅動程序

使用 virtio 設備 (以 virtio-net 爲例)

Guest OS 中,在不使用 virtio 設備的時候,這些驅動不會被加載。只有在使用某個 virtio 設備的時候,對應的驅動纔會被加載。每個前端驅動器具有在管理程序中的相應的後端的驅動程序。以 virtio-net 爲例,解釋其原理:

(1)多個虛機共享主機網卡 eth0。

(2)QEMU 使用標準的 tun/tap 將虛機的網絡橋接到主機網卡上。

(3)每個虛機看起來有一個直接連接到主機PCI總線上的私有 virtio 網絡設備。

(4)需要在虛機裏面安裝 virtio驅動。

總結 Virtio 的優缺點:更高的IO性能,幾乎可以和原生系統差不多。客戶機必須安裝特定的 virtio 驅動。一些老的 Linux 還沒有驅動支持,一些 Windows 需要安裝特定的驅動。不過,較新的和主流的OS都有驅動可以下載了。Linux 2.6.24+ 都默認支持 virtio。可以使用 lsmod | grep virtio 查看是否已經加載。

vhost-net (kernel-level virtio server)

前面提到 virtio 在宿主機中的後端處理程序(backend)一般是由用戶空間的QEMU提供的,然而如果對於網絡 I/O 請求的後端處理能夠在在內核空間來完成,則效率會更高,會提高網絡吞吐量和減少網絡延遲。在比較新的內核中有一個叫做 “vhost-net” 的驅動模塊,它是作爲一個內核級別的後端處理程序,將virtio-net的後端處理任務放到內核空間中執行,減少內核空間到用戶空間的切換,從而提高效率。

vhost-net 的要求:qemu-kvm-0.13.0 或者以上,主機內核中設置 CONFIG_VHOST_NET=y 和在虛機操作系統內核中設置 CONFIG_PCI_MSI=y (Red Hat Enterprise Linux 6.1 開始支持該特性),在客戶機內使用 virtion-net 前段驅動,在主機內使用網橋模式,並且啓動 vhost_net。

一般來說,使用 vhost-net 作爲後端處理驅動可以提高網絡的性能。不過,對於一些網絡負載類型使用 vhost-net 作爲後端,卻可能使其性能不升反降。特別是從宿主機到其中的客戶機之間的UDP流量,如果客戶機處理接受數據的速度比宿主機發送的速度要慢,這時就容易出現性能下降。在這種情況下,使用vhost-net將會是UDP socket的接受緩衝區更快地溢出,從而導致更多的數據包丟失。故這種情況下,不使用vhost-net,讓傳輸速度稍微慢一點,反而會提高整體的性能。使用 qemu-kvm 命令行,加上“vhost=off”(或沒有vhost選項)就會不使用vhost-net,而在使用libvirt時,需要對客戶機的配置的XML文件中的網絡配置部分進行如下的配置,指定後端驅動的名稱爲“qemu”(而不是“vhost”)。

virtio-balloon

另一個比較特殊的 virtio 設備是 virtio-balloon。通常來說,要改變客戶機所佔用的宿主機內存,要先關閉客戶機,修改啓動時的內存配置,然後重啓客戶機纔可以實現。而 內存的 ballooning (氣球)技術可以在客戶機運行時動態地調整它所佔用的宿主機內存資源,而不需要關閉客戶機。該技術能夠:當宿主機內存緊張時,可以請求客戶機回收利用已分配給客戶機的部分內存,客戶機就會釋放部分空閒內存。若其內存空間不足,可能還會回收部分使用中的內存,可能會將部分內存換到交換分區中。當客戶機內存不足時,也可以讓客戶機的內存氣球壓縮,釋放出內存氣球中的部分內存,讓客戶機使用更多的內存。目前很多的VMM,包括 KVM, Xen,VMware 等都對 ballooning 技術提供支持。其中,KVM 中的 Ballooning 是通過宿主機和客戶機協同來實現的,在宿主機中應該使用 2.6.27 及以上版本的 Linux內核(包括KVM模塊),使用較新的 qemu-kvm(如0.13版本以上),在客戶機中也使用 2.6.27 及以上內核且將“CONFIG_VIRTIO_BALLOON”配置爲模塊或編譯到內核。在很多Linux發行版中都已經配置有“CONFIG_VIRTIO_BALLOON=m”,所以用較新的Linux作爲客戶機系統,一般不需要額外配置virtio_balloon驅動,使用默認內核配置即可。
(1)KVM 發送請求給 VM 讓其歸還一定數量的內存給KVM。
(2)VM 的 virtio_balloon 驅動接到該請求。
(3)VM 的驅動是客戶機的內存氣球膨脹,氣球中的內存就不能被客戶機使用。
(4)VM 的操作系統歸還氣球中的內存給VMM
(5)KVM 可以將得到的內存分配到任何需要的地方。
(6)KVM 也可以將內存返還到客戶機中。
優勢和不足:ballooning 可以被控制和監控,對內存的調節很靈活,可多可少。KVM 可以歸還內存給客戶機,從而緩解其內存壓力。需要客戶機安裝驅動。大量內存被回收時,會降低客戶機的性能。目前沒有方便的自動化的機制來管理 ballooning,一般都在 QEMU 的 monitor 中執行命令來實現。內存的動態增加或者減少,可能是內存被過度碎片化,從而降低內存使用性能。在QEMU monitor中,提供了兩個命令查看和設置客戶機內存的大小。

(qemu) info balloon    #查看客戶機內存佔用量(Balloon信息)
(qemu) balloon num     #設置客戶機內存佔用量爲numMB

RedHat 的 多隊列 Virtio (multi-queue)

目前的高端服務器都有多個處理器,虛擬使用的虛擬CPU數目也不斷增加。默認的 virtio-net 不能並行地傳送或者接收網絡包,因爲 virtio_net 只有一個TX 和 RX 隊列。而多隊列 virtio-net 提供了一個隨着虛機的虛擬CPU增加而增強網絡性能的方法,通過使得 virtio 可以同時使用多個 virt-queue 隊列。它在以下情況下具有明顯優勢:

(1)網絡流量非常大。

(2)虛機同時有非常多的網絡連接,包括虛擬機之間的、虛機到主機的、虛機到外部系統的等。

(3)virtio 隊列的數目和虛機的虛擬CPU數目相同。這是因爲多隊列能夠使得一個隊列獨佔一個虛擬CPU。

注意:對隊列 virtio-net 對流入的網絡流工作得非常好,但是對外發的數據流偶爾會降低性能。打開對隊列 virtio 會增加中的吞吐量,這相應地會增加CPU的負擔。 在實際的生產環境中需要做必須的測試後才確定是否使用。

五、I/O 設備直接分配和 SR-IOV

本文將分析 PCI/PCIe 設備直接分配(Pass-through)和 SR-IOV, 以及三種 I/O 虛擬化方式的比較。

(1)PCI/PCI-E 設備直接分配給虛機 (PCI Pass-through)

設備直接分配 (Device assignment)也稱爲 Device Pass-Through。PCI/PCIe Pass-through 原理如下:
這種方式,允許將宿主機中的物理 PCI 設備直接分配給客戶機使用。較新的x86平臺已經支持這種類型,Intel 定義的 I/O 虛擬化技術成爲 VT-d,AMD 的稱爲 AMD-V。KVM 支持客戶機以獨佔方式訪問這個宿主機的 PCI/PCI-E 設備。通過硬件支持的 VT-d 技術將設備分給客戶機後,在客戶機看來,設備是物理上連接在PCI或者PCI-E總線上的,客戶機對該設備的I/O交互操作和實際的物理設備操作完全一樣,不需要或者很少需要 KVM 的參與。運行在 VT-d 平臺上的 QEMU/KVM,可以分配網卡、磁盤控制器、USB控制器、VGA 顯卡等設備供客戶機直接使用。幾乎所有的 PCI 和 PCI-E 設備都支持直接分配,除了顯卡以外,PCI Pass-through 需要硬件平臺 Intel VT-d 或者 AMD IOMMU 的支持。這些特性必須在 BIOS 中被啓用。Red Hat Enterprise Linux 6.0 及以上版本支持熱插拔的 PCI 設備直接分配到虛擬機。一般 SATA 或者 SAS 等類型的硬盤的控制器都是直接接入到 PCI 或者 PCI-E 總線的,所以也可以將硬盤作爲普通的PCI設備直接分配個客戶機。需要注意的是,當分配硬盤時,實際上將其控制器作爲一個整體分配到客戶機中,因此需要在硬件平臺上至少有另兩個或者多個SATA或者 SAS控制器。

(2)設備直接分配讓客戶機的優勢和不足

在執行 I/O 操作時大量減少甚至避免 VM-Exit 陷入到 Hypervisor 中,極大地提高了性能,可以達到幾乎和原生系統一樣的性能。VT-d 克服了 virtio 兼容性不好和 CPU 使用頻率較高的問題。一臺服務器主板上的空間比較有限,因此允許添加的 PCI 和 PCI-E 設備是有限的。大量使用 VT-d 獨立分配設備給客戶機,讓硬件設備數量增加,這會增加硬件投資成本。對於使用 VT-d 直接分配了設備的客戶機,其動態遷移功能將受限,不過也可以使用熱插拔或者libvirt 工具等方式來緩解這個問題。

(3)針對設備直接分配給客戶機的不足提出的解決方案

在一臺物理宿主機上,僅少數 I/O 如網絡性能要求較高的客戶機使用 VT-d直接分配設備,其他的使用純模擬或者 virtio 已達到多個客戶機共享同一個設備的目的。對於網絡I/O的解決辦法,可以選擇 SR-IOV 是一個網卡產生多個獨立的虛擬網卡,將每個虛擬網卡分配個一個客戶機使用。

(4)SR-IOV 設備分配

VT-d 的性能非常好,但是它的物理設備只能分配給一個客戶機使用。爲了實現多個虛機共享一個物理設備,並且達到直接分配的目的,PCI-SIG 組織發佈了 SR-IOV (Single Root I/O Virtualization and sharing) 規範,它定義了一個標準化的機制用以原生地支持實現多個客戶機共享一個設備。不過,目前 SR-IOV (單根 I/O 虛擬化)最廣泛地應用還是網卡上。SR-IOV 使得一個單一的功能單元(比如,一個以太網端口)能看起來像多個獨立的物理設備。一個帶有 SR-IOV 功能的物理設備能被配置爲多個功能單元。SR-IOV 使用兩種功能(function):
(1)物理功能(Physical Functions,PF):這是完整的帶有 SR-IOV 能力的PCIe 設備。PF 能像普通 PCI 設備那樣被發現、管理和配置。
(2)虛擬功能(Virtual Functions,VF):簡單的 PCIe 功能,它只能處理I/O。每個 VF 都是從 PF 中分離出來的。每個物理硬件都有一個 VF 數目的限制。一個 PF,能被虛擬成多個 VF 用於分配給多個虛擬機。
Hypervisor 能將一個或者多個 VF 分配給一個虛機。在某一時刻,一個 VF 只能被分配給一個虛機。一個虛機可以擁有多個 VF。在虛機的操作系統看來,一個 VF 網卡看起來和一個普通網卡沒有區別。SR-IOV 驅動是在內核中實現的。

(5)SR-IOV 的條件

(1)需要 CPU 支持 Intel VT-x 和 VT-D (或者 AMD 的 SVM 和 IOMMU)
(2)需要有支持 SR-IOV 規範的設備:目前這種設備較多,比如Intel的很多中高端網卡等。
(3)需要 QEMU/KAM 的支持。

六、Libvirt

(1)爲什麼需要Libvirt?

(1)Hypervisor 比如 qemu-kvm 的命令行虛擬機管理工具參數衆多,難於使用。
(2)Hypervisor 種類衆多,沒有統一的編程接口來管理它們,這對雲環境來說非常重要。
(3)沒有統一的方式來方便地定義虛擬機相關的各種可管理對象。

(2)Libvirt提供了什麼?

(1)它提供統一、穩定、開放的源代碼的應用程序接口(API)、守護進程 (libvirtd)和和一個默認命令行管理工具(virsh)。
(2)它提供了對虛擬化客戶機和它的虛擬化設備、網絡和存儲的管理。
(3)它提供了一套較爲穩定的C語言應用程序接口。目前,在其他一些流行的編程語言中也提供了對libvirt的綁定,在Python、Perl、Java、Ruby、PHP、OCaml等高級編程語言中已經有libvirt的程序庫可以直接使用。
(4)它對多種不同的 Hypervisor 的支持是通過一種基於驅動程序的架構來實現的。libvirt 對不同的 Hypervisor 提供了不同的驅動,包括 Xen 的驅動,對QEMU/KVM 有 QEMU 驅動,VMware 驅動等。在 libvirt 源代碼中,可以很容易找到 qemu_driver.c、xen_driver.c、xenapi_driver.c、vmware_driver.c、vbox_driver.c 這樣的驅動程序源代碼文件。
(5)它作爲中間適配層,讓底層 Hypervisor 對上層用戶空間的管理工具是可以做到完全透明的,因爲 libvirt 屏蔽了底層各種 Hypervisor 的細節,爲上層管理工具提供了一個統一的、較穩定的接口(API)。
(6)它使用 XML 來定義各種虛擬機相關的受管理對象。
目前,libvirt 已經成爲使用最爲廣泛的對各種虛擬機進行管理的工具和應用程序接口(API),而且一些常用的虛擬機管理工具(如virsh、virt-install、virt-manager等)和雲計算框架平臺(如OpenStack、OpenNebula、Eucalyptus等)都在底層使用libvirt的應用程序接口。

七、QEMU/KVM 快照

磁盤快照:磁盤的內容(可能是虛機的全部磁盤或者部分磁盤)在某個時間點上被保存,然後可以被恢復。在一個運行着的系統上,一個磁盤快照很可能只是崩潰一致的(crash-consistent) 而不是完整一致(clean)的,也是說它所保存的磁盤狀態可能相當於機器突然掉電時硬盤數據的狀態,機器重啓後需要通過 fsck 或者別的工具來恢復到完整一致的狀態(類似於 Windows 機器在斷電後會執行文件檢查)。對一個非運行中的虛機來說,如果上次虛機關閉的時候磁盤是完整一致的,那麼其被快照的磁盤快照也將是完整一致的。磁盤快照有兩種:內部快照 - 使用單個的 qcow2 的文件來保存快照和快照之後的改動。這種快照是 libvirt 的默認行爲,現在的支持很完善(創建、回滾和刪除),但是隻能針對 qcow2 格式的磁盤鏡像文件,而且其過程較慢等。外部快照 - 快照是一個只讀文件,快照之後的修改是另一個 qcow2 文件中。外置快照可以針對各種格式的磁盤鏡像文件。外置快照的結果是形成一個 qcow2 文件鏈:original <- snap1 <- snap2 <- snap3。

內存狀態(或者虛機狀態):只是保持內存和虛機使用的其它資源的狀態。如果虛機狀態快照在做和恢復之間磁盤沒有被修改,那麼虛機將保持一個持續的狀態;如果被修改了,那麼很可能導致數據corruption。

系統還原點(system checkpoint):虛機的所有磁盤的快照和內存狀態快照的集合,可用於恢復完整的系統狀態(類似於系統休眠)。

關於 崩潰一致(crash-consistent)的附加說明:應該儘量避免在虛機I/O繁忙的時候做快照。這種時候做快照不是可取的辦法。vmware 的做法是裝一個 tools,它是個 PV driver,可以在做快照的時候掛起系統。似乎 KVM 也有類似的實現 QEMU Guest Agent,但是還不是很成熟。

八、虛擬機遷移

(1)使用 libvirt 遷移 QEMU/KVM 虛機和 Nova 虛機

遷移(migration)包括系統整體的遷移和某個工作負載的遷移。系統整理遷移,是將系統上所有軟件包括操作系統完全複製到另一個物理機硬件機器上。虛擬化環境中的遷移,可分爲靜態遷移(static migration,或者 冷遷移 cold migration,或者離線遷移 offline migration) 和 動態遷移 (live migration,或者 熱遷移 hot migration 或者 在線遷移 online migration)。靜態遷移和動態遷移的最大區別是,靜態遷移有明顯一段時間客戶機中的服務不可用,而動態遷移則沒有明顯的服務暫停時間。虛擬化環境中的靜態遷移也可以分爲兩種,一種是關閉客戶機後,將其硬盤鏡像複製到另一臺宿主機上然後恢復啓動起來,這種遷移不能保留客戶機中運行的工作負載;另一種是兩臺宿主機共享存儲系統,這時候的遷移可以保持客戶機遷移前的內存狀態和系統運行的工作負載。 動態遷移,是指在保證客戶機上應用服務正常運行的同時,讓客戶機在不同的宿主機之間進行遷移,其邏輯步驟和前面的靜態遷移幾乎一致,有硬盤存儲和內存都複製的動態遷移,也有僅複製內存鏡像的動態遷移。不同的是,爲了保證遷移過程中客戶機服務的可用性,遷移過程只能有非常短暫的停機時間。動態遷移允許系統管理員將客戶機在不同物理機上遷移,同時不會斷開訪問客戶機中服務的客戶端或者應用程序的連接。一個成功的遷移,需要保證客戶機的內存、硬盤存儲和網絡連接在遷移到目的主機後任然保持不變,而且遷移的過程的服務暫停時間較短。

(2)遷移效率的衡量

(1)整體遷移時間
(2)服務器停機時間:這時間是指源主機上的客戶機已經暫停服務,而目的主機上客戶機尚未恢復服務的時間。
(3)對服務性能的影響:客戶機遷移前後性能的影響,以及目的主機上其它服務的性能影響。
其中,整體遷移時間受很多因素的影響,比如 Hypervisor 和遷移工具的種類、磁盤存儲的大小(是否需要複製磁盤鏡像)、內存大小及使用率、CPU 的性能和利用率、網絡帶寬大小及是否擁塞等,整體遷移時間一般分爲幾秒鐘到幾十分鐘不等。動態遷移的服務停機時間,也有這些因素的影響,往往在幾毫秒到幾百毫秒。而靜態遷移,其暫停時間較長。因此,靜態遷移一般適合於對服務可用性要求不高的場景,而動態遷移適合於對可用性要求高的場景。
動態遷移的應用場景包括:負載均衡、解除硬件依賴、節約能源 和異地遷移。

(3)KVM 遷移的原理

對於靜態遷移,你可以在宿主機上某客戶機的 QEMU monitor 中,用 savevm my_tag 命令保存一個完整的客戶機鏡像快照,然後在宿主機中關閉或者暫停該客戶機,然後將該客戶機的鏡像文件複製到另一臺宿主機中,使用在源主機中啓動該客戶機時的命令來啓動複製過來的鏡像,在其 QEMU monitor 中 loadvm my_tag 命令恢復剛纔保存的快照即可完全加載保存快照時的客戶機狀態。savevm 命令可以保證完整的客戶機狀態,包括 CPU 狀態、內存、設備狀態、可寫磁盤中的內存等。注意,這種方式需要 qcow2、qed 等格式的磁盤鏡像文件的支持。

如果源宿主機和目的宿主機共享存儲系統,則只需要通過網絡發送客戶機的 vCPU 執行狀態、內存中的內容、虛機設備的狀態到目的主機上。否則,還需要將客戶機的磁盤存儲發到目的主機上。共享存儲系統指的是源和目的虛機的鏡像文件目錄是在一個共享的存儲上的。

在基於共享存儲系統時,KVM 動態遷移的具體過程爲:

(1)遷移開始時,客戶機依然在宿主機上運行,與此同時,客戶機的內存頁被傳輸到目的主機上。

(2)QEMU/KVM 會監控並記錄下遷移過程中所有已被傳輸的內存頁的任何修改,並在所有內存頁都傳輸完成後即開始傳輸在前面過程中內存頁的更改內容。

(3)QEMU/KVM 會估計遷移過程中的傳輸速度,當剩餘的內存數據量能夠在一個可以設定的時間週期(默認 30 毫秒)內傳輸完成時,QEMU/KVM 會關閉源宿主機上的客戶機,再將剩餘的數據量傳輸到目的主機上,最後傳輸過來的內存內容在目的宿主機上恢復客戶機的運行狀態。

(4)至此,KVM 的動態遷移操作就完成了。遷移後的客戶機儘可能與遷移前一直,除非目的主機上缺少一些配置,比如網橋等。

注意,當客戶機中內存使用率非常大而且修改頻繁時,內存中數據不斷被修改的速度大於KVM能夠傳輸的內存速度時,動態遷移的過程是完成不了的,這時候只能靜態遷移。

(4)OpenStack Nova QEMU/KVM 實例動態遷移的環境配置

除了直接拷貝磁盤鏡像文件的冷遷移,OpenStack 還支持下面幾種虛機熱遷移模式:
(1)不使用共享存儲時的塊實時遷移(Block live migration without shared storage)。這種模式不支持使用只讀設備比如 CD-ROM 和 Config Drive。塊實時遷移不需要 nova compute 節點都使用共享存儲。它使用 TCP 來將虛機的鏡像文件通過網絡拷貝到目的主機上,因此和共享存儲式的實時遷移相比,這種方式需要更長的時間。而且在遷移過程中,主機的性能包括網絡和 CPU 會下降。
(2)基於共享存儲的實時遷移 (Shared storage based live migration):兩個主機可以訪問共享的存儲。
(3)從卷啓動的虛機的實時遷移(Volume backed VM live migration)。這種遷移也是一種塊拷貝遷移。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章