cgroup學(xué)習(xí)筆記之 cgroup的簡(jiǎn)介與使用

文章導(dǎo)讀

本文記錄學(xué)習(xí)cgroup的一些歷程,由淺入深,從面到點(diǎn)的介紹了cgroup的相關(guān)知識(shí),并以kubernetes使用cpu,memory cgroup為切入點(diǎn)進(jìn)行分析,破除對(duì)于cgroup技術(shù)的恐懼心理,讓cgroup能夠?yàn)槲宜?。本文包含以下?nèi)容 :

  • 為什么需要cgroup
  • cgroup的使用方法
  • cgroup的子系統(tǒng)介紹
  • cgroup v1的局限性
  • cgroup v2
  • 查看cgroup的一些方法
  • systemd的slice,sope,unit介紹
  • kubelet使用cgroup的一些坑

cgroup的需求來源

計(jì)算機(jī)的硬件資源是有限的,如cpu,memory,io,network等,然而軟件對(duì)于資源的需求是貪婪的。按照我的理解,cgroup就是來實(shí)現(xiàn)優(yōu)先保證高優(yōu)先級(jí)應(yīng)用的資源需求,并確保應(yīng)用對(duì)于資源的使用不會(huì)超量。所以cgroup就是限制進(jìn)程的資源使用,并對(duì)資源的使用情況做統(tǒng)計(jì)。

說出來一些具體的事項(xiàng),才能更好的理解cgroup。

  • DPDK綁定cpu,提高程序的運(yùn)行效率,這就可以用到cpuset。
  • 之前面試時(shí),面試官問到監(jiān)控工具對(duì)于系統(tǒng)有沒有什么影響,如執(zhí)行ansible,top,pidstat,vmstat等等工具。現(xiàn)在就有一些思路了,可以使用cgroup來限制這些監(jiān)控程序的資源使用,來保證系統(tǒng)的穩(wěn)定性。
  • 一個(gè)節(jié)點(diǎn)上多個(gè)pod,共享cpu資源,就可以用cgroup來限制pod的cpu使用情況,設(shè)置某個(gè)pod最多可以用到5C等。
  • 付費(fèi)用戶可以使用更多內(nèi)存資源(資源統(tǒng)計(jì)),就可以使用cgroup 的memory來限制普通用戶的資源使用。
  • 某些程序會(huì)有bug,有內(nèi)存泄露,也可以利用cgroup的memory來限制資源使用,不會(huì)對(duì)系統(tǒng)造成太大的影響。
  • 以上都是強(qiáng)行編造....

cgroup子系統(tǒng)分類

以5.4的內(nèi)核為例,cgroup包括cpu,memory,blokio,network...,這里的每一個(gè)文件夾都表示cgroup的一個(gè)子系統(tǒng),這里只以cpu,memory為例進(jìn)行介紹。

root@iZt4n1u8u50jg1r5n6myn2Z:~# mount -t tmpfs |grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
root@iZt4n1u8u50jg1r5n6myn2Z:~# mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
root@iZt4n1u8u50jg1r5n6myn2Z:~# ls /sys/fs/cgroup/
blkio  cpu  cpuacct  cpu,cpuacct  cpuset  devices  freezer  hugetlb  memory  net_cls  net_cls,net_prio  net_prio  perf_event  pids  rdma  systemd  unified
root@iZt4n1u8u50jg1r5n6myn2Z:~# uname -a
Linux iZt4n1u8u50jg1r5n6myn2Z 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
root@iZt4n1u8u50jg1r5n6myn2Z:~#

這里請(qǐng)注意一個(gè)細(xì)節(jié),這里有三層掛載,一個(gè)是sysfs,掛載點(diǎn)是/sys/,一個(gè)是tmpfs內(nèi)存文件系統(tǒng),掛載點(diǎn)是/sys/fs/cgroup,另一個(gè)是子系統(tǒng)的掛載,如cpu掛載點(diǎn)是/sys/fs/cgroup/cpu。三層掛載就是三個(gè)文件系統(tǒng),一個(gè)是kernfs,一個(gè)是tmpfs,一個(gè)是cgroup文件系統(tǒng)。即使是基于內(nèi)存的文件系統(tǒng),也都有superblock,dentry,inode等這些vfs的概念。

cgroup的使用

常規(guī)使用

1、創(chuàng)建cgroup子系統(tǒng)的子目錄
2、設(shè)置資源配額
3、將需要限制的進(jìn)程號(hào)寫入子目錄
以cpu限額為例,限制當(dāng)前shell最多使用1C。這里有個(gè)知識(shí)點(diǎn),tasks和cgroup.procs有什么區(qū)別呢?按照官方文檔的描述,將pid寫入cgroup.procs,則該pid所在的線程組及該pid的子進(jìn)程等都會(huì)自動(dòng)加入到cgroup中。將pid寫入tasks,則只限制該pid。

root@iZt4n1u8u50jg1r5n6myn2Z:~# mkdir /sys/fs/cgroup/cpu/myshell -p
root@iZt4n1u8u50jg1r5n6myn2Z:~# echo 100000 > /sys/fs/cgroup/cpu/myshell/cpu.cfs_quota_us
root@iZt4n1u8u50jg1r5n6myn2Z:~# echo $$ > /sys/fs/cgroup/cpu/myshell/cgroup.procs

cg工具集

cgcreate創(chuàng)建,cgdelete刪除,cgget查詢,cgset設(shè)置,cgexec執(zhí)行等

root@iZt4n1u8u50jg1r5n6myn2Z:~# cgcreate -g cpu:mycg
root@iZt4n1u8u50jg1r5n6myn2Z:~# cgset -r cpu.cfs.cfs_quota_us=10000 /mycg
root@iZt4n1u8u50jg1r5n6myn2Z:~# cgexec  -g cpu:mycg df -h -t ext4
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G   29G  9.0G  77% /
root@iZt4n1u8u50jg1r5n6myn2Z:~# cgdelete  -g cpu:mycg

systemd

通過systemd的接口設(shè)置服務(wù)的配額,與上訴兩種方式的使用原理是一樣的。systemcg-top的展示也不錯(cuò)。

root@iZt4n1u8u50jg1r5n6myn2Z:~# systemctl set-property sshd.service CPUShares=2048
root@iZt4n1u8u50jg1r5n6myn2Z:~# cat /sys/fs/cgroup/cpu/system.slice/ssh.service/cpu.shares
2048
root@iZt4n1u8u50jg1r5n6myn2Z:~# systemd-cgtop
Control Group                                                                                                                                                              Tasks   %CPU   Memory  Input/s Output/s
/                                                                                                                                                                            206      -   841.2M        -        -
assist                                                                                                                                                                         -      -     3.1M        -        -
docker                                                                                                                                                                         1      -    11.7M        -        -
docker/cbf77eadcd1bd5b4810eceeee1faa643a7d05bce9ca45d60f01813d15251c135                                                                                                        1      -    11.7M        -        -
system.slice                                                                                                                                                                 135      -   584.0M        -        -
system.slice/AssistDaemon.service                                                                                                                                              8      -     2.6M        -        -
system.slice/accounts-daemon.service                                                                                                                                           3      -     3.0M        -        -
system.slice/aegis.service                                                                                                                                                    28      -   130.3M        -        -
system.slice/aliyun.service                                                                                                                                                    9      -    15.0M        -        -
system.slice/atd.service                                                                                                                                                       1      -   516.0K        -        -
system.slice/chrony.service                                                                                                                                                    2      -     1.8M        -        -

kubelet使用systemd的cgroup驅(qū)動(dòng)目錄層級(jí)

這里kubelet使用systemd是指kubelet調(diào)用systemd的cgroup接口去管理cgroup,systemd管理cgroup與上面的幾種cgroup的方法本質(zhì)上是一致的
這里有三個(gè)slice。
kubepods.slice 所有pod的資源配額,下面還有pod級(jí)別的配額,容器級(jí)別的配額等。
system.slice systemd管理的服務(wù)的資源配額
user.slice ?

[root@10 ~]# ls /sys/fs/cgroup/cpu
cgroup.clone_children  cpuacct.stat       cpuacct.usage_percpu       cpuacct.usage_sys   cpu.cfs_quota_us   cpu.shares      notify_on_release  tasks
cgroup.procs           cpuacct.usage      cpuacct.usage_percpu_sys   cpuacct.usage_user  cpu.rt_period_us   cpu.stat        release_agent      user.slice
cgroup.sane_behavior   cpuacct.usage_all  cpuacct.usage_percpu_user  cpu.cfs_period_us   cpu.rt_runtime_us  kubepods.slice  system.slice
# pod級(jí)別配額
[root@10 ~]# ls -l /sys/fs/cgroup/cpu/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod41c19abf_8aaa_4b4f_9b4a_512194662502.slice/
total 0
-rw-r--r--. 1 root root 0 Nov 28 11:16 cgroup.clone_children
-rw-r--r--. 1 root root 0 Nov 28 11:16 cgroup.procs
-r--r--r--. 1 root root 0 Nov 28 11:16 cpuacct.stat
-rw-r--r--. 1 root root 0 Nov 28 11:16 cpuacct.usage
-r--r--r--. 1 root root 0 Nov 28 11:16 cpuacct.usage_all
-r--r--r--. 1 root root 0 Nov 28 11:16 cpuacct.usage_percpu
-r--r--r--. 1 root root 0 Nov 28 11:16 cpuacct.usage_percpu_sys
-r--r--r--. 1 root root 0 Nov 28 11:16 cpuacct.usage_percpu_user
-r--r--r--. 1 root root 0 Nov 28 11:16 cpuacct.usage_sys
-r--r--r--. 1 root root 0 Nov 28 11:16 cpuacct.usage_user
-rw-r--r--. 1 root root 0 Nov 28 11:16 cpu.cfs_period_us
-rw-r--r--. 1 root root 0 Nov 28 11:16 cpu.cfs_quota_us
-rw-r--r--. 1 root root 0 Nov 28 11:16 cpu.rt_period_us
-rw-r--r--. 1 root root 0 Nov 28 11:16 cpu.rt_runtime_us
-rw-r--r--. 1 root root 0 Nov 28 11:16 cpu.shares
-r--r--r--. 1 root root 0 Nov 28 11:16 cpu.stat
drwxr-xr-x. 2 root root 0 Nov 28 11:18 docker-095cb69032f07a3848e130014b2b574fda73818261ca3074065e3ae53b8f564d.scope
drwxr-xr-x. 2 root root 0 Nov 28 11:18 docker-f791c73f1fb7841079ea2ad89cee7c10f2926f6410f1ab2a01fbf8a65d9d1068.scope
# 容器級(jí)別配額
[root@10 ~]# ls -l /sys/fs/cgroup/cpu/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod41c19abf_8aaa_4b4f_9b4a_512194662502.slice/docker-095cb69032f07a3848e130014b2b574fda73818261ca3074065e3ae53b8f564d.scope/
total 0
-rw-r--r--. 1 root root 0 Nov 28 11:18 cgroup.clone_children
-rw-r--r--. 1 root root 0 Nov 28 11:18 cgroup.procs
-r--r--r--. 1 root root 0 Nov 28 11:18 cpuacct.stat
-rw-r--r--. 1 root root 0 Nov 28 11:18 cpuacct.usage
-r--r--r--. 1 root root 0 Nov 28 11:18 cpuacct.usage_all
-r--r--r--. 1 root root 0 Nov 28 11:18 cpuacct.usage_percpu
-r--r--r--. 1 root root 0 Nov 28 11:18 cpuacct.usage_percpu_sys
-r--r--r--. 1 root root 0 Nov 28 11:18 cpuacct.usage_percpu_user
-r--r--r--. 1 root root 0 Nov 28 11:18 cpuacct.usage_sys
-r--r--r--. 1 root root 0 Nov 28 11:18 cpuacct.usage_user
-rw-r--r--. 1 root root 0 Nov 28 11:18 cpu.cfs_period_us
-rw-r--r--. 1 root root 0 Nov 28 11:18 cpu.cfs_quota_us
-rw-r--r--. 1 root root 0 Nov 28 11:18 cpu.rt_period_us
-rw-r--r--. 1 root root 0 Nov 28 11:18 cpu.rt_runtime_us
-rw-r--r--. 1 root root 0 Nov 28 11:18 cpu.shares
-r--r--r--. 1 root root 0 Nov 28 11:18 cpu.stat
-rw-r--r--. 1 root root 0 Nov 28 11:18 notify_on_release
-rw-r--r--. 1 root root 0 Nov 28 11:18 tasks

查看cgroup個(gè)數(shù)

/proc/cgroups可以查看當(dāng)前系統(tǒng)掛載了多少子系統(tǒng),每個(gè)子系統(tǒng)的cgroup個(gè)數(shù)。
其中hierarchy一列是按照mount的順序生成的一個(gè)編號(hào)。num_cgroups表示該子系統(tǒng)下有多少個(gè)cgroup目錄,可以使用find命令查看。
內(nèi)核函數(shù)入口 :proc_cgroupstats_show

[root@10 ~]# cat /proc/cgroups  |column  -t
#subsys_name  hierarchy  num_cgroups  enabled
cpuset        7          308          1
cpu           4          310          1
cpuacct       4          310          1
blkio         5          310          1
memory        10         314          1
devices       6          310          1
freezer       13         308          1
net_cls       2          308          1
perf_event    12         308          1
net_prio      2          308          1
hugetlb       3          308          1
pids          8          310          1
rdma          11         1            1
misc          9          1            1
// 與上面/proc/cgroups的輸出是一致的。
[root@10 ~]# find /sys/fs/cgroup/cpu/ -type d  | wc -l
310
[root@10 ~]# find /sys/fs/cgroup/blkio/ -type d  | wc -l
310

查看進(jìn)程的所有cgroup信息

內(nèi)核函數(shù)入口 :proc_cgroup_show

root@iZt4n1u8u50jg1r5n6myn2Z:~# cat /proc/38538/cgroup 
12:net_cls,net_prio:/
11:devices:/system.slice/ssh.service
10:hugetlb:/
9:rdma:/
8:memory:/system.slice/ssh.service
7:pids:/system.slice/ssh.service
6:blkio:/system.slice/ssh.service
5:cpuset:/
4:freezer:/
3:cpu,cpuacct:/system.slice/ssh.service
2:perf_event:/
1:name=systemd:/system.slice/ssh.service
0::/system.slice/ssh.service

kubelet使用cgroup的坑

宿主機(jī)上除了跑pod的應(yīng)用,還有其他系統(tǒng)組件,如sshd,kubelet,docker,containerd等服務(wù),且系統(tǒng)組件的優(yōu)先級(jí)應(yīng)該比pod應(yīng)用更高,所以可以通過kubelet的資源預(yù)留功能為系統(tǒng)組件預(yù)留一部分的cpu和memory資源。既可以為system預(yù)留資源,也可以單獨(dú)為kubelet應(yīng)用預(yù)留資源,這里只以system預(yù)留為例說明。

  • systemReserved 配置為系統(tǒng)組件的預(yù)留資源,cpu和memory
  • systemReservedCgroup 配置預(yù)留資源的cgroup路徑
  • enforceNodeAllocatable 這里要配置上pods,systemReserved,高版本的kubernetes,如果這里不加上pods這個(gè)配置項(xiàng),將導(dǎo)致預(yù)留項(xiàng)不生效。
    驗(yàn)證cgroup預(yù)留資源是否生效的方法也很簡(jiǎn)單,以memory為例,kubepods的memorylimit + system的memorylimt = 宿主機(jī)的memory即表明預(yù)留資源生效。

cgroupv2

眾所周知,cgroupv1無法限制bufferio的寫入。下面將演示如何啟用cgroupv2以及使用cgroupv2限制bufferio的寫入。從使用體驗(yàn)上,cgroupv2比cgroupv1更簡(jiǎn)單。
關(guān)閉cgroupv1的內(nèi)核入口函數(shù) __setup("cgroup_no_v1=", cgroup_no_v1);

// 關(guān)閉cgroupv1
root@iZt4n1u8u50jg1r5n6myn2Z:~/lugl# cat /boot/grub/grub.cfg | grep cgroup
        linux   /boot/vmlinuz-5.4.0-91-generic root=UUID=12e5697d-887b-4790-a160-75cf814081a6 ro vga=792 console=tty0 console=ttyS0,115200n8 net.ifnames=0 noibrs quiet cgroup_no_v1=all
// 創(chuàng)建cgroup
root@iZt4n1u8u50jg1r5n6myn2Z:~/lugl# mkdir /sys/fs/cgroup/unified/iotest
// 使能io + memory
root@iZt4n1u8u50jg1r5n6myn2Z:~/lugl# echo "+io +memory" > /sys/fs/cgroup/unified/cgroup.subtree_control
// 將當(dāng)前進(jìn)程挪到iotest的cgroup中
root@iZt4n1u8u50jg1r5n6myn2Z:~/lugl# echo $$ >/sys/fs/cgroup/unified/iotest/cgroup.procs
// 設(shè)置最大寫入速度10M/s
root@iZt4n1u8u50jg1r5n6myn2Z:~/lugl# echo "252:0 wbps=10485760" > /sys/fs/cgroup/unified/iotest/io.max
root@iZt4n1u8u50jg1r5n6myn2Z:~/lugl# fio -iodepth=1 -rw=write -ioengine=libaio -bs=4k -size=300M -numjobs=1 -name=./fio.test
./fio.test: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
fio-3.16
Starting 1 process
Jobs: 1 (f=1): [W(1)][47.8%][w=11.4MiB/s][w=2928 IOPS][eta 00m:12s]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容