Cgroups是什么

2023-10-14 08:18
文章标签 cgroups

本文主要是介绍Cgroups是什么,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址:https://www.cnblogs.com/lisperl/archive/2013/01/14/2860353.html

作者:王喆锋 zhefwang@gmail.com(侵删)

 

Cgroups是什么?

Cgroups是control groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:cpu,memory,IO等等)的机制。最初由google的工程师提出,后来被整合进Linux内核。Cgroups也是LXC为实现虚拟化所使用的资源管理手段,可以说没有cgroups就没有LXC。

Cgroups可以做什么?

Cgroups最初的目标是为资源管理提供的一个统一的框架,既整合现有的cpuset等子系统,也为未来开发新的子系统提供接口。现在的cgroups适用于多种应用场景,从单个进程的资源控制,到实现操作系统层次的虚拟化(OS Level Virtualization)。Cgroups提供了一下功能:

  • 1.限制进程组可以使用的资源数量(Resource limiting )。比如:memory子系统可以为进程组设定一个memory使用上限,一旦进程组使用的内存达到限额再申请内存,就会出发OOM(out of memory)。
  • 2.进程组的优先级控制(Prioritization )。比如:可以使用cpu子系统为某个进程组分配特定cpu share。
  • 3.记录进程组使用的资源数量(Accounting )。比如:可以使用cpuacct子系统记录某个进程组使用的cpu时间
  • 4.进程组隔离(isolation)。比如:使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间。
  • 5.进程组控制(control)。比如:使用freezer子系统可以将进程组挂起和恢复。

Cgroups相关概念及其关系

相关概念

  • 1.任务(task)。在cgroups中,任务就是系统的一个进程。
  • 2.控制族群(control group)。控制族群就是一组按照某种标准划分的进程。Cgroups中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用cgroups以控制族群为单位分配的资源,同时受到cgroups以控制族群为单位设定的限制。
  • 3.层级(hierarchy)。控制族群可以组织成hierarchical的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性。 4.子系统(subsytem)。一个子系统就是一个资源控制器,比如cpu子系统就是控制cpu时间分配的一个控制器。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。

相互关系

  • 1.每次在系统中创建新层级时,该系统中的所有任务都是那个层级的默认 cgroup(我们称之为 root cgroup ,此cgroup在创建层级时自动创建,后面在该层级中创建的cgroup都是此cgroup的后代)的初始成员。
  • 2.一个子系统最多只能附加到一个层级。
  • 3.一个层级可以附加多个子系统。
  • 4.一个任务可以是多个cgroup的成员,但是这些cgroup必须在不同的层级。
  • 5.系统中的进程(任务)创建子进程(任务)时,该子任务自动成为其父进程所在 cgroup 的成员。然后可根据需要将该子任务移动到不同的 cgroup 中,但开始时它总是继承其父任务 的cgroup。

Cgroups子系统介绍

  1. blkio -- 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等)。
  2. cpu -- 这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。
  3. cpuacct -- 这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。
  4. cpuset -- 这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。
  5. devices -- 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。
  6. freezer -- 这个子系统挂起或者恢复 cgroup 中的任务。
  7. memory -- 这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。
  8. net_cls -- 这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。
  9. ns -- 名称空间子系统。

Cgroups如何实现

数据结构

我们从进程出发来剖析cgroups相关数据结构之间的关系。 在Linux中,管理进程的数据结构是task_struct,其中与cgroups有关的:

#ifdef CONFIG_CGROUPS/* Control Group info protected by css_set_lock: */struct css_set __rcu		*cgroups;/* cg_list protected by css_set_lock and tsk->alloc_lock: */struct list_head		cg_list;
#endif
#ifdef CONFIG_CGROUPS/* disallow userland-initiated cgroup migration */unsigned			no_cgroup_migration:1;
#endif

其中cgroups指针指向了一个css_set结构,而css_set存储了与进程相关的cgroups信息。cg_list是一个嵌入的list_head结构,用于将连到同一个css_set的进程组织成一个链表。下面我们来看css_set的结构:

/** A css_set is a structure holding pointers to a set of* cgroup_subsys_state objects. This saves space in the task struct* object and speeds up fork()/exit(), since a single inc/dec and a* list_add()/del() can bump the reference count on the entire cgroup* set for a task.*/
struct css_set {/** Set of subsystem states, one for each subsystem. This array is* immutable after creation apart from the init_css_set during* subsystem registration (at boot time).*/struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];/* reference count */refcount_t refcount;/** For a domain cgroup, the following points to self.  If threaded,* to the matching cset of the nearest domain ancestor.  The* dom_cset provides access to the domain cgroup and its csses to* which domain level resource consumptions should be charged.*/struct css_set *dom_cset;/* the default cgroup associated with this css_set */struct cgroup *dfl_cgrp;/* internal task count, protected by css_set_lock */int nr_tasks;/** Lists running through all tasks using this cgroup group.* mg_tasks lists tasks which belong to this cset but are in the* process of being migrated out or in.  Protected by* css_set_rwsem, but, during migration, once tasks are moved to* mg_tasks, it can be read safely while holding cgroup_mutex.*/struct list_head tasks;struct list_head mg_tasks;/* all css_task_iters currently walking this cset */struct list_head task_iters;/** On the default hierarhcy, ->subsys[ssid] may point to a css* attached to an ancestor instead of the cgroup this css_set is* associated with.  The following node is anchored at* ->subsys[ssid]->cgroup->e_csets[ssid] and provides a way to* iterate through all css's attached to a given cgroup.*/struct list_head e_cset_node[CGROUP_SUBSYS_COUNT];/* all threaded csets whose ->dom_cset points to this cset */struct list_head threaded_csets;struct list_head threaded_csets_node;/** List running through all cgroup groups in the same hash* slot. Protected by css_set_lock*/struct hlist_node hlist;/** List of cgrp_cset_links pointing at cgroups referenced from this* css_set.  Protected by css_set_lock.*/struct list_head cgrp_links;/** List of csets participating in the on-going migration either as* source or destination.  Protected by cgroup_mutex.*/struct list_head mg_preload_node;struct list_head mg_node;/** If this cset is acting as the source of migration the following* two fields are set.  mg_src_cgrp and mg_dst_cgrp are* respectively the source and destination cgroups of the on-going* migration.  mg_dst_cset is the destination cset the target tasks* on this cset should be migrated to.  Protected by cgroup_mutex.*/struct cgroup *mg_src_cgrp;struct cgroup *mg_dst_cgrp;struct css_set *mg_dst_cset;/* dead and being drained, ignore for migration */bool dead;/* For RCU-protected deletion */struct rcu_head rcu_head;
};

其中refcount是该css_set的引用数,因为一个css_set可以被多个进程共用,只要这些进程的cgroups信息相同,比如:在所有已创建的层级里面都在同一个cgroup里的进程。 hlist是嵌入的hlist_node,用于把所有css_set组织成一个hash表,这样内核可以快速查找特定的css_set。

tasks指向所有连到此css_set的进程连成的链表。 cg_links指向一个由struct cg_cgroup_link连成的链表。 Subsys是一个指针数组,存储一组指向cgroup_subsys_state的指针。一个cgroup_subsys_state就是进程与一个特定子系统相关的信息。通过这个指针数组,进程就可以获得相应的cgroups控制信息了。 下面我们就来看cgroup_subsys_state的结构:


/** Per-subsystem/per-cgroup state maintained by the system.  This is the* fundamental structural building block that controllers deal with.** Fields marked with "PI:" are public and immutable and may be accessed* directly without synchronization.*/
struct cgroup_subsys_state {/* PI: the cgroup that this css is attached to */struct cgroup *cgroup;/* PI: the cgroup subsystem that this css is attached to */struct cgroup_subsys *ss;/* reference count - access via css_[try]get() and css_put() */struct percpu_ref refcnt;/* siblings list anchored at the parent's ->children */struct list_head sibling;struct list_head children;/* flush target list anchored at cgrp->rstat_css_list */struct list_head rstat_css_node;/** PI: Subsys-unique ID.  0 is unused and root is always 1.  The* matching css can be looked up using css_from_id().*/int id;unsigned int flags;/** Monotonically increasing unique serial number which defines a* uniform order among all csses.  It's guaranteed that all* ->children lists are in the ascending order of ->serial_nr and* used to allow interrupting and resuming iterations.*/u64 serial_nr;/** Incremented by online self and children.  Used to guarantee that* parents are not offlined before their children.*/atomic_t online_cnt;/* percpu_ref killing and RCU release */struct work_struct destroy_work;struct rcu_work destroy_rwork;/** PI: the parent css.	Placed here for cache proximity to following* fields of the containing structure.*/struct cgroup_subsys_state *parent;
};

cgroup指针指向了一个cgroup结构,也就是进程属于的cgroup。进程受到子系统的控制,实际上是通过加入到特定的cgroup实现的,因为cgroup在特定的层级上,而子系统又是附加到曾经上的。通过以上三个结构,进程就可以和cgroup连接起来了:task_struct->css_set->cgroup_subsys_state->cgroup。

下面我们再来看cgroup的结构:


struct cgroup {/* self css with NULL ->ss, points back to this cgroup */struct cgroup_subsys_state self;unsigned long flags;		/* "unsigned long" so bitops work *//** idr allocated in-hierarchy ID.** ID 0 is not used, the ID of the root cgroup is always 1, and a* new cgroup will be assigned with a smallest available ID.** Allocating/Removing ID must be protected by cgroup_mutex.*/int id;/** The depth this cgroup is at.  The root is at depth zero and each* step down the hierarchy increments the level.  This along with* ancestor_ids[] can determine whether a given cgroup is a* descendant of another without traversing the hierarchy.*/int level;/* Maximum allowed descent tree depth */int max_depth;/** Keep track of total numbers of visible and dying descent cgroups.* Dying cgroups are cgroups which were deleted by a user,* but are still existing because someone else is holding a reference.* max_descendants is a maximum allowed number of descent cgroups.*/int nr_descendants;int nr_dying_descendants;int max_descendants;/** Each non-empty css_set associated with this cgroup contributes* one to nr_populated_csets.  The counter is zero iff this cgroup* doesn't have any tasks.** All children which have non-zero nr_populated_csets and/or* nr_populated_children of their own contribute one to either* nr_populated_domain_children or nr_populated_threaded_children* depending on their type.  Each counter is zero iff all cgroups* of the type in the subtree proper don't have any tasks.*/int nr_populated_csets;int nr_populated_domain_children;int nr_populated_threaded_children;int nr_threaded_children;	/* # of live threaded child cgroups */struct kernfs_node *kn;		/* cgroup kernfs entry */struct cgroup_file procs_file;	/* handle for "cgroup.procs" */struct cgroup_file events_file;	/* handle for "cgroup.events" *//** The bitmask of subsystems enabled on the child cgroups.* ->subtree_control is the one configured through* "cgroup.subtree_control" while ->child_ss_mask is the effective* one which may have more subsystems enabled.  Controller knobs* are made available iff it's enabled in ->subtree_control.*/u16 subtree_control;u16 subtree_ss_mask;u16 old_subtree_control;u16 old_subtree_ss_mask;/* Private pointers for each registered subsystem */struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT];struct cgroup_root *root;/** List of cgrp_cset_links pointing at css_sets with tasks in this* cgroup.  Protected by css_set_lock.*/struct list_head cset_links;/** On the default hierarchy, a css_set for a cgroup with some* susbsys disabled will point to css's which are associated with* the closest ancestor which has the subsys enabled.  The* following lists all css_sets which point to this cgroup's css* for the given subsystem.*/struct list_head e_csets[CGROUP_SUBSYS_COUNT];/** If !threaded, self.  If threaded, it points to the nearest* domain ancestor.  Inside a threaded subtree, cgroups are exempt* from process granularity and no-internal-task constraint.* Domain level resource consumptions which aren't tied to a* specific task are charged to the dom_cgrp.*/struct cgroup *dom_cgrp;struct cgroup *old_dom_cgrp;		/* used while enabling threaded *//* per-cpu recursive resource statistics */struct cgroup_rstat_cpu __percpu *rstat_cpu;struct list_head rstat_css_list;/* cgroup basic resource statistics */struct cgroup_base_stat pending_bstat;	/* pending from children */struct cgroup_base_stat bstat;struct prev_cputime prev_cputime;	/* for printing out cputime *//** list of pidlists, up to two for each namespace (one for procs, one* for tasks); created on demand.*/struct list_head pidlists;struct mutex pidlist_mutex;/* used to wait for offlining of csses */wait_queue_head_t offline_waitq;/* used to schedule release agent */struct work_struct release_agent_work;/* used to track pressure stalls */struct psi_group psi;/* used to store eBPF programs */struct cgroup_bpf bpf;/* If there is block congestion on this cgroup. */atomic_t congestion_count;/* ids of the ancestors at each level including self */int ancestor_ids[];
};

sibling,children和parent三个嵌入的list_head负责将同一层级的cgroup连接成一颗cgroup树。 subsys是一个指针数组,存储一组指向cgroup_subsys_state的指针。这组指针指向了此cgroup跟各个子系统相关的信息,这个跟css_set中的道理是一样的。
root指向了一个cgroupfs_root的结构,就是cgroup所在的层级对应的结构体。这样以来,之前谈到的几个cgroups概念就全部联系起来了。 top_cgroup指向了所在层级的根cgroup,也就是创建层级时自动创建的那个cgroup。 css_set指向一个由struct cg_cgroup_link连成的链表,跟css_set中cg_links一样。
下面我们来分析一个css_set和cgroup之间的关系。我们先看一下 cg_cgroup_link的结构

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

这篇关于Cgroups是什么的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/209265

相关文章

Kubernetes Kubelet 的 Cgroups 资源限制机制分析

前言 容器技术的两大技术基石,想必大家都有所了解,即 namespace 和 cgroups。但你知道 cgroups 是如何在 kubernetes 中发挥作用的吗?kubelet 都设置了哪些 cgroups 参数来实现对容器的资源限制的呢?本文就来扒一扒 Kubernetes kubelet 的 cgroups 资源限制机制。 层级化的资源限制方式 kubelet 基于 cgroups

Docker技术原理之Linux Cgroups(资源限制)

0.前言 首先要知道一个运行的容器,其实就是一个受到隔离和资源限制的Linux进程——对,它就是一个进程。前面我们讨论了Docker容器实现隔离用到的技术Linux namespace,本篇我们来讨论容器实现资源限制的技术 Linux CGroups。 1.关于Linux CGroups Linux Cgroups的全称是Linux Control Groups。它最主要的作用,就是限制一个

Introduction to Cgroups, the Linux Control Group

http://linuxaria.com/article/introduction-to-cgroups-the-linux-conrol-group?lang=en Cgroups is present in the official Linux kernel 2.6.24 (late 2007), still he’s not much know or used (at least for

Cgroups定义及验证

sudo lsb_release -a可以看到操作系统版本是20.04,sudo uname -r可以看到内核版本是5.4.0-156-generic。 Linux Cgroups 的全称是 Linux Control Group。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。 sudo mount -t cgroup展示Cgroups给用户暴

Docker学习(一):linux中的cgroups

在我职业生涯中第一个大项目做完之后(基于solaris的),我终于有点时间可以充充电,学习一些别的知识了。  近几年随着虚拟化技术的发展,各种云计算,open stack等术语几乎霸占各个IT网站的首页。我平时只是跟着了解,并没有做太深入的跟进。借着这个机会,也是该进场了。但毕竟相关技术太多,我也只能寻找一个突破点,从点到线,从线到面地把整个知识网编织起来了。纵观各大网站,最近讨论最热的莫过于d

【Docker 内核详解】cgroups 资源限制(二):组织结构与基本规则、子系统简介

cgroups 资源限制(二):组织结构与基本规则、子系统简介 1.组织结构与基本规则2.子系统简介 1.组织结构与基本规则 在之前的博客已经介绍过,传统的 Unix 任务管理,实际上是先启动 init 任务作为根节点,再由 init 节点创建子任务作为子节点,而每个子节点又可以创建新的子节点,如此往复,形成一个树状结构。而系统中的多个 cgroup 也构成类似的树状结构,子

【Docker 内核详解】cgroups 资源限制(三):实现方式及工作原理简介

实现方式及工作原理简介 1.cgroups 如何判断资源超限及超出限额之后的措施2.cgroup 与任务之间的关联关系3.Docker 在使用 cgroup 时的注意事项4./sys/fs/cgroup/cpu/docker/[container-ID] 下文件的作用 在对 cgroups 规则和子系统有了一定了解以后,下面简单介绍操作系统内核级别上 cgroups 的工作原理

【Docker 内核详解】cgroups 资源限制(一):概念、作用、术语

cgroups 资源限制(一):概念、作用、术语 1.cgroups 是什么2.cgroups 的作用3.cgroups 术语表 当谈论 Docker 时,常常会聊到 Docker 的实现方式。很多开发者都知道,Docker 容器本质上是宿主机上的进程(容器所在的运行环境统一称为宿主机)。Docker 通过 namespace 实现了 资源隔离,通过 cgroups 实现了 资

Linux Cgroups - freezer子系统

http://www.cnblogs.com/lisperl/archive/2012/04/25/2469587.html

27. Cgroups, 深入了解Kubernetes 的资源管理

注意:这是中文翻译稿,借助星火大模型直接翻译。参考价值还是有的,所以翻译出来供参考。 在本文中,我们将深入探讨 cgroups 是什么、Kubernetes 如何使用它们来管理 Node 资源,以及我们如何在 Pod 上设置资源请求和限制之外利用它们。 什么是Cgroups 首先是最重要的 - Cgroups 到底是什么? - Cgroups,或简称为 cgroups,是 Linux 内核的