侧边栏壁纸
  • 累计撰写 32 篇文章
  • 累计创建 55 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

Linux cgroups概述

Testerfans
2022-07-08 / 0 评论 / 24 点赞 / 1,537 阅读 / 3,537 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-07-12,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

将一台主机比喻成一个大家庭,那进程就是家庭成员,主机资源就是这个家庭拥有各种资源,包括虚拟资源(教育、经商机会等)和实体资源(粮食、居住面积等)。在大家庭里这些资源为全体成员共有,如果没有很好的管理方式就很有可能出现资源的争抢和冲突。比如老二不满老大资源占用的多,就会为此大打出手,这样的局面不利于整个家庭的稳定。

为了解决这个问题,大家庭提供了一套资源隔离和控制的机制(namespace和cgroups),可以实现把大家庭(宿主机)划分成小家庭(容器)并实现相互间资源的隔离(namespace)和成员间资源的控制(cgroups),以此避免因资源争抢导致的不稳定局面。但所有小家庭和小家庭的各种信息还需要在大家庭登记造册,以便大家庭对小家庭进行管理。

前面的文章我们了解Linux通过 namespace技术实现了uts、pid、user等资源隔离,那如何解决cpu、内存、网络等资源的控制和隔离呢?Linux已经提供了一种解决方案—cgroups,这也是我们今天要了解的内容。

cgroups简介

cgroups(控制组)是control groups的缩写。cgroups是Linux内核提供用来限制、统计和隔离一组进程资源(CPU, memory, disk I/O, network等)的功能。

Google工程师Paul Menage 和 Rohit Seth在2006年就开始研发这个功能,当时叫做"process container"。在2007年底,google为了避免和"container"一词上的含义冲突,将"process container"改名为"control groups"。

同年control groups功能被合并入Linux kernel 2.6.24主干,于2008年1月发布。后来工程师们又陆续加入了很多其他功能,比如2014年对kernfs的支持、firewalling和unified hierarchy。cgroups v2在Linux 4.5被合并进来,v2版本对v1的接口和内部功能都做了重大调整。

cgroups的版本

上面提到,cgroups有两个版本,v1和v2版本。cgroups 最初由 Paul Menage 和 Rohit Seth 编写,并于 2007 年被合并到 Linux 内核中。后来这被称为 cgroups v1版本。

后来Tejun Heo 接管了 cgroups 的开发和维护工作,他重新设计和重写了cgroups,这个版本我们称为v2版本。cgroup-v2 的文档首次出现在 2016 年 3 月 14 日发布的 Linux 内核 4.5 中。

和v1相比,cgroup v2 只有一个进程层次结构,并且只在进程层面进行区别,不再区别线程。

cgroups的作用

cgroups其中的一个设计目标是为了不同的使用场景提供统一的接口,这些场景包括从单个进程的控制到完整的操作系统层的虚拟化。

cgroups提供如下功能:

  • 资源限制
    cgroups 可以对任务是要的资源总额进行限制。比如设定任务运行时使用的内存上限,一旦超出就发 OOM。

  • 优先级分配
    通过分配的 CPU 时间片数量和磁盘 IO 带宽,实际上就等同于控制了任务运行的优先级。

  • 资源统计
    cgoups 可以统计系统的资源使用量,比如 CPU 使用时长、内存用量等。这个功能非常适合当前云端产品按使用量计费的方式。

  • 任务控制
    cgroups 可以对任务执行挂起、恢复等操作。

cgroups的术语

想要深入理解cgroups我们还需要了解cgroups的相关术语和概念,其中包括:task、cgroup、subsystem和hierarchy。

task(任务)

cgroup控制的是一组进程,task就是这组进程内的其中一个进程或者一个线程。

task可以理解成是一个家庭成员,家庭使用cgroup管理的就是一个家庭成员。

在 linux 系统中,内核本身的调度和管理并不对进程和线程进行区分,只是根据 clone 时传入的参数的不同来从概念上区分进程和线程。这里使用 task 来表示系统的一个进程或线程。

cgroup(控制组)

cgroup 表示按某种资源控制标准划分而成的任务组,包含一个或多个子系统。一个任务可以加入某个 cgroup,也可以从某个 cgroup 迁移到另一个 cgroup。

这里可以这样理解:为了实现对部分家庭成员(task—进程或线程)的资源使用限制,大家庭提供了一套统一的资源管理框架,即:cgroups。这个组织可以根据资源种类(subsystem)和标准(资源配置),创建一个资源管控组(cgroup)。家庭成员(task)加到这个组(cgroup)那么就会受到这个资源管控组的管理和控制(control)。这个资源管控组的的所有成员共享这个组里面分配的资源(土地、食物等),如果资源被使用完,那必须有人做出牺牲(如OOM)。

subsystem(子系统)

一个subsystem就是一个内核模块,他被关联到cgroup树之后,就会在树的每个节点(进程组)上做具体的操作。subsystem经常被称作"resource controller",因为它主要被用来调度或者限制每个进程组的资源,但是这个说法不完全准确,因为有时我们将进程分组只是为了做一些监控,观察一下他们的状态,比如perf_event subsystem。

上面的例子介绍了按照资源类型标准一个资源管控组(cgroup),以此来控制部分家庭成员的资源使用。如果我们要让这个组管理一种或多种资源,就需要给这个组赋予一定的能力(或者提供工具),比如:我们要让一个组管理土地资源和食物资源,那我们就要给这个组赋予土地管理和食物管理的能力,这种能力就是我们下面要介绍Linux内的子系统(subsystem),也称之为资源控制器(resource controller)。

这就好比一个资源控制组是管理食物资源的,那我这个组要具备管理食物资源的工具(资源控制器),当一个家庭成员加入进来之后,我就会用这个工具来管理这种资源。

cgroup层级结构(hierarchy)

内核使用 cgroup 结构体来表示一个 control group 对某一个或者某几个 cgroups 子系统的资源限制。cgroup 结构体可以组织成一颗树的形式,每一棵cgroup 结构体组成的树称之为一个 cgroups 层级结构。

cgroups层级结构可以 attach 一个或者几个 cgroups 子系统,当前层级结构可以对其 attach 的 cgroups 子系统进行资源的限制。每一个 cgroups 子系统只能被 attach 到一个 cpu 层级结构中。

一资源控制组可以针对资源控制的标准进行细分,划分成子控制组,依次类推形成孙子控制组,这种层级关系让组之间了一种树形结构(cgroup树),也就是我们说的cgroup的层级结构。对于一个家庭成员只能加入到这棵树中的一个cgroup内,因为同一棵树的不同组表示控制资源类型相同而标准不同,那这个家庭成员到底用哪个标准呢?

cgroups的使用

cgroup 是受相同标准约束并与一组参数或限制相关联的进程的集合。这些组可以是分层的,这意味着每个组都从其父组继承限制。内核通过 cgroup 接口提供对多个控制器(也称为子系统)的访问。例如cpu和内存的使用。

控制组可以多种方式使用方式:

  • 通过手动访问 cgroup 虚拟文件系统,来实现资源标准的修改、进程的资源控制等。
  • 通过使用libcgroup的cgcreate、cgexec 和 cgclassify等工具即时创建和管理组, libcgroup是一个开源的软件,提供一组cgroups的应用程序和库。
  • 通过“规则引擎守护进程”可以自动将某些用户、组或命令的进程移动到其配置中指定的 cgroups。
  • 间接通过使用 cgroup 的其他软件,例如 Docker、Firejail、LXC、libvirt、systemd和Open Grid Scheduler/Grid Engine。

Linux 内核文档包含设置和使用控制组1和v2 的一些技术细节。 systemd-cgtop命令可用于按资源使用情况显示顶级控制组。

总结

cgroups是Linux系统内核提供对一组进行对指定类型资源进行资源控制、监控、调度管理的功能,cgroup可以关联子系统(资源控制器),并按照标准不同创建层级cgroup树形结构,以便对不同的task(进程)按照不同的资源标准进行更好的资源管理和控制。

通过大家庭的案例希望以一种更直观的方式让大家来理解 Linux cgroups。接下来我们将更详细的介绍Linux cgroups相关内容。


本文参考:
cgroups

24

评论区