KVM 核心功能:CPU 虛擬化
阿新 • • 發佈:2020-07-26
1 vCPU 簡介
CPU 負責計算機程式指令的執行。QEMU-KVM 提供對虛擬機器 CPU 的模擬,對於虛擬機器來說,其擁有的 CPU 是真實的, 和物理 CPU 沒有區別。 實際上,虛擬機器在 host 上表現為一個 qemu 程序,而虛擬機器的 vCPU (從 host 上看是 vCPU) 則是該程序下的一個執行緒。 使用 qemu-kvm 建立一個虛擬機器:[root@lianhua qemu-kvm]# /usr/libexec/qemu-kvm -smp 2 -m 1G lianhua.qcow -monitor stdio QEMU 2.6.0 monitor - type '可以看到,虛擬機器的 CPU 0 和 1 分別對應執行緒 1019305 和 1019307。並且,它們都是程序 1019294 的子執行緒,而程序 1019294 則是通過 qemu-kvm 建立的虛擬機器程序。 同時,也可看到虛擬機器的子程序數要大於 CPU 數目,因為虛擬機器需要一些單獨的程序來處理專門的任務,比如 I/O 任務等。help' for more information (qemu) VNC server running on '::1;5900' (qemu) info cpus * CPU #0: pc=0x000000003fefa56a thread_id=1019305 CPU #1: pc=0x00000000000fd374 (halted) thread_id=1019307 (qemu) info cpus * CPU #0: pc=0x000000003ff0d4ea (halted) thread_id=1019305 CPU #1: pc=0x00000000000fd374 (halted) thread_id=1019307 [root@lianhua home]# ps-eLf | grep qemu root 1019294 1014044 1019294 0 5 12:53 pts/0 00:00:00 /usr/libexec/qemu-kvm -smp 2 -m 1G lianhua.qcow -monitor stdio root 1019294 1014044 1019300 0 5 12:53 pts/0 00:00:00 /usr/libexec/qemu-kvm -smp 2 -m 1G lianhua.qcow -monitor stdio root 1019294 1014044 1019305 6 5 12:53 pts/0 00:00:12 /usr/libexec/qemu-kvm -smp 2-m 1G lianhua.qcow -monitor stdio root 1019294 1014044 1019307 0 5 12:53 pts/0 00:00:00 /usr/libexec/qemu-kvm -smp 2 -m 1G lianhua.qcow -monitor stdio root 1019294 1014044 1019309 0 5 12:53 pts/0 00:00:00 /usr/libexec/qemu-kvm -smp 2 -m 1G lianhua.qcow -monitor stdio
2 vCPU 配置
這裡 vCPU 的配置都是使用硬體輔助的虛擬化技術,首先要保證核心已載入 kvm 模組。當然 qemu 也得執行起來。 配置 vCPU 有兩種方式,第一種直接使用 qemu-kvm 命令列指定 vCPU 資訊,第二種通過 virsh XML 配置 vCPU 資訊。兩種方式如下所示: 1)vCPU 配置如上例所述,可通過 smp 指定 cpu 的資訊來配置:[root@lianhua qemu-kvm]# /usr/libexec/qemu-kvm -smp 2 -m 1G lianhua.qcow -monitor stdio
該配置會建立一個有兩個 vCPU 的虛擬機器,且計算機架構為 SMP 架構(計算機架構主要有 SMP 和 NUMA,參考這裡瞭解更多)。
[root@lianhua qemu-kvm]# /usr/libexec/qemu-kvm -smp 3,sockets=3,cores=1,threads=1 -m 1G lianhua.qcow -monitor stdio該配置會建立一個具有 3 個 vCPU 的虛擬機器。對於虛擬機器來說,它有 3 個 socket,每個 socket 有 1 個核,且核上未開啟超執行緒,threads 為 1。 2) 通過在 virsh 的 XML 檔案中配置 vCPU 資訊:
<vcpu placement='static'>6</vcpu> <cputune> <shares>6144</shares> <vcpupin vcpu='0' cpuset='9'/> <vcpupin vcpu='1' cpuset='37'/> <vcpupin vcpu='2' cpuset='11'/> <vcpupin vcpu='3' cpuset='39'/> <vcpupin vcpu='4' cpuset='34'/> <vcpupin vcpu='5' cpuset='6'/> <emulatorpin cpuset='6,9,11,34,37,39'/> </cputune>如上所示,虛擬機器配有 6 個 vCPU,並且在 cputune 標籤中設定了 vCPU 和 host 上物理 CPU 的對映關係,即 0 - 9,1 - 37... 在 XML 檔案的 cpu mode 標籤中可詳細定義 cpu 的配置型別:
<cpu mode='host-model'> <model fallback='allow'/> <topology sockets='3' cores='1' threads='2'/> <numa> <cell id='0' cpus='0-5' memory='33554432' unit='KiB' memAccess='shared'/> </numa> </cpu>如上所示,cpu mode 為 host-model,即根據 host 的 cpu 特性為 domain 選擇最接近標準的 CPU 型號(看這裡瞭解 cpu mode 標籤)。同時,topology 標籤定義了 cpu 的 sockets/cores 和 threads 情況,這裡也配置了 numa node,指定 cpu 配置在 numa0 上,cpu 使用的記憶體為33554432和使用的方式 shared。 cpu 配置好之後登陸到 domain 虛擬機器中檢視 cpu 的配置是否生效:
$ cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 61 model name : Intel Core Processor (Broadwell) stepping : 2 microcode : 0x1 cpu MHz : 2394.454 cache size : 4096 KB physical id : 0 siblings : 2 core id : 0 cpu cores : 1 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit srbds bogomips : 4788.90 clflush size : 64 cache_alignment : 64 address sizes : 46 bits physical, 48 bits virtual power management: ... $ /bin/bash cpu.sh The physical cpu is: 3 core number in a physical cpu: 1 logical cpu number in a physical cpu: 2 The hyper threading is enabled, each core has 2 threads logical cpu number in host: 6cpu 配置生效,且 cpu model name 匹配為 Broadwell。
3 vCPU 特性
vCPU 有幾大特性,在部署虛機時合理利用這些特效能夠使得部署更靈活,同時實現效率最大化。3.1 vCPU overcommit
在實際虛擬機器使用時,不是每個虛擬機器都在同時工作,這樣就會造成 host 上 cpu 資源的浪費。通過 vCPU 的 overcommit 機制可以有效避免這種資源浪費。 vCPU overcommit,即虛擬機器上 vCPU 的個數可以大於 host 上 logical CPU 數目。3.2 vCPU 熱插拔
如果在生產環境上虛擬機器的 cpu 資源不夠了,那麼可以通過 vCPU 的熱插拔特性動態的為虛擬機器新增 vCPU:[root@lianhua qemu-kvm]# /usr/libexec/qemu-kvm -smp 3,maxcpus=5,sockets=3,cores=1,threads=1 -m 1G lianhua.qcow -monitor stdio QEMU 2.6.0 monitor - type 'help' for more information (qemu) VNC server running on '::1;5900' (qemu) info cpus * CPU #0: pc=0x000000003fefa56a thread_id=356200 CPU #1: pc=0x00000000000fd374 (halted) thread_id=356201 CPU #2: pc=0x00000000000fd374 (halted) thread_id=356203 (qemu) cpu-add 3 (qemu) info cpus * CPU #0: pc=0x00000000000fc373 (halted) thread_id=356200 CPU #1: pc=0x00000000000fd374 (halted) thread_id=356201 CPU #2: pc=0x00000000000fd374 (halted) thread_id=356203 CPU #3: pc=0x00000000fffffff0 thread_id=357997如上所示,在虛擬機器執行時通過 cpu-add 將 3 號 cpu 載入到虛機中。注意,在進行熱插拔時首先要保證有足夠的 cpu 資源可供熱插拔(maxcpus > smp 指定的 logical cpu 數),如果沒有足夠資源則會顯示無法進行熱插拔。
3.3 vCPU 親和性
部署虛擬機器時可配置 vCPU 的親和性,即將 vCPU 和 host 上 logical CPU 繫結在一起,使得 vCPU 執行在固定的 logical CPU 上。 vCPU 親和性的配置在上節已經介紹了,這裡不再贅述。在 host 上檢視繫結的 CPU 使用情況: 1) 配置 vCPU 親和性:<vcpu placement='static'>6</vcpu> <cputune> <shares>6144</shares> <vcpupin vcpu='0' cpuset='9'/> <vcpupin vcpu='1' cpuset='37'/> <vcpupin vcpu='2' cpuset='11'/> <vcpupin vcpu='3' cpuset='39'/> <vcpupin vcpu='4' cpuset='34'/> <vcpupin vcpu='5' cpuset='6'/> <emulatorpin cpuset='6,9,11,34,37,39'/> </cputune>vCPU 分別繫結在 host 上 logical cpu 的 6,9,11,34,37,39 上。 2) 檢視 host 上對應 logical cpu 的使用情況:
[root@lianhua home]# ps -eLo ruser,pid,ppid,lwp,psr,args | grep qemu | grep -v grep ... [root@lianhua home]# ps -eLo ruser,pid,ppid,lwp,psr,args | awk '{if($5==37) print $0}' root 193 2 193 37 [watchdog/37] root 194 2 194 37 [migration/37] root 195 2 195 37 [ksoftirqd/37] root 196 2 196 37 [kworker/37:0] root 197 2 197 37 [kworker/37:0H] root 145760 2 145760 37 [kworker/37:1] qemu 879955 1 880096 37 /usr/libexec/qemu-kvm -name guest=lianhua ...第一行命令輸出 qemu 建立的程序和執行緒情況。由於輸出資訊太多,這裡直接省略了。 第二行輸出指定 logical cpu 上執行的執行緒,以 37 號 cpu 為例,它上面運行了系統執行緒 watchdog,migration 等等,同時也運行了一個虛擬機器的執行緒(該執行緒是 vCPU 執行緒,可在 qemu monitor 裡使用 info cpus 檢視執行緒和 vCPU 的對映關係),且該執行緒的程序是 879955,該程序即使建立的虛擬機器的 qemu 程序。 最後,檢視 host 上其它 logical cpu 是否有排程到 vCPU 執行緒:
[root@lianhua home]# ps -eLo ruser,pid,ppid,lwp,psr,args | awk '{if($5==40) print $0}' root 208 2 208 40 [watchdog/40] root 209 2 209 40 [migration/40] root 210 2 210 40 [ksoftirqd/40] root 212 2 212 40 [kworker/40:0H] root 390900 2 390900 40 [kworker/40:0] root 673792 2 673792 40 [kworker/40:1] root 674097 2 674097 40 [kworker/40:1H] [root@lianhua home]# ps -eLo ruser,pid,ppid,lwp,psr,args | awk '{if($5==41) print $0}' root 213 2 213 41 [watchdog/41] root 214 2 214 41 [migration/41] root 215 2 215 41 [ksoftirqd/41] root 216 2 216 41 [kworker/41:0] root 217 2 217 41 [kworker/41:0H]沒有排程到 vCPU 執行緒,說明虛擬機器裡 vCPU 成功繫結到 logical cpu。