Linux CGroups简介

1、CGroups是什么

与Linux namespace对比来看,Linux namespace用来限制进程的运行范围或者运行环境的可见性,比如:uts限制进程读取到的hostname、mnt限制进程读取到的文件系统视图、net限制进程可以访问的网络范围等;而CGroups则是用来限制进程的资源配给,比如:磁盘IO读写速率、内存使用限制、CPU时间限制等,从而避免争抢和挤压。

2、核心概念

既然CGroups是用来管理进程的资源配给的,那么CGroups的概念最少应该涉及到进程和资源两部分:

  • task:任务,用来表示进程。
  • subsystem:子系统,用来表示资源控制***类型***,比如:cpu、memory等。Linux目前支持12种类型的subsystem:
    • blkio:限制task操作块设备的io速率
    • cpu:限制task的cpu使用率
    • cpuacct:非限制类,生成cgroup中task的cpu使用报告
    • cpuset:为cgroup中的task分配独立的cpu和内存节点
    • devices:现在cgroup中的task可以访问的设备
    • freezer:是cgroup中的task挂起,或者使挂起的task恢复正常运行
    • hugetlb:限制cgroup的HugeTLB使用量
    • memory:限制task的内存使用量
    • net_cls:标记task发出的网络数据包,tc会对标记过的数据包进行处理
    • net_prio:为task设置网络优先级
    • perf_event:对cgroup进行性能监控,而非对task进行监控
    • pids:现场cgroup中的task数量(含下级cgroup中的task)

除了进程和资源以外,还需要将两者结合起来,并且提供有效的管理手段:

  • cgroup:控制组,将task进行分组管理,以组为单位进行资源配给***量***设置。
  • hierarchy:可以理解为某个或者某些subsystem挂载点,比如:/sys/fs/cgroup/memory目录或者/sys/fs/cgroup/cpu,cpuacct目录都可以理解为一个hierarchy。
    • 一个subsystem只能出现在一个hierarchy上,最精细的情况就是每个hierarchy上仅挂载一个subsystem。
    • hierarchy上挂载的subsystem决定了当前hierarchy下的cgroup可以使用且只能使用的资源控制***类型***,比如:/sys/fs/cgroup/memory下的cgroup***只能***使用memory一种,而/sys/fs/cgroup/cpu,cpuacct***只能***使用cpu和cpuacct的组合。可以理解为:同一个hierarchy上的所有进程都以相同的手段限制资源,差别在于cgroup与cgroup之间的资源阈值。
    • 每个hierarchy都挂载着当前系统中的所有进程,初始状态下,这些进程都属于默认的cgroup,称之为root cgroup(考虑每个hierarchy都是一颗完整的进程树),可以在root cgroup下创建子cgroup。
    • 每个hierarchy上的进程只能属于一个cgroup,每当将进程加入到新的cgroup后,系统会自动从老的cgroup中移除该进程。
    • 在一个hierarchy上关联所有的subsystem,这是最粗力度的进程管理方式,每个进程同时使用所有的subsystem。
    • 每一个hierarchy上仅关联一个subsystem,这是最细粒度的进程管理方式,每个hierarchy上的进程仅使用一个subsystem。

核心概念中的前三个都比较简单,稍微难以理解的可能就是hierarchy了。简单来说,hierarchy可以理解为subsystem的分组,组团对进程进行限制,至于限制量多少,cgroup说了算~


上图中有两颗hierarchy树:hierarchy-a和hierarchy-b,两颗树上的task(进程)完全相同,两颗树上的subsystem不能存在交集,两颗树上的cgroup分组方式相互独立,互不影响。hierarchy-a上的cgroup必须同时使用cpu和cpuacct两种subsystem,此时cpu和cpuacct是一个整体。而hierarchy-b上只能使用memory一种subsystem。

进程fork出新的子进程时,子进程与父进程处于同一cgroup,受到相同的subsystem限制。之后子进程可以被添加到其他cgroup,父进程不受影响,父子进程相互独立。

3、基本操作

3.1、管理hierarchy

  • 查看当前系统中的hierarchy
### 查看当前系统中的hierarchy ###
[root@localhost ~]# mount --type cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,memory)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,blkio)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,hugetlb)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,freezer)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,net_prio,net_cls)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,devices)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpuset)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpuacct,cpu)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,perf_event)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,pids)
  • 创建hierarchy
### 尝试创建另一个hierarchy,失败,因为:从上面的结果来看,系统默认的hierarchy已经包含了所有的subsystem ###
[root@localhost ~]# mount --type cgroup --options cpu cpu cgroups/
mount: cpu is already mounted or /root/cgroups busy ### 尝试创建一个不与任何subsystem关联的hierarchy ###
[root@localhost ~]# mount --type cgroup --options none,name=cgroup-1 cgroup-1 cgroups/cgroup-1/
### 创建cgroup-1之后,系统会自动创建必要的配置文件 ###
[root@localhost ~]# ll cgroups/cgroup-1/
total 0
-rw-r--r--. 1 root root 0 Feb 26 14:57 cgroup.clone_children
--w--w--w-. 1 root root 0 Feb 26 14:57 cgroup.event_control
-rw-r--r--. 1 root root 0 Feb 26 14:57 cgroup.procs
-r--r--r--. 1 root root 0 Feb 26 14:57 cgroup.sane_behavior
-rw-r--r--. 1 root root 0 Feb 26 14:57 notify_on_release
-rw-r--r--. 1 root root 0 Feb 26 14:57 release_agent
-rw-r--r--. 1 root root 0 Feb 26 14:57 tasks

CGroup系统没有提供任何系统调用接口,而是通过vfs实现类似文件系统的操作方式来进行管理,比如上述这些自动生成的文件。因为没有关联任何subsystem,这些文件都是一些通用文件,文件的基本含义如下:

  • cgroup.clone_children:仅对cpuset有效,当配置内容为 1 时表示继承上级cgroup的cpuset配置。
  • cgroup.event_control:eventfd接口。
  • cgroup.procs:记录当前cgroup中的所有线程ID(TGID),无序,可重复。项此文件中增加tgid表示将整个线程组加入此cgroup。
  • cgroup.sane_behavior:
  • tasks:记录当前cgroup中的所有进程ID(PID),无序,可重复。向此文件中增加pid即表示将进程加入此cgroup,同时也会将pid从原cgroup的tasks文件中移除。
  • notify_on_release:如果改文件的内容为 1 ,当cgroup退出时系统将调用release_agent文件中的命令。
  • release_agent:cgroup退出时需要执行的命令,此文件仅出现在root cgroup中。

除了上述通用文件之外,每个subsystem都有自己独特的配置文件和配置格式,比如:

### 查看系统memory subsystem对应的配置文件 ###
[root@localhost ~]# ll /sys/fs/cgroup/memory/
total 0
-rw-r--r--. 1 root root 0 Feb 27 13:27 cgroup.clone_children
--w--w--w-. 1 root root 0 Feb 27 13:27 cgroup.event_control
-rw-r--r--. 1 root root 0 Feb 27 13:27 cgroup.procs
-r--r--r--. 1 root root 0 Feb 27 13:27 cgroup.sane_behavior
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.failcnt
--w-------. 1 root root 0 Feb 27 13:27 memory.force_empty
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.kmem.failcnt
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.kmem.limit_in_bytes
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.kmem.max_usage_in_bytes
-r--r--r--. 1 root root 0 Feb 27 13:27 memory.kmem.slabinfo
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.kmem.tcp.failcnt
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.kmem.tcp.limit_in_bytes
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.kmem.tcp.max_usage_in_bytes
-r--r--r--. 1 root root 0 Feb 27 13:27 memory.kmem.tcp.usage_in_bytes
-r--r--r--. 1 root root 0 Feb 27 13:27 memory.kmem.usage_in_bytes
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.limit_in_bytes
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.max_usage_in_bytes
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.memsw.failcnt
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.memsw.limit_in_bytes
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.memsw.max_usage_in_bytes
-r--r--r--. 1 root root 0 Feb 27 13:27 memory.memsw.usage_in_bytes
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.move_charge_at_immigrate
-r--r--r--. 1 root root 0 Feb 27 13:27 memory.numa_stat
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.oom_control
----------. 1 root root 0 Feb 27 13:27 memory.pressure_level
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.soft_limit_in_bytes
-r--r--r--. 1 root root 0 Feb 27 13:27 memory.stat
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.swappiness
-r--r--r--. 1 root root 0 Feb 27 13:27 memory.usage_in_bytes
-rw-r--r--. 1 root root 0 Feb 27 13:27 memory.use_hierarchy
-rw-r--r--. 1 root root 0 Feb 27 13:27 notify_on_release
-rw-r--r--. 1 root root 0 Feb 27 13:27 release_agent
-rw-r--r--. 1 root root 0 Feb 27 13:27 tasks
  • 删除hierarchy
### 接触挂载 ###
[root@localhost ~]# umount cgroups/cgroup-1/
### 自动生成的配置文件在umount之后自动删除 ###
[root@localhost ~]# ll cgroups/cgroup-1/
total 0

3.2、管理cgroup

hierarchy创建之后,默认会与一个顶层cgroup,也就是该hierarchy的root cgroup。在root cgroup下创建新目录,也就是创建了下级cgroup,项cgroup中加入task,配置对应的subsystem参数,也就限制了task中的进行访问与subsystem对应的系统资源的访问。

  • 创建cgroup
### 在/sys/fs/cgroup/cpu创建cgroup-c ###
[root@localhost ~]# mkdir /sys/fs/cgroup/cpu/cgroup-c
### 系统自动生成对应的配置文件,说明cgroup创建成功 ###
[root@localhost ~]# ll /sys/fs/cgroup/cpu/cgroup-c
total 0
-rw-r--r--. 1 root root 0 Feb 27 15:14 cgroup.clone_children
--w--w--w-. 1 root root 0 Feb 27 15:14 cgroup.event_control
-rw-r--r--. 1 root root 0 Feb 27 15:14 cgroup.procs
-r--r--r--. 1 root root 0 Feb 27 15:14 cpuacct.stat
-rw-r--r--. 1 root root 0 Feb 27 15:14 cpuacct.usage
-r--r--r--. 1 root root 0 Feb 27 15:14 cpuacct.usage_percpu
-rw-r--r--. 1 root root 0 Feb 27 15:14 cpu.cfs_period_us
-rw-r--r--. 1 root root 0 Feb 27 15:14 cpu.cfs_quota_us
-rw-r--r--. 1 root root 0 Feb 27 15:14 cpu.rt_period_us
-rw-r--r--. 1 root root 0 Feb 27 15:14 cpu.rt_runtime_us
-rw-r--r--. 1 root root 0 Feb 27 15:14 cpu.shares
-r--r--r--. 1 root root 0 Feb 27 15:14 cpu.stat
-rw-r--r--. 1 root root 0 Feb 27 15:14 notify_on_release
-rw-r--r--. 1 root root 0 Feb 27 15:14 tasks
### 每个cgroup还可以继续创建下级cgroup,下级会继承上级的一些配置项 ###
[root@localhost ~]# ll /sys/fs/cgroup/cpu/cgroup-c/cgroup-c-1
total 0
-rw-r--r--. 1 root root 0 Feb 27 15:17 cgroup.clone_children
--w--w--w-. 1 root root 0 Feb 27 15:17 cgroup.event_control
-rw-r--r--. 1 root root 0 Feb 27 15:17 cgroup.procs
-r--r--r--. 1 root root 0 Feb 27 15:17 cpuacct.stat
-rw-r--r--. 1 root root 0 Feb 27 15:17 cpuacct.usage
-r--r--r--. 1 root root 0 Feb 27 15:17 cpuacct.usage_percpu
-rw-r--r--. 1 root root 0 Feb 27 15:17 cpu.cfs_period_us
-rw-r--r--. 1 root root 0 Feb 27 15:17 cpu.cfs_quota_us
-rw-r--r--. 1 root root 0 Feb 27 15:17 cpu.rt_period_us
-rw-r--r--. 1 root root 0 Feb 27 15:17 cpu.rt_runtime_us
-rw-r--r--. 1 root root 0 Feb 27 15:17 cpu.shares
-r--r--r--. 1 root root 0 Feb 27 15:17 cpu.stat
-rw-r--r--. 1 root root 0 Feb 27 15:17 notify_on_release
-rw-r--r--. 1 root root 0 Feb 27 15:17 tasks
  • 删除cgroup
### 删除cgroup时,需要先删除下级cgroup ###
[root@localhost ~]# rmdir /sys/fs/cgroup/cpu/cgroup-c/
rmdir: failed to remove ‘/sys/fs/cgroup/cpu/cgroup-c/’: Device or resource busy
### 直接删除对应的目录即可 ###
[root@localhost ~]# rmdir /sys/fs/cgroup/cpu/cgroup-c/cgroup-c-1/
[root@localhost ~]# rmdir /sys/fs/cgroup/cpu/cgroup-c
[root@localhost ~]# ll /sys/fs/cgroup/cpu/cgroup-c
ls: cannot access /sys/fs/cgroup/cpu/cgroup-c: No such file or directory
  • 查看当前进程属于查询cgroup
### 数据结构:hierarchy_id:subsystem:cgroup_path ###
[root@localhost ~]# cat /proc/$$/cgroup
11:perf_event:/
10:blkio:/
9:freezer:/
8:pids:/
7:hugetlb:/
6:memory:/
5:cpuacct,cpu:/
4:devices:/
3:net_prio,net_cls:/
2:cpuset:/
1:name=systemd:/user.slice/user-0.slice/session-1.scope

cgroup_path表示从root cgroup(/)开始的路径,比如 /user.slice/user-0.slice/session-1.scope 表示的实际位置为:/sys/fs/cgroup/systemd/user.slice/user-0.slice/session-1.scope


这一篇先简单介绍到这里,主要为了理解cgroups的几个核心概念,具体subsystem的详细配置方法这里就不再继续研究了。

linux cgroups简介(上)的更多相关文章

  1. linux cgroups简介(下)Cgroups 与 Systemd

    Cgroups 是 linux 内核提供的一种机制,如果你还不了解 cgroups,请参考前文<Linux cgroups 简介>先了解 cgroups.当 Linux 的 init 系统 ...

  2. linux cgroups 简介

    cgroups(Control Groups) 是 linux 内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统 ...

  3. linux 文件系统简介

    linux文件系统简介   文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录.挂载基 ...

  4. Docker之Linux Cgroups

    Linux Cgroups介绍 上面是构建Linux容器的namespace技术,它帮进程隔离出自己单独的空间,但Docker又是怎么限制每个空间的大小,保证他们不会互相争抢呢?那么就要用到Linux ...

  5. Android系统简介(上):历史渊源

    上个月,看到微信的一系列文章,讲到Linux的鼻祖-李纳斯的传记<Just for Fun>, 其人神乎其能, 其人生过程非常有趣,值得每个程序员细细品味. 而实际上,对我而已,虽然做软件 ...

  6. Linux on Power 上的调试工具和技术

     Linux on Power 上的调试工具和技术 简介: 调试是一项主要的软件开发活动,作为应用程序开发人员,您无法避免对程序进行调试.有效的调试不仅能缩短软件开发周期,而且可以节省成本.本文简要介 ...

  7. Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装

    原文:Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装 Linux内核分析(一) 从本篇博文开始我将对linux内核进行学习和分析,整个过程必将十分艰辛,但我会坚持到底 ...

  8. Docker 基础技术之 Linux cgroups 详解

    PS:欢迎大家关注我的公众号:aCloudDeveloper,专注技术分享,努力打造干货分享平台,二维码在文末可以扫,谢谢大家. 推荐大家到公众号阅读,那里阅读体验更好,也沉淀了很多篇干货. 前面两篇 ...

  9. Linux基础学习(1)--Linux系统简介

    第一章——Linux系统简介 1.UNIX和Linux发展史: 1.1 unix发展史: (1)1965年,美国麻省理工学院(MIT).通用电气公司(GE)及AT&T的贝尔实验室联合开发Mul ...

随机推荐

  1. 第10组 Beta冲刺(1/4)

    队名:凹凸曼 组长博客 作业博客 组员实践情况 童景霖 过去两天完成了哪些任务 文字/口头描述 继续学习Android studio和Java 制作剩余界面前端 展示GitHub当日代码/文档签入记录 ...

  2. 对称加密与非对称加密,及Hash算法

    一 , 概述 在现代密码学诞生以前,就已经有很多的加密方法了.例如,最古老的斯巴达加密棒,广泛应用于公元前7世纪的古希腊.16世纪意大利数学家卡尔达诺发明的栅格密码,基于单表代换的凯撒密码.猪圈密码, ...

  3. 【2019年05月20日】A股滚动市盈率PE历史新低排名

    2010年01月01日 到 2019年05月20日 之间,滚动市盈率历史新低排名. 上市三年以上的公司, 2019年05月20日市盈率在300以下的公司. 1 - 阳光照明(SH600261) - 历 ...

  4. React组件介绍与使用(父传子、子传父、兄弟传)

    1.创建组件的方法     1.1.函数式无状态组件 1.1.1.语法 1 function myComponent(props) { 2 return 3 <div>Hello {pro ...

  5. Scrum story

    鸡和猪的故事故事: 一天,一只鸡散步时遇见了猪. 鸡对猪说:“嗨,我们合伙开个餐厅吧.” 猪说:“好啊,那准备取什么店名呢?” 鸡说:“要不,就叫火腿和鸡蛋吧.” 猪直接拒绝了:“那可不行.我要割肉, ...

  6. 重学C语言之结构体

    概念 结构体是一种构造类型,由若干个成员组成,成员可以是基本数据类型,或是另一个结构体 声明结构体 struct 结构体名 { 成员列表 }; 结构体名表示结构的类型名. 声明一个结构体表示创建一种新 ...

  7. 「UNR#1」奇怪的线段树

    「UNR#1」奇怪的线段树 一道好题,感觉解法非常自然. 首先我们只需要考虑一次染色最下面被包含的那些区间,因为把无解判掉以后只要染了一个节点,它的祖先也一定被染了.然后发现一次染色最下面的那些区间一 ...

  8. Java学习:迭代器简介

    迭代器 java.util.Iterator接口:迭代器(对集合进行遍历) 有两个常用的方法 boolean hasNext() 如果仍有元素可以迭代,则返回 true. 判断集合中还有没有下一个元素 ...

  9. 【WPF】2、美化控件

    控件有默认样式,但是有时候默认样式并不够用,就需要美化. 1.常用的方法是美术出图,直接贴图进去,效果又好又简单(对程序来说). 用图片有三种方式:设置控件背景图片.设置控件内容为图片和直接使用图片做 ...

  10. C# 接口、抽象类、以及事件

    接口.抽象类,用于项目集成,如: Interface icls = appid == "A" ? new ClassA() : new ClassA();icls.func(&qu ...