1.1.6 Control groups

Linux Cgroups的全称是Linux Control Groups,是Linux内核的一个功能。最早是由Google的工程师(主要是Paul Menage和Rohit Seth)在2006年发起,最早的名称为进程容器(process containers)。在2007年时,因为在Linux内核中,容器(container)这个名词有许多不同的意义,为避免混乱,被重命名为cgroup,并且被合并到2.6.24版的内核中去。自那以后,又添加了很多功能。

如果不对一个容器做任何资源限制,则宿主机会允许其占用无限大的内存空间,有时候会因为代码bug程序会一直申请内存,直到把宿主机内存占完,为了避免此类的问题出现,宿主机有必要对容器进行资源分配限制,比如CPU、内存等

Cgroups最主要的作用,就是限制一个进程组能够使用的资源上限,包括CPU、内存、磁盘、网络带宽等等。此外,还能够对进程进行优先级设置,资源的计量以及资源的控制(比如:将进程挂起和恢复等操作)。

1.1.6.1 验证系统cgroups

Cgroups在内核层默认已经开启,从CentOS和Ubuntu不同版本对比,显然内核较新的支持的功能更多。

Centos 8 cgroups:

[root@centos8 ~]# cat /etc/centos-release
CentOS Linux release 8.3.2011
[root@centos8 ~]# grep CGROUP /boot/config-4.18.0-240.el8.x86_64
CONFIG_CGROUPS=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_BLK_CGROUP_IOLATENCY=y
# CONFIG_BLK_CGROUP_IOCOST is not set
# CONFIG_BFQ_CGROUP_DEBUG is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y

centos7 cgroups:

[root@centos7 ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)
[root@centos7 ~]# grep CGROUP /boot/config-3.10.0-1160.el7.x86_64
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_NETPRIO_CGROUP=y

ubuntu cgroups:

[root@ubuntu2104 ~]# grep CGROUP /boot/config-5.11.0-17-generic
CONFIG_CGROUPS=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_BLK_CGROUP_RWSTAT=y
# CONFIG_BLK_CGROUP_IOLATENCY is not set
CONFIG_BLK_CGROUP_IOCOST=y
# CONFIG_BFQ_CGROUP_DEBUG is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y

cgroups中内存模块:

[root@ubuntu2104 ~]# grep MEMCG /boot/config-5.11.0-17-generic
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_KMEM=y
CONFIG_SLUB_MEMCG_SYSFS_ON=y

1.1.6.2 cgroups具体实现

blkio:块设备IO限制
cpu:使用调度程序为cgroup任务提供cpu的访问cpuacct:产生cgroup任务的cpu资源报告
cpuset:如果是多核心的cpu,这个子系统会为cgroup任务分配单独的cpu和内存devices:允许或拒绝 cgroup任务对设备的访问
freezer:暂停和恢复cgroup 任务
memory:设置每个cgroup 的内存限制以及产生内存资源报告net_cls:标记每个网络包以供cgroup方便使用
ns:命名空间子系统
perf_event:增加了对每 group的监测跟踪的能力,可以监测属于某个特定的group 的所有线程以及运行在特定CPU上的线程

1.1.6.3 查看系统cgroups

[root@ubuntu2104 ~]# ll /sys/fs/cgroup/
total 0
drwxr-xr-x 15 root root 380 Jul  6 03:08 ./
drwxr-xr-x  9 root root   0 Jul  6 03:08 ../
dr-xr-xr-x 14 root root   0 Jul  6 03:08 blkio/
lrwxrwxrwx  1 root root  11 Jul  6 03:08 cpu -> cpu,cpuacct/
lrwxrwxrwx  1 root root  11 Jul  6 03:08 cpuacct -> cpu,cpuacct/
dr-xr-xr-x 14 root root   0 Jul  6 03:08 cpu,cpuacct/
dr-xr-xr-x  3 root root   0 Jul  6 03:08 cpuset/
dr-xr-xr-x 14 root root   0 Jul  6 03:08 devices/
dr-xr-xr-x  4 root root   0 Jul  6 03:08 freezer/
dr-xr-xr-x  3 root root   0 Jul  6 03:08 hugetlb/
dr-xr-xr-x 14 root root   0 Jul  6 03:08 memory/
lrwxrwxrwx  1 root root  16 Jul  6 03:08 net_cls -> net_cls,net_prio/
dr-xr-xr-x  3 root root   0 Jul  6 03:08 net_cls,net_prio/
lrwxrwxrwx  1 root root  16 Jul  6 03:08 net_prio -> net_cls,net_prio/
dr-xr-xr-x  3 root root   0 Jul  6 03:08 perf_event/
dr-xr-xr-x 14 root root   0 Jul  6 03:08 pids/
dr-xr-xr-x  2 root root   0 Jul  6 03:08 rdma/
dr-xr-xr-x 14 root root   0 Jul  6 03:08 systemd/
dr-xr-xr-x 13 root root   0 Jul  6 07:10 unified/

[root@ubuntu2104 ~]# cat /sys/fs/cgroup/cpu/docker/7bbf2991f09aec07d777944a3b6f7b09062e147751c11ca7726fb2a77d705a4d/cpuacct.usage
3142189146
[root@ubuntu2104 ~]# cat /sys/fs/cgroup/memory/docker/7bbf2991f09aec07d777944a3b6f7b09062e147751c11ca7726fb2a77d705a4d/memory.limit_in_bytes
9223372036854771712
[root@ubuntu2104 ~]# cat /sys/fs/cgroup/memory/docker/7bbf2991f09aec07d777944a3b6f7b09062e147751c11ca7726fb2a77d705a4d/memory.usage_in_bytes
54177792
[root@ubuntu2104 ~]# cat /sys/fs/cgroup/memory/docker/7bbf2991f09aec07d777944a3b6f7b09062e147751c11ca7726fb2a77d705a4d/memory.max_usage_in_bytes
113979392