cgroup

cgroups 是Linux内核提供的一种可以限制单个进程或者多个进程所使用资源的机制,可以对 cpu,内存等资源实现精细化的控制

比如:可以通过cgroup限制特定进程的资源使用,比如使用特定数目的cpu核数和特定大小的内存,如果资源超限的情况下,会被暂停或者杀掉。

关系梳理:

  • 任务 (task):在cgroup中,任务就是一个进程。
  • 控制组 (control group):cgroup的资源控制是以控制组的方式实现,控制组指明了资源的配额限制。进程可以加入到某个控制组,也可以迁移到另一个控制组。
  • 层级 (hierarchy):控制组有层级关系,类似树的结构,子节点的控制组继承父控制组的属性(资源配额、限制等)
  • 子系统 (subsystem):一个子系统其实就是一种资源的控制器,比如memory子系统可以控制进程内存的使用。子系统需要加入到某个层级,然后该层级的所有控制组,均受到这个子系统的控制。

 

注意!  任务(进程)  和  层级 是不同的概念,任务可以依赖不同的层级

  • 一个层级可以附加多个子系统
  • 一个任务可以是多个cgroup的成员,但这些cgroup必须位于不同的层级

某一个进程也可以被加入到不同的 cgroups 层级结构的节点中,因为不同的 cgroups 层级结构可以负责不同的系统资源。

所以说进程和 cgroup 结构体是一个多对多的关系

cgroup_第1张图片

 

实现细节:

Linux把CGroup实现成了一个file system,在vfs下挂载文件系统,目录下方为他进程tasks

用户态进程使用到cgroups的功能:VFS,VFS将细节隐藏起来,给用户统一的文件系统API接口

cgroups和VFS之间的链接部分,称之为cgroups文件系统

子系统:

  1. cgroups为每种可以控制的资源定义了一个子系统。典型的子系统介绍如下:
  2. cpu 子系统,主要限制进程的 cpu 使用率。
  3. cpuacct 子系统,可以统计 cgroups 中的进程的 cpu 使用报告。
  4. cpuset 子系统,可以为 cgroups 中的进程分配单独的 cpu 节点或者内存节点。
  5. memory 子系统,可以限制进程的 memory 使用量。
  6. blkio 子系统,可以限制进程的块设备 io。
  7. devices 子系统,可以控制进程能够访问某些设备。
  8. net_cls 子系统,可以标记 cgroups 中进程的网络数据包,然后可以使用 tc 模块(traffic control)对数据包进行控制。
  9. freezer 子系统,可以挂起或者恢复 cgroups 中的进程。
  10. ns 子系统,可以使不同 cgroups 下面的进程使用不同的 namespace。
  • 内核使用 cgroup 结构体来表示一个 control group 对某一个或者某几个 cgroups 子系统的资源限制。
  • cgroups可以attach一个或几个cgroups子系统,对资源进行限制
  • 在每一个cgroups层级结构中,每一个节点可以设置对资源不同的限制权重
  • cgroups 的实现不允许css_set同时关联同一个cgroups层级结构下多个节点。 这是因为 cgroups 对同一种资源不允许有多个限制配置。

 

cgroup使用:

云平台都是基于 cgroups 技术搭建的,其实也都是把进程分组,然后把整个进程组添加到同一组 cgroups 节点中,受到同样的资源限制。

  1. 安装:sudo apt install cgroup-bin   安装完会出现/sys/fs/cgroup
  2. 创建cpu资源控制组:
  • cd /sys/fs/cgroup/cpu   
  • mkdir test_cpu     
  • echo '10000' > test_cpu/cpu.cfs_period_us     
  • echo  '5000' >  test_cpu/cpu.cfs_quota_us

 

  •  也可以通过挂载:mount -t cgroup -o remount,cpu,cpuset,memory cpu_and_mem /cgroup/cpu_and_mem

挂载某一个 cgroups 子系统到挂载点之后,就可以通过在挂载点下面建立文件夹或者使用cgcreate命令的方法创建 cgroups 层级结构中的节点。比如通过命令cgcreate -t sankuai:sankuai -g cpu:test就可以在 cpu 子系统下建立一个名为 test 的节点。

使用 cgset 命令也可以设置 cgroups 子系统的参数,格式为 cgset -r parameter=value path_to_cgroup

删除可以用cgdelete

 

      3. 限制程序cpu

     cgexec  -g   cpu: test_cpu   ./程序

 

把进程加入到 cgroups 子节点也有多种方法,可以直接把 pid 写入到子节点下面的 task 文件中。也可以通过 cgclassify 添加进程,格式为 cgclassify -g subsystems:path_to_cgroup pidlist,也可以直接使用 cgexec 在某一个 cgroups 下启动进程,格式为:gexec -g subsystems:path_to_cgroup command arguments

 

参考:

https://tech.meituan.com/2015/03/31/cgroups.html
https://coolshell.cn/articles/17049.html
https://zhuanlan.zhihu.com/p/81668069

你可能感兴趣的:(Linux)