Cgroup

什么是Cgroup

cgroups,其名称源自控制组群(control groups)的简写,是Linux内核的一个功能,用来限制、控制与分离一个进程组的资源(如CPU、内存、磁盘输入输出等)。

这个项目最早是由Google的工程师(主要是Paul Menage和Rohit Seth)在2006年发起,最早的名称为进程容器(process containers)。

在2007年时,因为在Linux内核中,容器(container)这个名词有许多不同的意义,为避免混乱,被重命名为cgroup,并且被合并到2.6.24版的内核中去。自那以后,又添加了很多功能。

Cgroup的相关概念

1.任务(task)。在cgroups中,任务就是系统的一个进程。

2.控制族群(control group)。控制族群就是一组按照某种标准划分的进程。Cgroups中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用cgroups以控制族群为单位分配的资源,同时受到cgroups以控制族群为单位设定的限制。

3.层级(hierarchy)。控制族群可以组织成hierarchical的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性。

4.子系统(subsystem)。一个子系统就是一个资源控制器,比如cpu子系统就是控制cpu时间分配的一个控制器。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。

相互关系

1.每次在系统中创建新层级时,该系统中的所有任务都是那个层级的默认 cgroup(我们称之为 root cgroup ,此cgroup在创建层级时自动创建,后面在该层级中创建的cgroup都是此cgroup的后代)的初始成员。

2.一个子系统最多只能附加到一个层级。

3.一个层级可以附加多个子系统

4.一个任务可以是多个cgroup的成员,但是这些cgroup必须在不同的层级。

5.系统中的进程(任务)创建子进程(任务)时,该子任务自动成为其父进程所在 cgroup 的成员。然后可根据需要将该子任务移动到不同的 cgroup 中,但开始时它总是继承其父任务的cgroup。

Cgroup的功能

cgroups的一个设计目标是为不同的应用情况提供统一的接口,从控制单一进程(像nice)到操作系统层虚拟化(像OpenVZ,Linux-VServer,LXC)。cgroups提供:

  1. 资源限制:组可以被设置不超过设定的内存限制;这也包括虚拟内存。
  2. 优先级:一些组可能会得到大量的CPU或磁盘IO吞吐量。
  3. 结算:用来衡量系统确实把多少资源用到适合的目的上。
  4. 控制:冻结组或检查点和重启动。

过去有一段时间,内核开发者甚至把 namespace 也作为一个 cgroups 的 subsystem 加入进来,也就是说 cgroups 曾经甚至还包含了资源隔离的能力。但是资源隔离会给 cgroups 带来许多问题,如 PID 在循环出现的时候 cgroup 却出现了命名冲突、cgroup 创建后进入新的 namespace 导致脱离了控制等等。

Cgroup的作用

Cgroups最初的目标是为资源管理提供的一个统一的框架,既整合现有的cpuset等子系统,也为未来开发新的子系统提供接口。现在的cgroups适用于多种应用场景,从单个进程的资源控制,到实现操作系统层次的虚拟化(OS Level Virtualization)。Cgroups提供了以下功能:

  1. 限制进程组可以使用的资源数量(Resource limiting )。比如:memory子系统可以为进程组设定一个memory使用上限,一旦进程组使用的内存达到限额再申请内存,就会触发OOM(out of memory)。
  2. 进程组的优先级控制(Prioritization )。比如:可以使用cpu子系统为某个进程组分配特定cpu share。
  3. 记录进程组使用的资源数量(Accounting )。比如:可以使用cpuacct子系统记录某个进程组使用的cpu时间
  4. 进程组隔离(Isolation)。比如:使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间。
  5. 进程组控制(Control)。比如:使用freezer子系统可以将进程组挂起和恢复。

Cgroup的层级图及特点

层级图:
在这里插入图片描述
Cgroup 特点

  • 在 cgroups 中,任务就是系统的一个进程。

  • 控制族群(control group)。控制族群就是一组按照某种标准划分的进程。Cgroups中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用cgroups 以控制族群为单位分配的资源,同时受到 cgroups 以控制族群为单位设定的限制。

  • 层级(hierarchy)。控制族群可以组织成 hierarchical 的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性。

  • 子系统(subsytem)。一个子系统就是一个资源控制器,比如 cpu 子系统就是控制 cpu
    时间分配的一个控制器。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。

    Cgroup怎么用

    假设现在要将一个新的任务加入到cgroup,功能是将该任务的进程在指定的cpu上运行,因此我们使用"cpuset"cgroup 子系统,操作的大致步骤如下:

    1)mount -t tmpfs cgroup_root /sys/fs/cgroup

    挂载cgroup根文件系统,类型为tmpfs

    2)mkdir /sys/fs/cgroup/cpuset

    在cgroupfs根目录下创建子cgroup,名为cpuset

    3)mount -t cgroup -o cpuset cpuset /sys/fs/cgroup/cpuset

    将名为cpuset的cgroup关联到cpuset子系统

    4)在cpuset目录下创建目录,生成一个子cgroup,属性文件中写入相应内容,设置属性。

    5)启动需要限制的进程,查找其对应的进程ID,将其写入对应的task文件中

    以下操作步骤是创建一个名为"Charlie"的cgroup,这个cgroup的资源包含cpu2,cpu3和内存节点1,将shell进程附加到这个cgroup。

    mount -t tmpfs cgroup_root /sys/fs/cgroup

    mkdir /sys/fs/cgroup/cpuset

    mount -t cgroup cpuset -o cpuset /sys/fs/cgroup/cpuset

    cd /sys/fs/cgroup/cpuset

    mkdir Charlie

    cd Charlie

    echo 2-3 > cpuset.cpus

    echo 1 > cpuset.mems

    echo $$ > tasks

    sh

    cat /proc/self/cgroup

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐