Cgroup基础知识
Cgroup是control groups的缩写,是Linux内核提供的一种可以 限制、记录、隔离进程组所使用的物理资源的机制。Cgroup可实现的功能如下所示:
- 限制进程组可以使用资源的数量,比如限制进程使用内存的大小。
- 进程组优先级的控制,如调整CPU的利用率。
- 记录进程组使用的资源数量。如使用cpuacct子系统记录某个进程组使用的cpu时间。
- 实现进程组之间的隔离。
- 进程组控制。比如使用freezer子系统将进程挂起或者恢复。
基本概念
任务:在cgroup中,任务就是系统的一个进程。
控制族群:一组按照某种标准划分的进程。Cgroups中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用cgroups以控制族群为单位分配的资源,同时受到cgroups以控制族群为单位设定的限制。
层级:控制族群可以组织成hierarchical的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性。
子系统:一个子系统就是一个资源控制器。Cgroup一下九个子系统分别是:blkio(限制块设备的输入与输出)、cpu(使用调度程序提供对CPU的cgroup访问)、cpuacct(生成cgroup中任务使用cpu的报告)、cpuset(为cgroup中的任务分配独立cpu和内存节点)、devices(允许或者拒绝cgroup中的任务访问设备)、freezer(挂起或者恢复cgroup中的任务),memory(限制cgroup中任务队内存的使用)、net_cls(使用等级识别符(classid)标记网络数据包,可允许Linux流量控制程序(tc)识别从具体cgroup中生成的数据包),ns(名称空间子系统)。
相互关系
- 每次在系统中创建新层级时,该系统中的所有任务都是那个层级的默认 cgroup(我们称之为 root cgroup ,此cgroup在创建层级时自动创建,后面在该层级中创建的cgroup都是此cgroup的后代)的初始成员。
- 一个子系统最多只能附加到一个层级。
- 一个层级可以附加多个子系统
- 一个任务可以是多个cgroup的成员,但是这些cgroup必须在不同的层级。
- 系统中的进程(任务)创建子进程(任务)时,该子任务自动成为其父进程所在 cgroup 的成员。然后可根据需要将该子任务移动到不同的 cgroup 中,但开始时它总是继承其父任务的cgroup。
Cgroup结构关系
规则1:每个hierarchy挂载一个或者多个subsystem(只要subsystem没有被其他hierarchy挂载)。如下图:cpu和memory两个子系统被/cpu_mem_cg挂载。
规则2:一个subsystem(比如cpu)不能被多个hierarchy挂载,如果其中一个hierarchy已经挂载其他subsystem类型。如下图:/cpu_mem_cg已经挂载memory subsystem,那么/cpu_mem_cg和/cpu_cg不能同时再挂载一个cpu subsystem。一个subsystem可以被多个hierarchy同时挂载得前提是这多个 hierarchy都只能挂载这个subsystem。
规则3:每个task不能同时处于多个相同的hierarchy的cgroup中,如果task加入到同一个hierarchy里面的第二个group里面,这个task将自动从第一个group里面删除。比如下图:一共有两个hierarchy,分别是/cpu_mem_cg和/net,分别挂载cpu、memory和net_cls这些subsystem;这两个hierarchy一共有三个cgroup,分别是/cg1、/cg2和/cg3,/cg1和/cg2位于/cpu_mem_cg中,/cg3位于/net中。Httpd(PID=54656)这个进程是一个task,可以通过存在/cg1和/cg3这两个cgroup里面,但是不能同时存在/cg1和/cg2这两个cgroup里面。
规则4:子进程在fork工程中自动继承父进程的cgroup配置;fork完毕后,子进程和父进程独立,子进程可以被移动到另外一个cgroup里面。比如下图:httpd(PID=4537)进程fork一个httpd子进程(PID=4840),httpd子进程(PID=4840)自动成为/cg1的成员。
Cgroup基本操作
- 创建层级并附加子系统:
- 在/etc/cgconfig.conf文件中的mount部分配置如下格式的条目:subsystem=/cgroup/hierareby。以下的实例创建了一个cpu_and_mem的层级,并附加cpu/cpuset/cpuacct/memory子系统。
mount{
cpuset=/cgroup/cpu_and_mem
cpu=/cgroup/cpu_and_mem
cpuacct=/cgroup/cpu_and_mem
memory=/cgroup/cpu_and_mem
} - 或者使用mount命令直接挂载,上述的命令等价于以下命令:
- 在/etc/cgconfig.conf文件中的mount部分配置如下格式的条目:subsystem=/cgroup/hierareby。以下的实例创建了一个cpu_and_mem的层级,并附加cpu/cpuset/cpuacct/memory子系统。
mkdir /cgroup/cpu_and_mem |
- 使用remount重新挂载层级并添加子系统。
mount –t cgroup –o remount cpuset,cpu,cpuacct,memory:/cgroup/cpu_and_mem
- 卸载层级。umount /cgroup/cpu_and_mem。
- 创建控制组群。Cgcreate –t uid:gid –a uid:gid –g subsystem:path。-g指定在其中创建 cgroup 的层级,格式为与那些层级关联的用逗号分开的subsystems列表。例如cgcreate –g cpu,net_cls:/test-subgroup。
- 删除控制组群。使用cgdelete删除cgroup,其语法如下所示:cgdelete subsystems:path。如cgdelete cpu,net_cls:/test-group。使用-r选项时循环删除所有的子群组。