你的位置:首页 > 操作系统

[操作系统]Cgroup学习笔记


  cgroups 系统是 Linux 内核提供的一个基于进程组的资源管理的框架,可以为特定的进程组限定可以使用的资源。其具体介绍可以参考周明耀先生的CGroup 例及原理描述1,该文详细讲述了cgroup的概念、结构、原理,并给出了应用实例,是不可多得的精品级入门文档,因此建议移步学习,其内容在此也不作复述。

  本文主要解答对cgroup的认知和运用上的一些常见问题。

 

1. namespace与hierarchy、cgroup是什么关系,容器=层级?

  为了更好的理解他们的关系,我们先看一下曹江华先生的Linux 容器的建立和简单管理2中对cgroup子系统的介绍,其中提到了这样一个子系统——ns:

  ns 子系统提供了一个将进程分组到不同名称空间的方法。在具体名称空间中,进程可彼此互动,但会与在其它名称空间中运行的进程隔绝。这些分开的名称空间在用于操作系统级别的虚拟化时,有时也称之为容器。

  可见,容器和层级并没有直接的关系,容器在cgroup系统中只是作为一个子系统(资源管理器)为hierarchy中的进程划分命名空间,将之隔离开来。

  值得一提的是,提到ns子系统的文章都是2013年之前的,这是因为在2013年linux内核中的cgroup功能做了很多改动,直接把ns子系统剔除了。参考Wiki中提到的:

Redesign of cgroups started in 2013, with additional changes brought by versions 3.15 and 3.16 of the Linux kernel.……The "ns" subsystem was added early in cgroups development to integrate namespaces and control groups. If the "ns" cgroup was mounted, each namespace would also create a new group in the cgroup hierarchy. This was an experiment that was later judged to be a poor fit for the cgroups API, and removed from the kernel.

  为什么要剔除ns子系统呢?笔者的理解是这样的,用过cgroup的人会清楚,cgroup就是对系统资源进行分配,而容器不仅对进程使用的资源做隔离,还要禁止不同容器间进程的通信,这超出了cgroup的职责范围,使其功能变得更加复杂和紊乱。因此,容器不再由cgroup管理,而是交由其他技术实现了。

 

2. cgroup有没有ID?单个cgroup可在不同hierarchy中重复吗?

  cgroup没有ID,不过有指向hierarchy(结构体)的指针和指向top-cgroup的指针,还包含有分别组织起兄弟cgroup和子cgroup的链表的表头,因此每个cgroup在系统中都是唯一的。

  Hierarchy本质上是文件系统中的一个目录结构,cgroup在hierarchy中是以目录的形式存在的,不同的hierarchy中的cgroup均是不同的目录,目录中包含的是该cgroup和该hierarchy子系统的一系列配置文件,以及子cgroup。

 

3. hierarchy与subsystem的关系

  hierarchy可有多个不同的subsystem依附,如cpu、memory同时依附;一个subsystem只能依附一个hierarchy,但如果第二个hierarchy没有其他subsystem,那么就可以依附,如可同时存在两个仅有cpu依附的hierarchy。详细规则可参考Red Hat Enterprise Linux 6 Resource Management Guide3中的Relationships Between Subsystems, Hierarchies, Control Groups and Tasks一节。

 

4.root-cgroup是否包含hierarchy中所有进程?

  不是,同一hierarchy内每个cgroup的进程都不会出现在其他cgroup中。

  root-cgroup默认的设定是,系统一旦有新的进程出现,即刻会被root-cgroup包含进去(子进程未做测试)。某个cgroup管理的进程可在其目录下的tasks文件中查看,操作进程加入cgroup也仅需将pid添加进该文件中。

*注:一旦把一个进程放进某个cgroup,不把它移到其他cgroup是不会离开该cgroup的;而只要加入到其他cgroup,原cgroup将会自动释放该进程。

 

5.子cgroup能否继承父cgroup资源配置?

  会自动继承,因为子cgroup的资源配置不能超出父cgroup的限定范围。正如Ubuntu Document中提到:

In general, the kernel enforces the hierarchical constraints on limits, so that for instance if devices cgroup /child1 cannot access a disk drive, then/child1/child2 cannot give itself those rights.

  而在父cgroup的限定下,子cgroup的资源配置相互之间可以相同。

 

6.如果给多个cgroup分配的资源有重叠会怎样?譬如说给A分配了50%的资源,给B分配了100%的资源,它们会如何竞争?

  这里给出笔者针对CPU资源的实验结果:假设A需要使用10%的资源,B需要用80%的资源,那么当限制A使用50%的资源的时候,B是能用80%的;但A需要使用80%的资源的话,那么限定A使用50%的时候,A和B运行时都使用50%的资源。

  可见,cgroup的功能是限定资源,而不是划分资源。

  操作cgroup的命令和子系统配置文件的功能可以参考how to use cgroup【4】

 

7.如何在更改容器状态后快速切换资源的分配?

  修改该容器对应cgroup的配置文件。

 

8.为什么每个cgroup里都会自动创建一个user目录?- Ubuntu 14.04

  参考help.ubuntu.com中的解释:

As of Ubuntu 14.04 (Linux Kernel 3.16), users are automatically placed in a set of cgroups which they own, safely allowing them to constrain their own jobs using child cgroups. This feature is relied upon, for instance, for unprivileged container creation in lxc.

 

 

参考资料

【1】CGroup 介绍、应用实例及原理描述. http://www.ibm.com/developerworks/cn/linux/1506_cgroup/index.html

【2】Linux 容器的建立和简单管理. https://www.ibm.com/developerworks/cn/linux/1312_caojh_linuxlxc/

【3】Red Hat Enterprise Linux 6 Resource Management Guide. https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/index.html

【4】how to use cgroup. http://tiewei.github.io/devops/howto-use-cgroup/

【5】CGROUPS. https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt

【6】wiki/Cgroups. https://en.wikipedia.org/wiki/Cgroups

【7】All About the Linux Kernel: Cgroup’s Redesign. http://www.linux.com/news/featured-blogs/200-libby-clark/733595-all-about-the-linux-kernel-cgroups-redesign

【8】Ubuntu Document. https://help.ubuntu.com/lts/serverguide/cgroups-delegation.html