qemu-kvm虛擬化——CPU 基於WMWare Workstation 搭建 KVM 環境
前言
拋開眾多令人花眼的虛擬化技術不談,一個實實在在計算機系統都包含什麼?處理器(CPU)、記憶體(Memory)、儲存(Storage)、網路(Network)、顯示(Display)等。對於虛擬機器也是如此。本文介紹就是針對CPU的虛擬化技術。在正式開始之前,先想像下面這個問題? 虛擬化技術中最重要的一個環節在哪,為什麼 ?
虛擬化技術的核心——CPU虛擬化
CPU是虛擬化技術的核心? 鬼扯,早期QEMU使用純程式碼模擬硬體不是也是先虛擬化了嗎?不僅如此,還做到跨平臺呢(因為QEMU是C寫的)。這個一點沒錯,但是QEMU技術下的虛擬機器執行速度太慢,所有針對硬體的訪問都要QEMU這Hypervisor進行轉譯,尤其是針對CPU也要轉譯。對於現今雲端計算時代需要的虛擬化技術而言,在效能上實在達不到標準。影響QEMU虛擬化效能最關鍵的一塊就在CPU虛擬化上(其他還包括記憶體、對效能要求高硬體虛擬化上),可以說這是QEMU的瓶頸所在。
現在正式開始回答,為啥CPU是虛擬化的核心。如下圖
實現虛擬化的重要一步就在於,虛擬化層必須能夠截獲計算元件對物理資源的直接訪問,並將其重新定向到虛擬資源池中。區分有無CPU虛擬化的關鍵是,這個“截獲並重定向”的動作是純軟體實現,還是有硬體協助。對於傳統QEMU,屬於純軟體實現,對於KVM則是有硬體協助。
需要說明的是,硬體協助虛擬化技術是一套解決方案。完整的情況需要CPU、主機板晶片組、BIOS和軟體的支援。例如Hypervisor軟體本身 或者 某些OS本身。即使只是CPU支援虛擬化技術,在配合Hypervisor軟體的情況下,也會比完全不支援虛擬化技術的系統有更好的效能。
Intel虛擬化技術
鑑於虛擬化的巨大需求和硬體虛擬化產品的廣闊前景,Intel自2005年末,便開始在其CPU產品線中推廣應用Intel Virtualization Technology(IntelVT)虛擬化技術。下圖是Intel虛擬化技術進化圖
主要分為3類:
第一類是處理器相關的,稱為VT-x,是實現處理器虛擬化的硬體擴充套件,這也是硬體虛擬化的基礎;
第二類是晶片組相關的,成為VT-d,是從晶片組的層面為虛擬化提供必要支援,通過它,可以實現諸如直接分配物理裝置給客戶機的功能;
第三類是輸入輸出裝置相關的,主要目的是通過定義新的輸入輸出協議,使新一代的輸入輸出裝置可以更好地支援虛擬化環境下的工作,比如Intel網絡卡自有的VMDq技術和PCI組織定義的單根裝置虛擬化協議(SR-IOV)。
QEMU和QEMU-KVM
上面說過QEMU是純軟體的虛擬化,由於沒有CPU協助虛擬化,因此效能不高。KVM誕生伊始就需要硬體虛擬化支援,但是KVM模組本身僅僅對CPU、記憶體、部分對效能要求高的硬體做了虛擬化,其他的外設並沒有進行虛擬化。而這部分工作恰恰是QEMU的強項。於是兩者結合,有了QEMU-KVM分支。但是在2012年底,QEMU的1.3.0版本釋出時,qemu-kvm中針對KVM的修改已經完全加入到普通的QEMU程式碼庫中了,從此之後可以完全使用純QEMU來與KVM配合使用(命令列新增-enable-kvm引數),而不是需要專門使用qemu-kvm程式碼庫了。QEMU與KVM的結合可以說是各取所需,QEMU利用KVM實現硬體加速,KVM利用QEMU實現虛擬機器執行時其他依賴的虛擬裝置。不僅如此QEMU還負責虛擬機器的配置和建立,虛擬機器執行時的使用者操作環境和互動,以及一些針對虛擬機器的特殊技術(諸如動態遷移)。
SMP技術
在處理器技術中,多處理器、多核、超執行緒等技術得到了廣泛的應用。無論是在企業級和科研應用的伺服器領域中,還是個人消費者使用的桌上型電腦、筆記本甚至智慧手機上,隨處可見SMP(Symmetric Multi-Processor,對稱多處理器)系統。在SMP系統中,多個程式(程序)可以做到真正的並行執行,而且單個程序的多個執行緒也可以得到並行執行,這極大地提高了計算機系統並行處理能力和整體效能。
在硬體方面,早期的計算機系統更多的是在一個主機板上擁有多個物理的CPU插槽來實現SMP系統,後來隨著多核技術、超執行緒(Hyper-Threading)技術的出現,SMP系統就會使用多處理器、多核、超執行緒等技術中的一個或多個。多數的現代CPU都支援多核 或 超執行緒技術。要想CPU支援了超執行緒(HT)技術,還需要在BIOS中開啟它的設定開關。在BIOS中,超執行緒的設定可能會在“Advanced→CPU Configuration”下設定,通常標識為“Hyper-Threading”。另外,由於AMD走mult-core的路線,可能沒有Hyper-Threading的產品或者支援不完善。而Intel支援mult-core和hyper-threading一起使用。
在作業系統軟體方面,主流OS都提供了對SMP系統的支援。
如下指令碼可用於檢查當前系統中CPU數量,多核及超執行緒使用情況
#!/bin/bash #this script only works in a Linux system which has one or more identical physical CPU(s). #author: Jay http://smilejay.com/ echo -n "logical CPU number in total: " #邏輯CPU個數 cat /proc/cpuinfo | grep "processor" | wc -l echo -n "physical CPU number in total: " #物理CPU個數 cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l echo -n "core number in a physical CPU: " #每個物理CPU上Core的個數(未計入超執行緒) core_per_phy_cpu=$(cat /proc/cpuinfo | grep "core id" | sort | uniq | wc -l) echo $core_per_phy_cpu echo -n "logical CPU number in a physical CPU: " #每個物理CPU中邏輯CPU(可能是core, threads或both)的個數 logical_cpu_per_phy_cpu=$(cat /proc/cpuinfo | grep "siblings" | sort | uniq | awk -F: '{print $2}') echo $logical_cpu_per_phy_cpu #是否開啟有超執行緒? #如果在同一個物理CPU上兩個邏輯CPU具有相同的”core id”,那麼超執行緒是開啟的。 #此處根據前面計算的core_per_phy_cpu和logical_core_per_phy_cpu的比較來檢視超執行緒。 #當然,cat /proc/cpuinfo | grep ht 也可以檢查超執行緒。 if [ $logical_cpu_per_phy_cpu -gt $core_per_phy_cpu ]; then echo "Hyper threading is enabled." elif [ $logical_cpu_per_phy_cpu -eq $core_per_phy_cpu ]; then echo "Hyper threading is NOT enabled." else echo "Error. There's something wrong." fiView Code
qemu-kvm在SMP下的體現形式
多個Guest就是Host中的多個QEMU程序,而一個Guest的多個vCPU就是一個QEMU程序中的多個執行緒。和普通作業系統一樣,在客戶機系統中,同樣分別執行著客戶機的核心和客戶機的使用者空間應用程式。對其vCPU這個執行緒,在傳統執行模式(Kernel Mode、User Mode)基礎上又增加了一種模式——Guest Mode。三種模式關係圖如下
配置SMP的引數
我的實驗環境上qemu-kvm時使用yum從遠處軟體倉庫拉去rpm包線上安裝得,線上安裝的版本預設開啟了對KVM支援。如果沒有開啟KVM支援,在qemu-kvm啟動時加上-enable-kvm引數。
-smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]
- n用於設定Guest中使用的邏輯CPU數量(預設值是1)。
- maxcpus用於設定Guest中最大可能被使用的CPU數量,包括啟動時處於離線(offline)狀態的CPU數量(可用於熱插拔hot-plug加入CPU,但不能超過maxcpus這個上限)。
- cores用於設定每個CPU socket上的core數量(預設值是1)。
- threads用於設定每個CPU core上的執行緒數(預設值是1)。
- sockets用於設定Guest中看到的總的CPU socket數量。
Guest中檢視vCPU資訊
啟動Guest,在Guest中檢視cpu情況
由於我已事先安裝好Guest(如何安裝參考:基於WMWare Workstation 搭建 KVM 環境)。啟動Guest
/usr/libexec/qemu-kvm -vnc 0.0.0.0:1 centos1708.img
VNC viewer遠端連線到Guest
Ctrl+Alt+2切換到qemu monitor檢視cpu資訊,以及qemu對kvm支援情況
可以看到有1個vCPU,執行緒IP是2884。
在Host中檢視這個執行緒
[[email protected] ~]# ps -efL | grep qemu UID PID PPID LWP C NLWP STIME TTY TIME CMD root 2880 1240 2880 1 3 22:30 pts/0 00:00:04 /usr/libexec/qemu-kvm -vnc 0.0.0.0:1 centos1708.img root 2880 1240 2884 11 3 22:30 pts/0 00:00:30 /usr/libexec/qemu-kvm -vnc 0.0.0.0:1 centos1708.img root 2880 1240 2886 0 3 22:30 pts/0 00:00:00 /usr/libexec/qemu-kvm -vnc 0.0.0.0:1 centos1708.img root 2974 2948 2974 0 1 22:34 pts/1 00:00:00 grep --color=auto qemuView Code
PID 2880這個程序是客戶機程序,它產生執行緒LWP 2884 作為Guest 的vCPU執行在Host中
執行緒關係樹如下
給Guest啟動8個vCPU
由於我的Host最多隻有4個邏輯CPU,因此無法啟動Guest(會一直卡在Guest啟動介面)
這相當於2個sockets,每個socket 有2個cores,每個cores有1個thread。
我物理CPU使用的是i7 6700K,4核心2執行緒,相當於有8個CPU。更改Host設定
再次啟動Guest
/usr/libexec/qemu-kvm -smp 8,sockets=2,cores=2,threads=2 -vnc 0.0.0.0:1 centos1708.img
啟動成功後檢視cpu資訊
Host檢視vCPU對性的執行緒(LWP 1323~1330)
設定Guest CPU支援熱插拔
如果要對Guest進行CPU的熱插拔(hot-plug),則需要在啟動Guest的qemu-kvm命令列引數中加上“maxcpus=num”這個選項。以前qemu-kvm中CPU的hot-plug功能有一些bug,處於不可用狀態,現在不清楚啥情況。
CPU過載使用
KVM允許客戶機過載使用(over-commit)物理資源,即允許為客戶機分配的CPU和記憶體數量多於物理上實際存在的資源。
物理資源的過載使用能帶來資源充分利用方面的好處。試想在一臺強大的硬體伺服器中執行Web伺服器、圖片儲存伺服器、後臺資料統計伺服器等作為虛擬客戶機,但是它們不會在同一時刻都負載很高,如Web伺服器和圖片伺服器在白天工作時間負載較重,而後臺數據統計伺服器主要在晚上工作,所以對物理資源進行合理的過載使用,向這幾個客戶機分配的系統資源總數多於實際擁有的物理資源,就可能在白天和夜晚都充分利用物理硬體資源,而且由於幾個客戶機不會同時對物理資源造成很大的壓力,它們各自的服務質量(QoS)也能得到保障。
CPU的過載使用,是讓一個或多個客戶機使用vCPU的總數量超過實際擁有的物理CPU數量。QEMU會啟動更多的執行緒來為客戶機提供服務,這些執行緒也是被Linux核心排程執行在物理CPU硬體上。
關於CPU的過載使用,推薦的做法是對多個單CPU的客戶機使用over-commit,比如,在擁有4個邏輯CPU的宿主機中,同時執行多於4個(如8個、16個)客戶機,其中每個客戶機都分配一個vCPU。這時,如果每個宿主機的負載不是很大,宿主機Linux對每個客戶機的排程是非常有效的,這樣的過載使用並不會帶來客戶機的效能損失。
關於CPU的過載使用,最不推薦的做法是讓某一個客戶機的vCPU數量超過物理系統上存在的CPU數量。比如,在擁有4個邏輯CPU的宿主機中,同時執行一個或多個客戶機,其中每個客戶機的VCPU數量多於4個(如16個)。這樣的使用方法會帶來比較明顯的效能下降,其效能反而不如為客戶機分配2個(或4個)VCPU的情況,而且如果客戶機中負載過重,可能會讓整個系統執行不穩定。不過,在並非100%滿負載的情況下,一個(或多個)有4個vCPU的客戶機執行在擁有4個邏輯CPU的宿主機中並不會帶來明顯的效能損失。
總的來說,KVM允許CPU的過載使用,但是並不推薦在實際的生產環境(特別是負載較重的環境)中過載使用CPU。在生產環境中過載使用CPU,有必要在部署前進行嚴格的效能和穩定性測試。