KVM虛擬機cpu資源限制和vcpu親緣性綁定


前言

KVM中添加的實例存在資源分布不均的情況,這樣如果有消耗資源的實例會影響到其他實例的服務正常運行,所以給kvm做資源限制是很有必要的,下面記錄一下在centos7中KVM環境下使用cgroup限制vm實例資源的過程。

安裝cgroup

[root@yufu ~]# yum install libcgroup libcgroup-devel libcgroup-tools-y

啟動cgroup服務

[root@yufu ~]# systemctl start cgconfig

[root@yufu ~]# systemctl enable cgconfig

默認安裝后目錄文件並沒有在/cgroup 目錄下,而是在/sys/fs/cgoup 目錄下。可以說使用find / -type d -name cgroup查找目錄。

限制cpu資源

查看當前宿主機上有哪些實例並查看實例的進行號。
使用ps -ef 指令可以看到每個vm實例的進程號,一個示列在宿主機中就是一個進程。【通過進程名稱查看進程號:pidof qemu-kvm

下面使用進程為 2106 的這個vm實例進測試:

進程號 2106 對應的實例是vm5,內存4G,cpu為2核心

在實例vm4中寫一個消耗cpu的腳本測試,在宿主機中查看該進程消耗的cpu資源

#! /bin/bash

x=0
while [ True ];do
    x=$x+1
done;

宿主機執行 top -p 2106查看進程狀態

Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  4.2 us,  0.0 sy,  0.0 ni, 95.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 98821584 total, 95922736 free,  2029444 used,   869412 buff/cache
KiB Swap:  8388604 total,  8388604 free,        0 used. 96262080 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                               
 2106 qemu      20   0 4549900 566812   9336 S 100.0  0.6  11:47.26 qemu-kvm  

可以看到cpu已經使用了100%

下面用cgroup控制這個進程的cpu資源

要對vm實例做資源限制,在cgroup目錄下創建一個資源組vm5,然后在這個資源組中定義資源分配(可以一個vm定義一個資源組,容易管理,也可以給所有vm定義一個資源組)

  • 創建資源組
[root@yufu ~]# mkdir /sys/fs/cgroup/cpu/vm5

#資源組創建以后會有很多控制文件
[root@yufu ~]# ls /sys/fs/cgroup/cpu/vm5
cgroup.clone_children  cpuacct.stat          cpu.cfs_period_us  cpu.rt_runtime_us  notify_on_release
cgroup.event_control   cpuacct.usage         cpu.cfs_quota_us   cpu.shares         tasks
cgroup.procs           cpuacct.usage_percpu  cpu.rt_period_us   cpu.stat

查看當前進程

[root@yufu ~]# pidof qemu-kvm
2106 1642
  • 添加控制進程

將要限制的進程號加入到/sys/fs/cgroup/cpu/vm5/cgroup.procs

[root@yufu ~]# echo 2106 > /sys/fs/cgroup/cpu/vm5/cgroup.procs
  • 限制cpu資源使用

cpu.cfs_period_us和cpu.cfs_quota_us來限制該組中的所有進程在單位時間里可以使用的cpu時間。這里的cfs是完全公平調度器的縮寫。cpu.cfs_period_us就是時間周期(微秒),默認為100000,即百毫秒。cpu.cfs_quota_us就是在這期間內可使用的cpu時間(微秒),默認-1,即無限制。

  • 查看默認值
[root@yufu ~]# cat  /sys/fs/cgroup/cpu/vm5/cpu.cfs_period_us 
100000
[root@yufu ~]# cat  /sys/fs/cgroup/cpu/vm5/cpu.cfs_quota_us 
-1
  • 對上面的兩個值做調整
[root@yufu ~]# echo 80000 > /sys/fs/cgroup/cpu/vm5/cpu.cfs_period_us 
[root@yufu ~]# echo 40000 > /sys/fs/cgroup/cpu/vm5/cpu.cfs_quota_us
  • 再執行腳本測試
    在vm5上執行測試腳本,宿主機查看top
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.1 us,  0.0 sy,  0.0 ni, 97.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 98821584 total, 95904496 free,  2047560 used,   869528 buff/cache
KiB Swap:  8388604 total,  8388604 free,        0 used. 96243984 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                               
 2106 qemu      20   0 4549900 567324   9336 S  50.0  0.6  12:02.15 qemu-kvm                                              

對比發現:長時間高負載下,限制了cpu資源的vm實例負載比沒有做限制的實例負載要小。

同樣,其他虛擬機實例按照上面同樣的方式也可以對cpu資源進行限制

撤銷資源限制

要撤銷某個資源的限制,將該資源組中的tasks中的pid寫到根 cgroup 的 tasks 文件即可,因為每個進程都屬於且只屬於一個 cgroup,加入到新的 cgroup 后,原有關系也就解除了。要刪除一個 cgroup,可以用 rmdir 刪除相應目錄。不過在刪除前,必須先讓其中的進程全部退出,對應子系統的資源都已經釋放,否則是無法刪除的。

  • 撤銷資源
[root@yufu vm5]# echo 2106 > /sys/fs/cgroup/cpu/tasks 
[root@yufu vm5]# echo 2111 > /sys/fs/cgroup/cpu/tasks 
[root@yufu vm5]# echo 2112 > /sys/fs/cgroup/cpu/tasks
  • 查看原來vm5實例中的pid已經被清空了
[root@yufu vm5]# cat tasks 

再執行腳本測試,cpu又是100%

Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  4.1 us,  0.0 sy,  0.0 ni, 95.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 98821584 total, 95905520 free,  2046364 used,   869704 buff/cache
KiB Swap:  8388604 total,  8388604 free,        0 used. 96245000 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                               
 2106 qemu      20   0 4549900 567324   9336 S 100.0  0.6  14:29.49 qemu-kvm 

KVM中虛擬機的cpu親緣性綁定

默認情況下,kvm虛擬機實例並沒有對vcpu做任何限制,當一個實例負載過高時,vcpu會在宿主機的cpu上來回切換,頻繁的切換容易造成資源浪費,將vcpu與宿主機cpu對應綁定,能夠有效提升cpu工作效率。

也可以將一個進程綁定在一個cpu上,使用taskset指令

cpu綁定方式

上面提到過,一個vm實例在宿主機中其實就是一個進程,綁定方式有兩種:

taskset指令綁定進程cpu

使用taskset綁定是以vm實例上的所有vcpu為單位,與宿主機上的cpu進行綁定。比如:將vm4實例綁定在第4號cpu上,那么vm4實例中有4個vcpu,這4個vcpu都工作在了宿主機的第4號cpu上了。這種綁定方式粒度比較大

vcpupin子命令綁定

virsh vcpupin 子命令是KVM自帶的指令工具,它可以把vm實例的每個vcpu與宿主機的cpu對應綁定,這種綁定方式粒度更小。

下面以vm4實例為例,查看其cpu運行情況和對其進程綁定

  • 查看vm4當前cpu綁定情況:
[root@yufu ~]# virsh vcpupin vm4
VCPU: CPU Affinity
----------------------------------
   0: 0-23      
   1: 0-23
 #默認2個vcpu沒有進行綁定,可以在0-24號cpu上切換
  • 查看vcpu使用的時間
[root@yufu ~]# virsh vcpuinfo vm4
VCPU:           0
CPU:            10   #運行在10號cpu上
State:          running
CPU time:       14.2s
CPU Affinity:   yyyyyyyyyyyyyyyyyyyyyyyy

VCPU:           1
CPU:            8      #運行在8號cpu上
State:          running
CPU time:       6.8s
CPU Affinity:   yyyyyyyyyyyyyyyyyyyyyyyy

  • 將vm4的兩個vcpu綁定在宿主機的第4號和第6號cpu上

cpu編號從0開始計數

[root@yufu ~]# virsh vcpupin vm4 0 3

[root@yufu ~]# virsh vcpupin vm4 1 5
  • 再看vcpu狀態
[root@yufu ~]# virsh vcpuinfo vm4
VCPU:           0
CPU:            3
State:          running
CPU time:       14.5s
CPU Affinity:   ---y--------------------

VCPU:           1
CPU:            5
State:          running
CPU time:       7.3s
CPU Affinity:   -----y------------------

[root@yufu ~]# virsh vcpupin vm4
VCPU: CPU Affinity
----------------------------------
   0: 3
   1: 5

可以看到cpu已經綁定了,此時在vm4上做壓力測試並在宿主機上看看cpu運行情況
上面使用指令綁定的方式只在當前系統環境有效,實例重啟后就會失效,要永久生效需要在xml配置文件中定義

接着再把vm4的cpu使用資源做cgroup限制就就可以了:

  • 執行ps -ef獲得vm4的pid為1636

  • 創建cgroup資源組vm4

[root@yufu ~]# mkdir /sys/fs/cgroup/cpu/vm4
  • 將vm4的pid寫進cgroup.procs文件
[root@yufu ~]# cd /sys/fs/cgroup/cpu/vm4/

[root@yufu vm4]# echo 1636 > cgroup.procs
#當把進程pid加到 cgroup.procs后,系統會自動將該進程和進程下的線程加入到tasks文件中

[root@yufu vm4]# echo 80000 > cpu.cfs_period_us 
[root@yufu vm4]# echo 40000 > cpu.cfs_quota_us
  • 運行vm4消耗cpu腳本,查看宿主機進程狀態和cpu

可以看到htop中,兩個線程的cpu使用率一直在50%左右,且負載一直在第4個第6號cpu運行(這里就不上圖了)

將cpu綁定信息寫到xml配置文件

上面提到過,在命令行做的設置后,vm實例重啟后,綁定信息就會失效,要想永久生效,需要將cpu的綁定信息寫到該實例的xml配置文件中。

  • 在配置xml配置文件中添加綁定信息

停止vm4實例,編輯其xml文件

<domain type='kvm'>
  <name>vm4</name>
  <uuid>a140824a-800b-42bf-ae26-60e9ec6aa50f</uuid>
  <memory unit='KiB'>4097152</memory>
  <currentMemory unit='KiB'>4097152</currentMemory>
  <vcpu placement='static'>2</vcpu>
  #以下為添加內容
  <cputune>    
  <vcpupin vcpu='0' cpuset='3'/>
  <vcpupin vcpu='1' cpuset='5'/>
  </cputune>
  • 修改配置文件后要重載xml文件
[root@yufu qemu]# virsh define /etc/libvirt/qemu/vm4.xml 

再啟動實例查看vcpu綁定信息

[root@yufu qemu]# virsh vcpuinfo vm4
VCPU:           0
CPU:            3
State:          running
CPU time:       14.2s
CPU Affinity:   ---y--------------------

VCPU:           1
CPU:            5
State:          running
CPU time:       4.3s
CPU Affinity:   -----y------------------

[root@yufu qemu]# virsh vcpupin vm4
VCPU: CPU Affinity
----------------------------------
   0: 3
   1: 5

關於kvm虛擬機的cpu優化和資源限制暫時記錄到這里,后面有時間再對內存和io進行總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM