tft每日頭條

 > 生活

 > 一圖看懂kvm虛拟化

一圖看懂kvm虛拟化

生活 更新时间:2024-06-12 18:40:51

  X86 操作系統是設計在直接運行在裸硬件設備上的,因此它們自動認為它們完全占有計算機硬件。x86 架構提供四個特權級别給操作系統和應用程序來訪問硬件。 Ring 是指 CPU 的運行級别,Ring 0是最高級别,Ring1次之,Ring2更次之…… 就 Linux x86 來說,

  操作系統(内核)需要直接訪問硬件和内存,因此它的代碼需要運行在最高運行級别 Ring0上,這樣它可以使用特權指令,控制中斷、修改頁表、訪問設備等等。

  應用程序的代碼運行在最低運行級别上ring3上,不能做受控操作。如果要做,比如要訪問磁盤,寫文件,那就要通過執行系統調用(函數),執行系統調用的時候,CPU的運行級别會發生從ring3到ring0的切換,并跳轉到系統調用對應的内核代碼位置執行,這樣内核就為你完成了設備訪問,完成之後再從ring0返回ring3。這個過程也稱作用戶态和内核态的切換。

  一圖看懂kvm虛拟化(虛拟化基本原理)(1)

  那麼,虛拟化在這裡就遇到了一個難題,因為宿主操作系統是工作在 ring0 的,客戶操作系統就不能也在 ring0 了,但是它不知道這一點,以前執行什麼指令,現在還是執行什麼指令,但是沒有執行權限是會出錯的。所以這時候虛拟機管理程序(VMM)需要避免這件事情發生。 虛機怎麼通過 VMM 實現 Guest CPU 對硬件的訪問,根據其原理不同有三種實現技術:

  1. 全虛拟化

  2. 半虛拟化

  3. 硬件輔助的虛拟化

  1.1 基于二進制翻譯的全虛拟化(Full Virtualization with Binary Translation)

  一圖看懂kvm虛拟化(虛拟化基本原理)(2)

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

  異常 “捕獲(trap)-翻譯(handle)-模拟(emulate)” 過程:

  一圖看懂kvm虛拟化(虛拟化基本原理)(3)

  1.2. 超虛拟化(或者半虛拟化/操作系統輔助虛拟化 Paravirtualization)

  半虛拟化的思想就是,修改操作系統内核,替換掉不能虛拟化的指令,通過超級調用(hypercall)直接和底層的虛拟化層hypervisor來通訊,hypervisor 同時也提供了超級調用接口來滿足其他關鍵内核操作,比如内存管理、中斷和時間保持。

  這種做法省去了全虛拟化中的捕獲和模拟,大大提高了效率。所以像XEN這種半虛拟化技術,客戶機操作系統都是有一個專門的定制内核版本,和x86、mips、arm這些内核版本等價。這樣以來,就不會有捕獲異常、翻譯、模拟的過程了,性能損耗非常低。這就是XEN這種半虛拟化架構的優勢。這也是為什麼XEN隻支持虛拟化Linux,無法虛拟化windows原因,微軟不改代碼啊。

  一圖看懂kvm虛拟化(虛拟化基本原理)(4)

  1.3. 硬件輔助的全虛拟化

  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模式下。

  一圖看懂kvm虛拟化(虛拟化基本原理)(5)

  而且兩種操作模式可以互相轉換。運行在 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廠商,支持虛拟化的力度越來越大,靠硬件輔助的全虛拟化技術的性能逐漸逼近半虛拟化,再加上全虛拟化不需要修改客戶操作系統這一優勢,全虛拟化技術應該是未來的發展趨勢。

  (1)一個 KVM 虛機即一個Linux qemu-kvm 進程,與其他 Linux 進程一樣被Linux 進程調度器調度。

  (2)KVM 虛機包括虛拟内存、虛拟CPU和虛機 I/O設備,其中,内存和 CPU 的虛拟化由 KVM 内核模塊負責實現,I/O 設備的虛拟化由 QEMU 負責實現。

  (3)KVM戶機系統的内存是 qumu-kvm 進程的地址空間的一部分。

  (4)KVM 虛機的 vCPU 作為 線程運行在 qemu-kvm 進程的上下文中。

  支持虛拟化的 CPU 中都增加了新的功能。以 Intel VT 技術為例,它增加了兩種運行模式:VMX root 模式和 VMX nonroot 模式。通常來講,主機操作系統和 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 給客戶機使用。

  主機 Linux 将一個虛拟視作一個 QEMU 進程,該進程包括下面幾種線程:

  1.I/O 線程用于管理模拟設備

  2.vCPU 線程用于運行 Guest 代碼

  3.其它線程,比如處理 event loop,offloaded tasks 等的線程

  在我的測試環境中(RedHata Linux 作 Hypervisor):

  一圖看懂kvm虛拟化(虛拟化基本原理)(6)

  要将客戶機内的線程調度到某個物理 CPU,需要經曆兩個過程:

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

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

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

  vCPU如何設置

  我們來假設一個主機有 2 個socket,每個 socket 有 4 個core。主頻2.4G MHZ 那麼一共可用的資源是 2*4*2.4G= 19.2G MHZ。假設主機上運行了三個VM,VM1和VM2設置為1socket*1core,VM3設置為1socket*2core。那麼VM1和VM2分别有1個vCPU,而VM3有2個vCPU。假設其他設置為缺省設置。

  那麼三個VM獲得該主機CPU資源分配如下:VM1:25%; VM2:25%; VM3:50%

  假設運行在VM3上的應用支持多線程,那麼該應用可以充分利用到所非配的CPU資源。2vCPU的設置是合适的。假設運行在VM3上的應用不支持多線程,該應用根本無法同時使用利用2個vCPU. 與此同時,VMkernal層的CPU Scheduler必須等待物理層中兩個空閑的pCPU,才開始資源調配來滿足2個vCPU的需要。在僅有2vCPU的情況下,對該VM的性能不會有太大負面影響。但如果分配4vCPU或者更多,這種資源調度上的負擔有可能會對該VM上運行的應用有很大負面影響。

  确定 vCPU 數目的步驟。假如我們要創建一個VM,以下幾步可以幫助确定合适的vCPU數目

  1 了解應用并設置初始值

  該應用是否是關鍵應用,是否有Service Level Agreement。一定要對運行在虛拟機上的應用是否支持多線程深入了解。咨詢應用的提供商是否支持多線程和SMP(Symmetricmulti-processing)。參考該應用在物理服務器上運行時所需要的CPU個數。如果沒有參照信息,可設置1vCPU作為初始值,然後密切觀測資源使用情況。

  2 觀測資源使用情況

  确定一個時間段,觀測該虛拟機的資源使用情況。時間段取決于應用的特點和要求,可以是數天,甚至數周。不僅觀測該VM的CPU使用率,而且觀測在操作系統内該應用對CPU的占用率。特别要區分CPU使用率平均值和CPU使用率峰值。

  假如分配有4個vCPU,如果在該VM上的應用的CPU

  使用峰值等于25%, 也就是僅僅能最多使用25%的全部CPU資源,說明該應用是單線程的,僅能夠使用一個vCPU (4 * 25% = 1 )

  平均值小于38%,而峰值小于45%,考慮減少 vCPU 數目

  平均值大于75%,而峰值大于90%,考慮增加 vCPU 數目

  3 更改vCPU數目并觀測結果

  每次的改動盡量少,如果可能需要4vCPU,先設置2vCPU在觀測性能是否可以接受。

  KVM 實現客戶機内存的方式是,利用mmap系統調用,在QEMU主線程的虛拟地址空間中申明一段連續的大小的空間用于客戶機物理内存映射。

  一圖看懂kvm虛拟化(虛拟化基本原理)(7)

  KVM 中,虛機的物理内存即為 qemu-kvm 進程所占用的内存空間。KVM 使用 CPU 輔助的内存虛拟化方式。在 Intel 和 AMD 平台,其内存虛拟化的實現方式分别為:

  AMD 平台上的 NPT (Nested Page Tables) 技術

  Intel 平台上的 EPT (Extended Page Tables)技術

  EPT 和 NPT采用類似的原理,都是作為 CPU 中新的一層,用來将客戶機的物理地址翻譯為主機的物理地址。

  KSM 作為内核中的守護進程(稱為 ksmd)存在,它定期執行頁面掃描,識别副本頁面并合并副本,釋放這些頁面以供它用。因此,在多個進程中,Linux将内核相似的内存頁合并成一個内存頁。這個特性,被KVM用來減少多個相似的虛拟機的内存占用,提高内存的使用效率。由于内存是共享的,所以多個虛拟機使用的内存減少了。這個特性,對于虛拟機使用相同鏡像和操作系統時,效果更加明顯。但是,事情總是有代價的,使用這個特性,都要增加内核開銷,用時間換空間。所以為了提高效率,可以将這個特性關閉。

  其好處是,在運行類似的客戶機操作系統時,通過 KSM,可以節約大量的内存,從而可以實現更多的内存超分,運行更多的虛機。

  (1)初始狀态:

  一圖看懂kvm虛拟化(虛拟化基本原理)(8)

  (2)合并後:

  一圖看懂kvm虛拟化(虛拟化基本原理)(9)

  (3)Guest 1 寫内存後:

  一圖看懂kvm虛拟化(虛拟化基本原理)(10)

  Intel 的 x86 CPU 通常使用4Kb内存頁,當是經過配置,也能夠使用巨頁(huge page): (4MB on x86_32, 2MB on x86_64 and x86_32 PAE)

  使用巨頁,KVM的虛拟機的頁表将使用更少的内存,并且将提高CPU的效率。最高情況下,可以提高20%的效率!

  大頁面和透明大頁面(THP)

  x86 CPU 通常會在 4kB 頁面中處理内存,但可以使用更大的 2MB 或 1GB 頁面,即 huge page(大頁面)。大頁面内存可以支持 KVM 客機部署,通過增加點擊轉換後備緩沖器(TLB)的 CPU 緩存以改善性能。

  kernel 功能将在 Red Hat Enterprise Linux 7 中默認啟用,大頁面可以大幅提高性能,尤其是對于較大的内存和内存密集型的負載。Red Hat Enterprise Linux 7 可以通過使用大頁面增加頁面大小,以便有效管理大量内存。

  過程 7.1. 為客機啟用 1GB 大頁面

  Red Hat Enterprise Linux 7.1 系統支持 2MB 或 1GB 大頁面,分配将在啟動或運行時進行。頁面大小均可以在運行時被釋放。例如,在啟動時分配 4 個 1GB 的大頁面和 1,024 個 2MB 的大頁面,請使用以下命令行:

  default_hugepagesz=1G hugepagesz=1G hugepages=4 hugepagesz=2M hugepages=1024

  此外,大頁面還可以在運行時分配。運行時分配允許系統管理員選擇從何種 NUMA 模式分配頁面。然而由于内存碎片的存在,運行時的頁面分配會比啟動時分配更容易造成分配失敗。以下運行時的分配示例顯示了從 node1 分配 4 個 1GB 的大頁面以及從 node3 分配 1,024 個 2MB 的大頁面:

  # echo 4 /sys/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages

  # echo 1024 /sys/devices/system/node/node3/hugepages/hugepages-2048kB/nr_hugepages

  接下來,将 2MB 和 1GB 的大頁面挂載到主機:

  # mkdir /dev/hugepages1G # mount -t hugetlbfs -o pagesize=1G none /dev/hugepages1G # mkdir /dev/hugepages2M # mount -t hugetlbfs -o pagesize=2M none /dev/hugepages2M

  默認1GB 大頁面現在對客機不可用。客戶機中要想使用1G大内存頁,需要如下配置:

  在以下示例中,客機 NUMA 節點 0-5(不包括 NUMA 節點 4)将會使用 1 GB 的大頁面,客機 NUMA 節點 4 将使用 2 MB 的大頁面,無論客機 NUMA 節點在主機的任何位置。

  memoryBackinghugepages/page size= unit= nodeset=0-3,5 page size= unit= nodeset=//hugepages/memoryBacking

  透明大頁面(THP,transparent huge page)将為性能自動優化系統設置。通過允許所有的空餘内存被用作緩存以提高性能。

  一旦 /sys/kernel/mm/transparent_hugepage/enabled 被設置為 always,透明大頁面将被默認使用。運行以下命令禁用透明大頁面:

  # echo never /sys/kernel/mm/transparent_hugepage/enabled

  透明大頁面支持不能阻止 hugetlbfs 的使用。但在 hugetlbfs 未使用時,KVM 将使用透明大頁面來替代常規的 4KB 頁面大小

  例子:

  使用方法,需要三部:

  mkdir /dev/hugepages mount -t hugetlbfs hugetlbfs /dev/hugepages #保留一些内存給巨頁 sysctl vm.nr_hugepages=2048 (使用 x86_64 系統時,這相當于從物理内存中保留了2048 x 2M = 4GB 的空間來給虛拟機使用) #給 kvm 傳遞參數 hugepages qemu-kvm - qemu-kvm -mem-path /dev/hugepages

  也可以在配置文件裡加入:

  memoryBacking

  hugepages/

  /memoryBacking

  驗證方式,當虛拟機正常啟動以後,在物理機裡查看:

  cat /proc/meminfo |grep -i hugepages

  ,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved