KVM 虛擬化基本原理

2020-08-26 閃念基因

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

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

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

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

1. 全虛擬化

2. 半虛擬化

3. 硬體輔助的虛擬化

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

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

異常 「捕獲(trap)-翻譯(handle)-模擬(emulate)」 過程:

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

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

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

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

而且兩種操作模式可以互相轉換。運行在 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):

要將客戶機內的線程調度到某個物理 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 中,虛機的物理內存即為 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)初始狀態:

(2)合併後:

(3)Guest 1 寫內存後:

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 的大頁面,請使用以下命令行:

&39;

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

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

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

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

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

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

<memoryBacking> <hugepages/> <page size=&34; unit=&34; nodeset=&34;/> <page size=&34; unit=&34; nodeset=&34;/> </hugepages> </memoryBacking>

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

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

保留一些內存給巨頁 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

相關焦點

  • 虛擬化--KVM
    一、虛擬化介紹什麼是虛擬化?這時候我們就可以使用虛擬化技術,用這三臺物理伺服器虛擬出60個系統然後分配成開發人員。KVM、vmware與虛擬化是什麼關係?kvm和vmwrae都可看做是一個可以實現虛擬化的軟體。
  • kvm虛擬化介紹
    二、虛擬化 ---KVM 1、虛擬化kvm發展: 2006 年 10 月由以色列的 Qumranet 組織開發的一種新的「虛擬機」方案,並將其貢獻給開源世界 2007 年 2 月於 Linux Kernel-2.6.20 中第一次包含了 KVM
  • Linux虛擬化-KVM-虛擬機安裝
    虛擬機可以使用真機物理硬體,性能高,需要改內核;全虛擬化:直接使用物理硬體,性能高;Vmware:支持仿真虛擬化;xen半虛擬化:REHL5自帶xen,安裝時需要安裝內核rpm -ivh kernel-xen-xxx.rpmkvm 全虛擬化:RHEL6自帶kvmShell是一個命令解釋器,它在作業系統的最外層,負責直接與用戶進行對話,把用戶的輸入解釋給作業系統
  • Kvm --01 虛擬化基礎概念
    虛擬化基礎概念01. 什麼是虛擬化?虛擬化,是指通過虛擬化技術將一臺計算機虛擬為多臺邏輯計算機。為什麼要用虛擬化?2.是x86架構且硬體支持虛擬化技術(如 intel VT 或 AMD-V)的Linux全虛擬化解決方案。3.它包含一個為處理器提供底層虛擬化,可加載的核心模塊kvm.ko(kvm-intel.ko或kvm-AMD.ko)。
  • 虛擬化技術之kvm基礎
    KVM的虛擬化需要硬體支持(如Inter VT技術或者AMD V技術),是基於硬體的完全虛擬化。而Xen早期則是基於軟體模擬的Para-Virtualization,新版本則是基於硬體支持的完全虛擬化。但Xen本身有自己的進程調度器,存儲管理模塊等,所以代碼較為龐大。
  • Kvm虛擬化存儲管理
    一、KVM 存儲虛擬化介紹KVM 的存儲虛擬化是通過存儲池(Storage Pool)和卷(Volume)來管理的。存儲池:kvm通過存儲池管理資源,在主機裡面申請的一塊存儲空間卷:在存儲池裡申請的資源Storage Pool 是宿主機上可以看到的一片存儲空間,可以是多種型;Volume 是在 Storage Pool 中劃分出的一塊空間,宿主機將 Volume 分配給
  • KVM虛擬化平臺
    本章將介紹部署虛擬化環境、創建虛擬機實例,以及虛擬機的基本管理。(如Intel-VT,AMD-V)實現高性能的虛擬化支持。       下圖簡單描繪了KVM虛擬化架構,在KVM環境中運行的每個虛擬化作業系統都將表現為單個獨立的系統進程。因此它可以很方便地與Linux系統中的安全模塊進行整合(SELinux),可以靈活地實現資源的管理及分配。
  • 雲計算底層技術之 KVM 初探
    它是作為 Linux kernel 中的一個內核模塊而存在,模塊名為 kvm.ko,也可以看作是一個進程,被內核調度並管理,從 Linux 2.6.20 版本開始被完全正式加入到內核的主幹開發和正式發布代碼中。 KVM 主要用於管理 CPU 和內存的虛擬化,IO 設備的虛擬化則是由 Qemu 來完成。為什麼會有這樣的分工,請繼續往下看。
  • kvm虛擬化知識梳理
    它的原理是以簡短的信息(元數據)表示空數據塊,而不是在在磁碟上佔用實際空間來存儲空數據塊。只有真實(非空)的數據塊會按原樣寫入磁碟。二、kvm常用命令virsh是kvm虛擬機常用的管理工具,常用的命令如下:1、安裝kvm環境sudo apt-get install qemu-kvm2、導入虛機配置(xml格式配置文件
  • kvm搭建
    技術(CPU要支持查看自己的CPU是否支持全虛擬化虛擬化技術且是64位的)Intel:cat /proc/cpuinfo | grep --color vmxAMD :cat /proc/5、開啟BIOS 虛擬化支持。
  • 基於Ubuntu16.04使用KVM實現Linux環境虛擬機化
    當前部署方案基於Ubuntu 16.04 Server,使用KVM實現Linux環境下的虛擬化解決方案。本人在虛擬化方面還是小白一枚,寫手冊主要是為了做筆記。老話說的好,好記性不如爛筆頭。話轉正題,之前接觸過Vmware虛擬化解決方案,圖形界面使用起來非常方便。這次使用使用Linux環境,純命令行環境使用起來略有不同,基本原理還是一致的。
  • 讀懂x86 架構 CPU 虛擬化,看這文就夠了|贈書
    作者 | 王柏生、謝廣軍導讀:本文摘自於王柏生、謝廣軍撰寫的《深度探索Linux系統虛擬化:原理與實現》一書,介紹了CPU虛擬化的基本概念,探討了x86架構在虛擬化時面臨的障礙,以及為支持CPU虛擬化,Intel在硬體層面實現的擴展VMX。
  • 讀懂 x86 架構 CPU 虛擬化,看這文就夠了 | 贈書
    作者 | 王柏生、謝廣軍導讀:本文摘自於王柏生、謝廣軍撰寫的《深度探索Linux系統虛擬化:原理與實現》一書,介紹了CPU虛擬化的基本概念,探討了x86架構在虛擬化時面臨的障礙,以及為支持CPU虛擬化,Intel在硬體層面實現的擴展VMX。
  • KVM實驗
    【1】、虛擬機分配4個G內存【2】、開啟虛擬化==============grep &34; /proc/cpuinfo //能夠過濾vmx就說明能夠支持虛擬化iptables -Fsetenforce 0systemctl stop firewalld
  • Kvm --05 密碼保護:Kvm管理之WebVirtMgr
    前言當Kvm宿主機越來越多,需要對宿主機的狀態進行調控,決定採用WebVirtMgr作為Kvm虛擬化的web管理工具,圖形化的WEB,讓人能更方便的查看Kvm宿主機的情況和操作。部署1)、安裝相關依賴首先要安裝Kvm虛擬化環境,這裡我將WebVirtMgr伺服器和Kvm伺服器放在同一臺機器上部署的,即單機部署。
  • Centos7安裝KVM虛擬機教程
    KVM --- 全稱是基於內核的虛擬機(Kernel-based Virtual Machine)是一個開源軟體,基於內核的虛擬化技術,實際是嵌入系統的一個虛擬化模塊,通過優化內核來使用虛擬技術,該內核模塊使得 Linux 變成了一個Hypervisor,虛擬機使用 Linux 自身的調度器進行管理。
  • 詳解x86架構CPU虛擬化
    導讀:本文摘自王柏生、謝廣軍撰寫的《深度探索Linux系統虛擬化:原理與實現》一書,介紹了CPU虛擬化的基本概念,探討了x86架構在虛擬化時面臨的障礙,以及為支持CPU虛擬化,Intel在硬體層面實現的擴展VMX。同時,介紹了在VMX擴展支持下,虛擬CPU從Host模式到Guest模式,再回到Host模式的完整生命周期。
  • 紅帽企業版 6.0 KVM虛機實戰攻略(圖)
    這個內核模塊導出了一個名為 /dev/kvm 的設備,它可以啟用內核的客戶模式(除了傳統的內核模式和用戶模式)。有了 /dev/kvm 設備,VM 使自己的地址空間獨立於內核或運行著的任何其他 VM 的地址空間。設備樹(/dev)中的設備對於所有用戶空間進程來說都是通用的。但是每個打開 /dev/kvm 的進程看到的是不同的映射(為了支持 VM 間的隔離)。
  • 淺析openstack虛擬化技術
    Hypervisor是所有虛擬化技術的核心。非中斷地支持多工作負載遷移的能力是Hypervisor的基本功能。當伺服器啟動並執行Hypervisor時,它會給每一臺虛擬機分配適量的內存、CPU、網絡和磁碟,並加載所有虛擬機的客戶作業系統。
  • OpenStack | libvirt基本原理及應用
    在部署OpenStack的過程中《OpenStack Installation Guide | Debug》,在Nova的配置文件中有一個virt_type配置項,可以配置成kvm也可以是qemu,這裡的kvm其實指的也是qemu-kvm。