Cgroup(一)简介
一、Linux CGroup
Cgroups是control groups的缩写,是Linux内核提供的一种可以限制,记录,隔离进程组(process groups)所使用物理资源的机制
二、作用
1、Resource limitation: 限制资源使用,比如内存使用上限以及文件系统的缓存限制
2、Prioritization: 优先级控制,比如:CPU利用和磁盘IO吞吐
3、Accounting: 一些审计或一些统计,主要目的是为了计费
4、Control: 挂起进程,恢复执行进程
三、基本概念
Cgroups主要由task,cgroup,subsystem及hierarchy构成
1、task:在Cgroups中,task就是系统的一个进程
2、cgroup
Cgroups中的资源控制都以cgroup为单位实现的。
cgroup表示按照某种资源控制标准划分而成的任务组,包含一个或多个子系统。
一个任务可以加入某个cgroup,也可以从某个cgroup迁移到另外一个cgroup
3、subsystem
Cgroups中的subsystem就是一个资源调度控制器(Resource Controller)。
比如CPU子系统可以控制CPU时间分配,内存子系统可以限制cgroup内存使用量
4、hierarchy
hierarchy由一系列cgroup以一个树状结构排列而成,每个hierarchy通过绑定对应的subsystem进行资源调度。
hierarchy中的cgroup节点可以包含零或多个子节点,子节点继承父节点的属性。整个系统可以有多个hierarchy
四、组件之间的关系
1、同一个hierarchy能够附加一个或多个subsystem
cpu和memory subsystems(或者任意多个subsystems)附加到同一个hierarchy
2、cpu subsystem已经附加到了hierarchy A,并且memory subsystem已经附加到了hierarchy B,此时cpu subsystem不能在附加到hierarchy B
3、一个task不能存在于同一个hierarchy的不同cgroup,但可以存在在不同hierarchy中的多个cgroup
系统每次新建一个hierarchy时,该系统上的所有task默认构成了这个新建的hierarchy的初始化cgroup,这个cgroup也称为root cgroup。
对于你创建的每个hierarchy,task只能存在于其中一个cgroup中,即一个task不能存在于同一个hierarchy的不同cgroup中,但是一个task可以存在在不同hierarchy中的多个cgroup中。
如果操作时把一个task添加到同一个hierarchy中的另一个cgroup中,则会从第一个cgroup中移除。
如下图,cpu和memory被附加到cpu_mem_cg的hierarchy。而net_cls被附加到net hierarchy。并且httpd进程被同时加到了cpu_mem_cg hierarchy的cg1 cgroup中和net hierarchy的cg3 cgroup中。并通过两个hierarchy的subsystem分别对httpd进程进行cpu,memory及网络带宽的限制。
4、子task继承父task cgroup的关系
系统中的任何一个task(Linux中的进程)fork自己创建一个子task(子进程)时,子task会自动的继承父task cgroup的关系,在同一个cgroup中,但是子task可以根据需要移到其它不同的cgroup中。父子task之间是相互独立不依赖的。
如下图,httpd进程在cpu_and_mem hierarchy的/cg1 cgroup中并把PID 4537写到该cgroup的tasks中。
之后httpd(PID=4537)进程fork一个子进程httpd(PID=4840)与其父进程在同一个hierarchy的统一个cgroup中,但是由于父task和子task之间的关系独立不依赖的,所以子task可以移到其它的cgroup中。
五、Cgroup使用
1、创建hierarchy
# mkdir /cgroup/cpuset # mount -t cgroup -o cpuset cpuset /cgroup/cpuset # mount -t cgroup|grep cpuset cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) cpuset on /cgroup/cpuset type cgroup (rw,relatime,cpuset)
2、卸载hierarchy
# umount /cgroup/cpuset
3、创建Cgroup
# mkdir /cgroup/cpuset/group1 # ls /cgroup/cpuset/group1/ cgroup.clone_children cpuset.cpu_exclusive cpuset.effective_mems cpuset.memory_migrate cpuset.memory_spread_slab cpuset.sched_relax_domain_level cgroup.event_control cpuset.cpus cpuset.mem_exclusive cpuset.memory_pressure cpuset.mems notify_on_release cgroup.procs cpuset.effective_cpus cpuset.mem_hardwall cpuset.memory_spread_page cpuset.sched_load_balance tasks # ls /sys/fs/cgroup/cpuset/group1/ cgroup.clone_children cpuset.cpu_exclusive cpuset.effective_mems cpuset.memory_migrate cpuset.memory_spread_slab cpuset.sched_relax_domain_level cgroup.event_control cpuset.cpus cpuset.mem_exclusive cpuset.memory_pressure cpuset.mems notify_on_release cgroup.procs cpuset.effective_cpus cpuset.mem_hardwall cpuset.memory_spread_page cpuset.sched_load_balance tasks
可以看到cpuset子系统同时挂载到cgroup/cpuset和/sys/fs/cgroup/cpuset,其实底层是连接到同一个inode,相当于硬连接
4、设置参数
# echo 0-1 >/cgroup/cpuset/group1/cpuset.cpus # echo 0 >/cgroup/cpuset/group1/cpuset.mems
5、限制进程
# echo 1024 > /sys/fs/cgroup/cpuset/group1/tasks
六、subsystem
1、当前系统支持的子系统
# more /proc/cgroups #subsys_name hierarchy num_cgroups enabled cpuset 9 1 1 cpu 10 2 1 cpuacct 10 2 1 memory 7 2 1 devices 4 1 1 freezer 11 1 1 net_cls 3 1 1 blkio 5 1 1 perf_event 6 1 1 hugetlb 8 1 1 pids 2 2 1 net_prio 3 1 1
- subsys_name:subsystem的名字
- hierarchy:subsystem所关联到的cgroup树的ID,如果多个subsystem关联到同一颗cgroup树,那么他们的这个字段将一样
- num_cgroups:subsystem所关联的cgroup树中进程组的个数,也即树上节点的个数
- enabled:是否开启开子系统,1表示开启,0表示没有被开启
2、子系统介绍
- cpu:用来限制cgroup的CPU使用率。
- cpuacct:统计cgroup的CPU的使用率。
- cpuset:绑定cgroup到指定CPUs和NUMA节点。
- memory:统计和限制cgroup的内存的使用率,包括process memory, kernel memory, 和swap。
- devices:限制cgroup创建(mknod)和访问设备的权限。
- freezer:suspend和restore一个cgroup中的所有进程。
- net_cls:将一个cgroup中进程创建的所有网络包加上一个classid标记,用于tc和iptables。 只对发出去的网络包生效,对收到的网络包不起作用。
- blkio:限制cgroup访问块设备的IO速度。
- perf_event:对cgroup进行性能监控
- net_prio:针对每个网络接口设置cgroup的访问优先级。
- hugetlb:限制cgroup的huge pages的使用量。
- pids:限制一个cgroup及其子孙cgroup中的总进程数。
3、查看进程所属的cgroup
# more /proc/{PID}/cgroup 11:freezer:/ 10:cpuacct,cpu:/ 9:cpuset:/ 8:hugetlb:/ 7:memory:/ 6:perf_event:/ 5:blkio:/ 4:devices:/ 3:net_prio,net_cls:/ 2:pids:/ 1:name=systemd:/system.slice/filebeat.service
第一列:cgroup树的ID
第二列:和cgroup树绑定的所有subsystem,多个subsystem之间用逗号隔开。这里name=systemd表示没有和任何subsystem绑定,只是给他起了个名字叫systemd
第三列:进程在cgroup树中的路径,这个路径是相对于挂载点的相对路径