Docker核心原理解读-cgroups

cgroups

1.control groups,能够根据需求把一系列系统任务整合到按资源划分等级的不一样组里(能够限制、记录任务组所使用的物理资源,CPU、Memory、IO等)。它不只能够限制被namespace隔离起来的资源,还能够为资源设置权重、计算使用量、操控任务(进程或线程)启停等。本质上来讲,cgroups是内核附加在程序上的一系列钩子,经过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。

2.特色:
  • cgroup的api是以一个为文件系统的方式实现,用户态的程序能够经过文件操做实现cgroup的组织管理
  • 组织管理操做单元能够细粒度到线程级别,能够建立和销毁cgroup从而实现资源再分配和管理
  • 全部资源管理的功能都以子系统的方式实现,接口统一
  • 子任务建立之初与父任务处于同一个cgroups控制组

3.cgroups提供四大功能:
  • 资源限制(Resource Limitation):cgroups能够对任务使用的资源总额进行限制。如设定应用运行时使用内存的上限,一旦超过这个配额就发出OOM(Out of Memory)。
  • 优先级分配(Prioritization):经过分配的CPU时间片数量及硬盘IO带宽大小,实际上就至关于控制了进程运行的优先级。
  • 资源统计(Accounting): cgroups能够统计系统的资源使用量,如CPU使用时长、内存用量等等,这个功能很是适用于计费。
  • 进程控制(Control):cgroups能够对进程组执行挂起、恢复等操做。
4.cgroups术语表
  • task(任务):cgroups的术语中,task就表示系统的一个进程或线程。
  • cgroup(控制组):cgroups 中的资源控制都以cgroup为单位实现。cgroup表示按某种资源控制标准划分而成的任务组,包含一个或多个子系统。一个任务能够加入某个cgroup,也能够从某个cgroup迁移到另一个cgroup。
  • subsystem(子系统):cgroups中的subsystem就是一个资源调度控制器(Resource Controller)。好比CPU子系统能够控制CPU时间分配,内存子系统能够限制cgroup内存使用量。
  • hierarchy(层级树):hierarchy由一系列cgroup以一个树状结构排列而成,每一个hierarchy经过绑定对应的subsystem进行资源调度。hierarchy中的cgroup节点能够包含零或多个子节点,子节点继承父节点的属性。整个系统能够有多个hierarchy。
5.cgroups、任务、子系统、层级之间的关系和基本规则:
  • 规则1:同一个层级能够附加一个或多个子系统
  • 一个子系统能够附加到多个层级,当且仅当目标层级只有惟一一个子系统时。图中小圈中的数字表示子系统附加的时间顺序,CPU子系统附加到层级A的同时不能再附加到层级B,由于层级B已经附加了内存子系统。
  • 系统每次新建一个层级时,该系统上的全部任务默认加入这个新建层级的初始化cgroup,这个sgroup也就是root cgroup。对于建立的每一个层级,任务只能存在于其中一个cgroup中任务只能存在于其中一个cgroup中,即一个任务不能存在于同一个层级的不一样cgroup中,但一个任务能够存在于不一样层级中的多个cgroup中。若是操做时把一个任务添加到同一个层级的另外一个cgroup中,则会将它从第一个cgroup中移除。
  • 任务在fork/clone自身时建立的子任务默认与原任务在同一个cgroup中,可是子任务容许被移动到不一样的cgroup中。即fork/clone完成后,父子任务间在cgroup方面是互不影响的。
6.子系统简介
实际上就是cgroups的资源控制系统,每种子系统独立的控制一种资源,目前Docker使用以下9种子系统,具体以下:
  • blkio:为块设备设定输入/输出限制,好比物理驱动设备(包括磁盘、固态硬盘、USB等)。
  • cpu:使用调度程序控制任务对CPU的使用。
  • cpuacct:自动生成cgroup中任务对CPU资源使用状况的报告。
  • cpuset:能够为cgroup中的任务分配独立的CPU和内存。
  • devices:能够开启或关闭cgroup中任务对设备的访问。
  • freezer:能够挂起或恢复cgroup中的任务。
  • memory:能够设定cgroup中任务对内存使用量的限定,而且自动生成这些任务对内存资源使用状况的报告。
  • perfevent:使用后使得cgroup中的任务能够进行统一的性能测试。
  • net_cls:Docker没有直接使用,它经过使用等级识别符(classid)标记网络数据包,从而容许Linux流量控制程序(TC:Traffic Controller)识别从具体cgroup中生成的数据包。 
7.cgroups的实现本质上是给任务挂上钩子,当任务运行的过程当中涉及某种资源时,就会触发钩子上所附带的子系统进行检测,而后根据资源类别的不一样使用对应的技术进行资源限制和优先级分配。
  • 判断资源超出限额:对于不一样的系统资源,cgroups提供了统一的接口对资源进行控制和统计,但限制的具体方式则不尽相同。如memory子系统,会在描述内存状态的“mm_struct”结构体中记录它所属的cgroup,当进程须要申请更多内存时,就会触发cgroup用量检测,用量超过cgroup规定的限额,则拒绝用户的内存申请,不然就给予相应内存并在cgroup的统计信息中记录。
  • 实现上,cgroup与任务之间是多对多的关系,所以它们并不直接关联,而是经过一个中间结构把双向的关联信息记录起来。每一个任务结构体task_struct都包含了一个指针,能够查询到对应cgroup的状况,同时也能够查询到各个子系统的状态,这些子系统状态中也包含了找到任务的指针,不一样类型的子系统按需定义自己的控制信息结构体,最终在自定义的结构体中把子系统状态指针包含进去,而后内核经过container_of等宏定义来获取对应的结构体,关联到任务,以此达到资源限制的目的。 
相关文章
相关标签/搜索