简介:cgroups是控制群组(control groups)的简写,是linux内核的一个功能,用来限制、控制与分离一个进程资源(如cpu、内存、磁盘等)
cgroups是控制群组(control groups)的简写,是linux内核的一个功能,用来限制、控制与分离一个进程资源(如cpu、内存、磁盘等)。
Linux通过文件系统,将cgroups的功能和配置暴露给用户,文件系统上层还有一层虚拟文件系统(VFS)。VFS将具体文件系统的细节隐藏起来,给用户态提供一个统一的文件系统API接口。
文件本身是层级的,构成了hierarchery,这个层次结构是通过在cgroup文件系统中创建、删除和重命名子目录来定义。用户直接通过创建、读写和删除目录、文件来控制cgroups
文件系统可以被linux操作系统使用,但是linux系统还找不到它,我们还需要把这个文件系统注册进linux操作系统中,即挂载(mount)
可以通过mount命令查看cgroups的挂载信息,如下所示,我的机器上,cgroups已经挂载了。
[ops@db-backup-001 ~]$ mount -t cgroup
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/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
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/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
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)
如果没有的话,也可以通过以下命令来把想要的subsystem mount 到系统中:
mount -t cgroup -o cpu,cpuset,memory cpu_and_mem /cgroup/cpu_and_mem
这个命令就创建一个名为cpu_and_mem的层级,这个层级上附加了cpu,cpuset,memory三个子系统,并把层级挂载到了/cgroup/cpu_and_mem
什么是子系统?
cgroups支持的所有可配置的资源称为subsystem。例如cpu是一种subsystem,memory也是一种subsystem。linux内核在演进过程中subsystem是不断增加的。
创建cgroup,可以直接用mkdir 在对应的子资源中创建一个目录:
[root@db-backup-001 cpu]# mkdir /sys/fs/cgroup/cpu/mycgroup
[root@db-backup-001 cpu]# cd /sys/fs/cgroup/cpu/mycgroup
[root@db-backup-001 mycgroup]# ls
cgroup.clone_children cpuacct.usage_percpu_sys cpu.rt_period_us
cgroup.procs cpuacct.usage_percpu_user cpu.rt_runtime_us
cpuacct.stat cpuacct.usage_sys cpu.shares
cpuacct.usage cpuacct.usage_user cpu.stat
cpuacct.usage_all cpu.cfs_period_us notify_on_release
cpuacct.usage_percpu cpu.cfs_quota_us tasks
上面的命令在cpu子系统中创建了mycgroup文件夹,该目录中会自动创建一些文件。
除了每个cgroup独特的资源控制文件,还有一些通用的文件。
echo PID > tasks
一次只能添加一个任务进程ID。如果有多个任务ID,需分多次添加。
cgroup各个子系统初始化时,默认把系统中所有进程都纳管了,将一个进程的pid添加到新建的cgroup tasks文件的操作,实际是从一个cgroup移入到另一个cgroup的操作。所以要将进程从某个cgroup中删除,只能通过将其移出到另一个cgroup来实现,或者将进程终止。
删除子资源,就是删除对应的目录:
rmdir /sys/fs/cgroup/cpu/mycgroup
跟cpu相关的子系统有cpu、cpuacct和cpuset。其中:
设置 CPU 数字的单位都是微秒,用us表示
两个文件配合起来设置CPU的使用上限
示例:
echo 250000 > cpu.cfs_quota_us
echo 250000 > cpu.cfs_period_us
echo 1000000 > cpu.cfs_quota_us
echo 500000 > cpu.cfs_period_us
echo 10000 > cpu.cfs_quota_us
echo 50000 > cpu.cfs_period_us
用来设置CPU的相对值,并且是针对所有的CPU(内核),默认值是1024,假如系统中有两个cgroup,分别是A和B,A的shares值是1024,B的shares值是512,那么A将获得1024/(1204+512)=66%的CPU资源,而B将获得33%的CPU资源
shares有两个特点:
综上,我们看到shares是一个绝对值,需要和其他cgroup的值进行比较才能得到自己的相对限额
cat /dev/urandom | gzip -9 > /dev/null

可以看到pid为19496的进程的cpu使用率达到了100%。现在我们使用cgroups将它限制到20%
mkdir /sys/fs/cgroup/cpu/mycgroup
cd /sys/fs/cgroup/cpu/mycgroup
echo 10000 > cpu.cfs_quota_us
echo 50000 > cpu.cfs_period_us
echo 19496 > tasks
