使用cgroups做资源限制测试
一,什么是cgroups?
1,cgroups是资源的控制组,它提供了一套机制用于控制一组特定进程对资源的使用。
cgroups绑定一个进程集合到一个或多个限制资源使用的子系统上。
2, cgroups是容器的实现基础之一:
其中:Namespace主要用于隔离资源
Cgroups用来提供对一组进程以及将来子进程的资源限制
说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest
对应的源码可以访问这里获取: https://github.com/liuhongdi/
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,cgroups的用途:
主要有4个:
Resource limitation: 限制资源使用,例:内存使用上限/cpu的使用限制
Prioritization: 优先级控制,例:CPU利用/磁盘IO吞吐
Accounting: 一些审计或一些统计
Control: 挂起进程/恢复执行进程
三,cgroups相关的操作:
1、查看内核是否开启cgroup支持:
[root@blog ~]$ more /boot/config-`uname -r` | grep -i cgroup CONFIG_CGROUPS=y CONFIG_BLK_CGROUP=y # CONFIG_DEBUG_BLK_CGROUP is not set CONFIG_CGROUP_WRITEBACK=y CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_PIDS=y ...
2、cgroup目前存在v1/v2 两个版本,如何检查当前内核版本是否支持cgroup v2呢 ?
[root@node1 ~]# grep cgroup /proc/filesystems nodev cgroup nodev cgroup2
如果看到cgroup2,表示支持cgroup v2
3、列出所有挂载的cgroup挂载点
[root@blog ~]$ mount | grep cgroup tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755) cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio) cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma) cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
注意:/sys/fs/cgroup的挂载方式是ro,表示readonly
因为/sys/fs/cgroup 目录由 systemd 在系统启动的过程中挂载, 它把目录挂载为只读的类型,这个目录下不能再手动创建目录
4、列出cgroup支持的子系统?
[root@blog ~]# ll /sys/fs/cgroup/ total 0 dr-xr-xr-x 4 root root 0 Jan 10 18:03 blkio lrwxrwxrwx 1 root root 11 Jan 10 18:03 cpu -> cpu,cpuacct lrwxrwxrwx 1 root root 11 Jan 10 18:03 cpuacct -> cpu,cpuacct dr-xr-xr-x 2 root root 0 Jan 10 18:03 cpu,cpuacct dr-xr-xr-x 2 root root 0 Jan 10 18:03 cpuset dr-xr-xr-x 4 root root 0 Jan 10 18:03 devices dr-xr-xr-x 2 root root 0 Jan 10 18:03 freezer dr-xr-xr-x 2 root root 0 Jan 10 18:03 hugetlb dr-xr-xr-x 4 root root 0 Jan 10 18:03 memory lrwxrwxrwx 1 root root 16 Jan 10 18:03 net_cls -> net_cls,net_prio dr-xr-xr-x 2 root root 0 Jan 10 18:03 net_cls,net_prio lrwxrwxrwx 1 root root 16 Jan 10 18:03 net_prio -> net_cls,net_prio dr-xr-xr-x 2 root root 0 Jan 10 18:03 perf_event dr-xr-xr-x 4 root root 0 Jan 10 18:03 pids dr-xr-xr-x 2 root root 0 Jan 10 18:03 rdma dr-xr-xr-x 5 root root 0 Jan 10 18:03 systemd
[root@blog ~]# more /proc/cgroups #subsys_name hierarchy num_cgroups enabled cpuset 8 1 1 cpu 2 1 1 cpuacct 2 1 1 blkio 4 29 1 memory 7 1703 1 devices 3 60 1 freezer 9 1 1 net_cls 5 1 1 perf_event 10 1 1 net_prio 5 1 1 hugetlb 11 1 1 pids 12 67 1 rdma 6 1 1
Cgroup的子系统
blkio | 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等) |
devices | 限制设备文件的创建\限制对设备文件的读写 |
cpuset | 把任务绑定到特定的cpu |
cpu | 限定cpu的时间份额 |
cpuacct | 统计CPU使用情况,例如运行时间,throttled时间(统计一组进程占用cpu资源的报告) |
memory |
这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告 |
freezer | 暂停/恢复cgroup中的task |
net_cls | 配合 tc限制网络带宽(用classid标记该cgroup内的task产生的报文) |
net_prio | 设置进程的网络流量优先级 |
huge_tlb | 限制huge page 内存页数量 |
perf_event | 允许perf监控cgroup的task数据 |
ns | 名称空间子系统 |
pids | 限制cgroup中可以创建的进程数 |
rdma | 限制RDMA资源(Remote Direct Memory Access,远程直接数据存取) |
参考: https://man7.org/linux/man-pages/man7/cgroups.7.html |
四,查看一个进程上的cgroup限制:
以nginx的进程为例
[root@blog ~]# ps auxfww | grep nginx: root 491 0.0 0.0 71028 3368 ? Ss May18 0:00 nginx: master process /usr/local/openresty/nginx/sbin/nginx nginx 492 0.0 0.0 102496 7036 ? S May18 0:00 \_ nginx: worker process nginx 493 0.0 0.0 102764 7496 ? S May18 0:00 \_ nginx: worker process nginx 494 0.0 0.0 102496 5856 ? S May18 0:00 \_ ...
五,使用libcgroup-tools工具包做进程的限制和子系统测试
libcgroup-tools包含了多个cgroup相关的命令,方便进行cgroups的测试。
说明:从centos7开始,已经默认不再使用libcgroup套件
[root@blog ~]# yum install libcgroup-tools -y
lssubsys -a / lssubsys -m 命令
[root@blog ~]lssubsys -a //列出所有的子系统
[root@ht5 ~] lssubsys -m //列出所在的目录
启动1个消耗内存的进程,每个进程占用50M内存
#--vm-keep 一直占用内存,(默认是不断释放并重新分配内存)
[root@node1 memory]# stress -m 1 --vm-bytes 50M --vm-keep stress: info: [14327] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
用pidstat查看效果
[root@node1 ~]# pidstat -r | grep stress 14时57分13秒 0 46088 0.01 0.00 7948 972 0.03 stress 14时57分13秒 0 46089 0.07 0.00 59152 51496 1.34 stress
3,在cgroup中添加一个内存限制:再次用stress测试:
[root@node1 memory]# pwd /sys/fs/cgroup/memory [root@node1 memory]# mkdir lhd_stress_memory
注意:
cgroups 文件系统会在创建文件目录的时候自动创建相应的配置文件
[root@node1 memory]# ls lhd_stress_memory/ cgroup.clone_children memory.kmem.limit_in_bytes memory.kmem.tcp.usage_in_bytes memory.memsw.max_usage_in_bytes memory.soft_limit_in_bytes tasks cgroup.event_control memory.kmem.max_usage_in_bytes memory.kmem.usage_in_bytes memory.memsw.usage_in_bytes memory.stat cgroup.procs memory.kmem.slabinfo memory.limit_in_bytes memory.move_charge_at_immigrate memory.swappiness memory.failcnt memory.kmem.tcp.failcnt memory.max_usage_in_bytes memory.numa_stat memory.usage_in_bytes memory.force_empty memory.kmem.tcp.limit_in_bytes memory.memsw.failcnt memory.oom_control memory.use_hierarchy memory.kmem.failcnt memory.kmem.tcp.max_usage_in_bytes memory.memsw.limit_in_bytes memory.pressure_level notify_on_release
可以看到新建目录下面已建好了配置文件
设置这个cgroup内存限制的最大使用内存:
[root@node1 memory]# expr 1024 \* 1024 \* 10 10485760
设置内存的限制
[root@node1 memory]# echo 10485760 > lhd_stress_memory/memory.limit_in_bytes
用stress测试内存限制
[root@node1 memory]# cgexec -g memory:lhd_stress_memory stress -m 1 --vm-bytes 100M --vm-keep --verbose stress: info: [35293] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd stress: dbug: [35293] using backoff sleep of 3000us stress: dbug: [35293] --> hogvm worker 1 [35294] forked stress: dbug: [35294] allocating 104857600 bytes ... stress: dbug: [35294] touching bytes in strides of 4096 bytes ... stress: FAIL: [35293] (415) <-- worker 35294 got signal 9 stress: WARN: [35293] (417) now reaping child worker processes stress: FAIL: [35293] (451) failed run completed in 0s
六,与systemd相关的cgroup操作:
1、systemd-cgtop:显示 cgoups 的实时资源消耗情况
[root@node1 ~]# systemd-cgtop Control Group Tasks %CPU Memory Input/s Output/s / 211 4.0 1.0G - - /system.slice 84 1.5 831.7M - - /user.slice 9 0.9 64.3M - - /system.slice/kubelet.service 15 0.6 31.3M - …
2、systemd-cgls :查看 cgroups 的层级结构
[root@node1 ~]# systemd-cgls Control group /: -.slice ├─user.slice │ └─user-0.slice │ ├─session-3.scope │ │ ├─14349 sshd: root [priv] …
什么是slice:一组进程:由service或会话/容器/虚拟机组成
3、为systemd启动的服务添加cgroup限制
查看有哪些cgroup配置项可用
[root@node1 ~]# man systemd.resource-control
查看nginx的内存限制:
[root@node1 ~]# more /sys/fs/cgroup/memory/system.slice/nginx.service/memory.limit_in_bytes 9223372036854771712
上面是没有手动设置时的默认值
设置内存限制
[root@node1 ~]# systemctl set-property nginx.service MemoryLimit=512M
再次查看
[root@node1 ~]# more /sys/fs/cgroup/memory/system.slice/nginx.service/memory.limit_in_bytes 536870912
注意:即使服务重启,这个cgroup限制仍然会起作用,因为systemctl已经把它写到了service文件中
[root@node1 ~]# systemctl cat nginx # /usr/lib/systemd/system/nginx.service [Unit] Description=The nginx HTTP and reverse proxy server After=network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/run/nginx.pid # Nginx will fail to start if /run/nginx.pid already exists but has the wrong # SELinux context. This might happen when running `nginx -t` from the cmdline. # https://bugzilla.redhat.com/show_bug.cgi?id=1268621 ExecStartPre=/usr/bin/rm -f /run/nginx.pid ExecStartPre=/usr/sbin/nginx -t ExecStart=/usr/sbin/nginx ExecReload=/bin/kill -s HUP $MAINPID KillSignal=SIGQUIT TimeoutStopSec=5 KillMode=mixed PrivateTmp=true [Install] WantedBy=multi-user.target # /etc/systemd/system.control/nginx.service.d/50-MemoryLimit.conf # This is a drop-in unit file extension, created via "systemctl set-property" # or an equivalent operation. Do not edit. [Service] MemoryLimit=536870912
4、其他常用命令:
设置cpu使用率最高不超过单颗cpu的80%
[root@node1 ~]# systemctl set-property nginx.service CPUQuota=80%
七,查看linux的版本:
[root@node1 ~]# more /etc/redhat-release CentOS Linux release 8.1.1911 (Core) [root@node1 ~]# uname -r 4.18.0-147.el8.x86_64
参考
https://man7.org/linux/man-pages/man1/unshare.1.html
https://man7.org/linux/man-pages/man7/cgroups.7.html
https://man7.org/linux/man-pages/man7/cgroups.7.html
分类:
k8s
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2022-02-22 导出带标签的tar包(docker)-解决导出不带标签的麻烦