Cgroups

cgroups，其名稱源自控制群組（）的簡寫，是Linux内核的一个功能，用来限制、控制與分離一个行程群組的资源（如CPU、内存、磁盘输入输出等）。

這個專案最早是由Google的工程師（主要是Paul Menage和Rohit Seth）在2006年發起，最早的名稱為进程容器（process containers）。在2007年時，因為在Linux內核中，容器（container）這個名詞有許多不同的意義，為避免混亂，被重新命名為cgroup，並且被合併到2.6.24版的内核中去（该版本于2008年1月发布）。自那以后，开发人员陆续添加了许多新功能和控制器，例如2014年对kernfs的支持，防火墙功能和统一层次结构。cgroup v2在Linux内核4.5中被合并，接口和内部功能发生了重大变化。

功能
cgroups的一个设计目标是为不同的用例提供统一的接口，从控制单一进程（像Nice值）到作業系統層虛擬化（像OpenVZ，，LXC）。cgroups提供：
 资源限制（Resource limiting）：组可以被设置不超过设定的内存限制（这也包括）、I/O带宽限制、CPU配额限制、CPU集合限制或最大打开文件数。
 优先级设定（Prioritization）：一些组可能会得到更大的CPU或磁盘IO吞吐量。
 结算（Accounting）：衡量一个组的资源使用情况，可以用于计费等目的
 控制（Control）：冻结组中的进程，运行和重新启动。

 使用 
控制组（cgroup）是一组受相同条件约束的进程，并与一组参数或限制相关联。这些组可以是层次结构的，意味着每个组都从其父组继承限制。

内核通过cgroup接口提供对多个控制器（也称为子系统）的访问；例如，“memory”控制器限制内存使用，“cpuacct”记录CPU使用情况等。

控制组可以通过多种方式使用：

 手动读写 cgroup 的虚拟文件系统。
 使用 cgcreate 、 cgexec 和 cgclassify （来自 libcgroup ）等工具，即时创建和管理群组。
 通过“规则引擎守护程序”，可以根据配置自动将特定用户、组或命令的进程移动到cgroups中。
 间接通过使用 cgroups 的其他软件，如Docker、Firejail、LXC、libvirt、systemd、Open Grid Scheduler/Grid Engine，以及Google已停止开发的lmctfy。

Linux 内核文档包含了控制组版本1（cgroup v1）和版本2（cgroup v2）的一些设置和使用的技术细节。

也可以使用  systemd-cgtop  命令按资源使用情况显示顶级控制组。

 重新设计 
cgroups的重新设计始于2013年，随后在Linux内核的3.15和3.16版本中引入了额外的改变。

 命名空间隔离 

虽然不是cgroups工作的技术部分，但Linux内核的一个相关特性是命名空间隔离，它将一组进程分离开来，使它们无法“看到”其他组中的资源。例如，PID命名空间在每个命名空间中提供了一个独立的进程标识符枚举。还有可用的挂载、用户、UTS、网络和SysV IPC命名空间。

 PID namespace (PID命名空间)  提供了进程标识符（PID）、进程列表及其详细信息的分离。虽然新的命名空间与其他同级命名空间隔离，但其“父”命名空间中的进程仍然可以看到子命名空间中的所有进程，尽管PID号码不同。
 Network namespace (网络命名空间)  隔离了（物理或虚拟的）网络接口控制器、iptables防火墙规则、路由表等。网络命名空间可以使用"veth"虚拟以太网设备连接在一起。
 "UTS" namespace 允许更改主机名。
 Mount namespace 允许创建不同的文件系统布局，或将某些挂载点设置为只读。
 IPC namespace 隔离了命名空间之间的System V进程间通信。
 User namespace 在命名空间之间隔离用户ID。
 Cgroup namespace 

命名空间是通过"unshare"命令或系统调用创建的，或者作为"clone"系统调用中的"new"标志。

在 cgroups 开发早期，添加了"ns"子系统，以整合命名空间和控制组。如果挂载了"ns"控制组，每个命名空间也会在控制组层次结构中创建一个新的组。这是一个实验，后来被认为与cgroups API不太匹配，并从内核中移除。

Linux的命名空间受到了贝尔实验室九号项目中广泛使用的更通用的命名空间功能的启发。

 统一层次结构（Unified hierarchy） 
Kernfs于2014年3月引入Linux内核，版本为3.14，主要作者是Tejun Heo。一个独立的kernfs的主要动机之一是cgroups文件系统。Kernfs基本上是通过将一些sysfs逻辑拆分为一个独立实体来创建的，从而为其他内核子系统实现自己的虚拟文件系统提供了便利，包括处理设备连接和断开连接、动态创建和删除以及其他属性。重设计继续到Linux内核的3.15版本。

 内核内存控制组（kmemcg） 
内核内存控制组（kmemcg）已合并到Linux内核主线版本3.8（）。kmemcg控制器可以限制内核用于管理其自身内部进程所使用的内存量。

 cgroup对OOM killer的感知 
Linux内核4.19（2018年10月）引入了对实现的cgroup感知，这增加了以cgroup为单位杀死进程的能力，从而保证了工作负载的完整性。

 应用 
各种项目都使用cgroups作为基础，包括CoreOS、Docker（2013年）、Hadoop、Jelastic、Kubernetes、lmctfy（Let Me Contain That For You）、LXC（LinuX Containers）、systemd、Mesos和Mesosphere，以及HTCondor。主要的Linux发行版也采用了它，例如Red Hat Enterprise Linux（RHEL）6.0在2010年11月采用，比主线Linux内核晚三年。

2019年10月29日，Fedora项目将Fedora 31默认修改为使用CgroupsV2。

参见
 实现了操作系统级虚拟化的项目列表
 进程组

 工作对象 - Windows平台的等效概念，由该平台的对象管理器管理。

引用

外部連結
 Linux kernel documentation on cgroups

Category:Linux内核功能
Category:操作系统技术