Cgroup概述

article/2025/10/14 11:01:31

一、Cgroup的目的    

    Cgroup和namespa类似,也是将进程进程分组,但是目的与namespace不一样,namespace是为了隔离进程组之前的资源,而Cgroup是为了对一组进程进行统一的资源监控和限制。

二、为什么需要Cgroup

    在Linux里,对进程进程分组,比如Session group、process group等,后来需要追踪一组进程的内存和IO使用情况,出现了cgroup,用来统一对进程进行分组,并在分组的基础上对进程进程监控和资源控制管理等。

三、Cgroup中名词概念

任务(Task)在Cgroup中,任务就是系统的一个进程
控制族群(control group)控制族群就是按照一组某种标准划分的进程。Cgroup中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也可以从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用cgroups以控制族群为单位分配资源,同时受到cgroups以控制族群为单位设定限制。
层级(hierachy)控制族群可以组织成hierarchical的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定属性
子系统(subsystem)一个子系统就是一个资源控制器

    Cgroup可以指整个cgrop技术,也可以指一个具体的进程组。

    Cgroup是Linux下一种将进程按组管理的机制,在用户层面看,Cgroup技术就是可以把系统中的所有进程组织成一颗独立的树,每颗树都包含系统所有进程,树的每个节点就是一个进程组,而每颗树又和一个或者多个subsystem关联,树的作用是对进程分组,而subsystem作用是对这些组进行操作。

  • subsystem:一个subsystem就是一个内核模块,它被关联到一颗Cgroup树之后,就会对树的每个节点(进程组)上做具体操作。subsystem也被称为resource controller,因为它主要用来调度和限制每个进程组资源,有时也可以将进程分组只是为了做监控,观察进程组的状态。例如,perf_event subsystem。目前Linux支持12中system,比如限制CPU的使用时间,限制使用内存,统计CPU使用情况,冻结和恢复一组进程等。
  • 下面每个子系统都需要与内核的其它模块配合来完成资源控制,比如对CPU资源的限制是通过进程调度模块根据CPU子系统的配置来完成;对内存资源的限制是内存模块根据memoty子系统的配置来完成,对网络数据包的控制则需要Traffic Control子系统配合完成。
    subsystem作用
    cpu主要限制进程CPU使用率
    cpuacct统计cgroups中进程的cpu使用率
    cpuset为cgroups中进程分配单独的CPU节点(多核)或内存节点
    blkio限制进程的块设备IO
    memory限制进程的memory使用量
    devices可以控制进程能够访问某些设备
    freezer挂起或者恢复cgrops中进程
    net_cls可以标记cgroups中进程的网络数据包,然后可以使用tc(traffic control)对数据包进程控制
    ns可以使不同cgroups下面的进程使用不同的namespace

四、cgroups层级结构(Hierachy)

    内核使用cgroup结构体表示一个control group对某一个或者某几个cgroups子系统的资源限制。cgroup结构体可以组成一棵树,每一颗cgroup结构体组成的的树称为cgroup层级结构。cgroups层级结构可以attach一个或几个cgroups子系统,当前层级结构可以对其attach的cgroups子系统进行资源限制。每一个cgroups子系统只能被attach到一个cpu层级结构中

  上图表示两个cgroups层级结构,每一个层级结构中是一颗树形结构,树的每一个节点是一个cgroups结构体(比如cpu_cgrp,memory_cgrp)。第一个cgroups层级结构attach了cpu子系统和cpuacct子系统,当前

cgroups层级结构中的cgroups层级结构中的cgroup结构体就可以对cpu资源进进行限制,并且对进程的cpu使用情况进行统计。

    第二个cgroups层级结构中attach了memory子系统,当前cgroups层级结构中的cgroup结构体就可以对memory的资源进行限制。在每一个cgroups层级结构中,每一个节点(cgroup结构体)可以设置对资源不同的限制权重。比如上图中cgrp1组中的进程可以使用60%cpu时间片,而cgrp2组中的进程可以使用20%的cpu时间片。

 

 cgroup层级关系显示,CPU和Memory两个子系统有自己独立的层级系统而又通过Task group取得关联关系

相互关系:

每次在系统中创建新层级时,该系统中所有任务都是那个层级默认cgroup(root cgroup,此cgoup在创建层级时自动创建,后面在该层级中创建的cgroup都是此cgroup的后代)的初始成员;

  • 同一个hierarchy可以附加到一个或者多个subsystem
  • 一个subsystem可以附加到多个hierarchy,当且仅当这个hierarchy只有这一个subsystem,如下图,hierarchy B已经有了一个subsystem Memory,所以hierarchy不能attach到CPU这个subsystem中

 

  • 同一个task不能属于同一个hierarchy的不同的cgroup:
  • fork出的子进程在初始化状态与其父进程处于同一个cgroup。进程(task)在fork出自身时创建子任务(child task)默认与原task在同一个cgroup,但之后这个子任务可以被移动到其它cgroup中去,可以理解为这个子任务是一个独立的进程:

五、cgroups与进程

  在创建了cgroups层级结构中的节点(cgroup结构体)之后,可以把进程加入到某个节点的控制任务列表中,一个节点的控制列表中的所有进程都会受到当前节点的资源限制、同时一个进程也可以被加入到不同的cgroups层级结构的节点中,因为不同的cgroups层级结构可以负责不同的系统资源。所以说进程和cgroup结构是一个多对多的关系。

    上图从总体结构描述了进程与cgroups之间的关系。最下面的P代表一个进程。每个进程的描述符中有一个指针指向一个辅助的数据结构css_set(cgroup subsystem set)。指向某一个 css_set的进程会被加入到当前的css_set的进程链表中。一个进程只能隶属一个css_set,一个css_set可以包含多个进程,隶属于同一css_set的进程受同一个css_set所管理的资源限制。

   “MXN Linkage”说明css_set通过辅助的数据结构可以与cgroups节点进行多对多的关联。但是cgroup实现不允许css_set同时关联同一个cgroup层级结构下的多个节点。这是因为cgroups对同一种资源不运行有多个限额配置。 

    一个ccs_set关联多个cgroups层级结构的节点时,表明需要对当前css_set下的进程进行多种资源控制。而一个cgroups节点关联多个css_set时,表面多个css_set下的进行列表受到同一份资源的相同限制。

六、cgroups文件系统

    Linux使用多种数据结构在内核中实现了cgroups的配置,关联了进程和cgroups节点,那么Linux如何让用户态的进程使用到cgroups的功能呢?

    Linux内核有一个很强大的模块VFS(Virtual File System)。VFS能够把具体文件系统的细节隐藏起来,给用户态进程提供一个统一的文件系统API接口。cgroups也是通过VFS把功能暴露给用户态,cgroups与VFS衔接部分称为cgroups文件系统。

    VFS:

     VFS是一个内核抽象层,能够隐藏具体文件系统实现细节,从而给用户态提供一整套统一的API接口。VFS使用了一种通用文件系统的设计,具体的文件系统只要实现VFS的设计接口,就能够注册到VFS中,从而使内核可以读写这种文件系统。这很像面向对象设计中抽象类和子类之间的关系,抽象类负责对外接口的设计,子类负责具体的实现。其实,VFS本身就是用c语言实现的一套面向对象的接口。

    VFS通用文件模型中包含以下四种元数据结构:

    1. 超级块对象(superblock object) ,用于存放已经注册的文件系统信息。比如ext2,ext3等这些基础的磁盘文件系统,还用于读写socket的socket文件系统,以及当前用于读写cgroups文件系统等。

    2. 索引节点对象(inode object),用于存放具体文件的信息。对于一般的磁盘文件系统而言,inode节点中一般会存放文件在硬盘中的存储块信息;对于socket文件系统,inode会存放socket的相关属性,而对于cgoups这样的特殊文件系统,inode会存放与cgroup节点相关的属性信息。这里比较重要的一部分叫做inode_operations的结构体,这个结构体定义了在具体文件系统中创建文件,删除文件等具体操作。

   3. 文件对象(file object),一个文件对象表示一个进程打开的一个文件,文件对象是存放在进程文件描述符表里面的。同样这个文件中比较重要的部分是file_operations的结构体,这个结构体描述了具体的文件系统读写实现。当进程在某一个文件描述符上调用读写操作时,实际调用的时file_operations中定义的方法。对于普通的磁盘文件系统,file_operations中定义的就是普通块设备读写操作;对于socket文件系统,file_operations中定义的就是socket对应的send/recv等操作;而对于cgroups这样特殊的文件系统,file_operations中定义的就是操作cgroup结构体等具体实现。

4. 目录项对象(dentry object):在每个文件系统中,内核在查找一个路径的文件时,会为内核路径上的每一个分量都生成一个目录项对象,通过目录项对象找到对应的indode对象,目录项对象一般会被缓存,从而提供内核查找速度。

基于VFS实现的文件系统,都必须实现VFS通用文件模型定义这些对象,并实现这些对象中定义的部分函数。cgroup文件系统也不例外:

static struct file_system_type cgroup_fs_type = {.name = "cgroup",.mount = cgroup_mount,       //安装cgroup文件系统要执行的函数.kill_sb = cgroup_kill_sb,  //卸载cgroup文件系统要执行的函数
}

 

   每次把一个cgroups子系统安装到某个转载点时,cgroup_mount方法都会被调用,这个方法生成一个cgroup_root(cgroup层级结构的根)并封装成超级块对象。

    cgroups超级块对象定义的操作:

static file_system_type cgroup_fs_type = {.statfs = simple_statfs,.drop_inode = generic_delelte_inode,.show_option = cgroup_show_options,.remount_fd = cgroup_remount,
}

 cgroups文件系统对inode对象和file对象定义的特殊实现:

static const struct inode_operations cgroup_dir_inode_operations = {.lookup = cgroup_lookup,.mkdir = cgroup_mkdir,.rmdir = cgroup_rmdir,.rename = cgroup_rename,
};static const struct file_operations cgroup_file_operations = {.read = cgroup_file_read,.write = cgroup_file_write,.llseek = generic_file_llseek,.open = cgroup_file_open,.release = cgroup_file_release,
};

 

    cgroups通过实现VFS的通用文件系统模型,把cgroups层级结构的细节,隐藏在cgroups文件系统的这些实现函数中。从令一个方面说,用户在用户态对cgroups文件系统的操作,通过VFS转化为对cgroups层级结构的维护。通过这样的方式,内核把cgroups的功能暴露给用户态进程。

七、cgroups使用方法

#################cgroups文件系统挂载###########################

Linux用户使用mount命令挂载cgroup文件系统,

mount -t cgroup -o subsystems name /cgroup/name  #其中subsystems表示要挂载的cgroups子系统, /cgroup/name表示挂载点,这条命令同时在内核中创建了一个cgroups层级结构

 比如挂载cpu_set,cpu, cpuacct,memory 4个subsystem到cgroup/cpu_and_mem目录下,

mount -t cgroup -o remount, cpu,cpuset, cpu_acct,memory cpu_and mem /cgroup/cup_and_mem

在centos下,使用yum install libcgroup安装了cgroups模块之后,在/etc/cgfong.conf文件中自动生成cgroups子系统的挂载点:

mount {cpuset  = /cgroup/cpuset;cpu = /cgroup/cpu;cpuacct = /cgroup/cpuacct;memory  = /cgroup/memory;devices = /cgroup/devices;freezer = /cgroup/freezer;net_cls = /cgroup/net_cls;blkio   = /cgroup/blkio;
}

上面的每一条配置都等于展开的mount命令,例如

mount -t cgroup -o cpuset cpuset /cgroup/cpuset  #这样系统启动之后会自动把这些子系统挂载到相应的挂载点

#########子节点和进程############

    挂载某个cgroups子系统到挂载点后,就可以通过在挂载点下面建立文件夹或者使用cgcreate命令创建cgroups层级结构中的节点,比如通过命令

cgcreate -t sankkuai:sankuai -g cpu: test #就可以在cpu子系统下面建立一个名为test节点
[root@idx cpu]# ls
cgroup.event_control  cgroup.procs  cpu.cfs_period_us  cpu.cfs_quota_us  cpu.rt_period_us   cpu.rt_runtime_us  cpu.shares  cpu.stat  lxc  notify_on_release  release_agent  tasks  test

  然后可以通过写入需要的值到test下面不同文件,来配置需要限制的资源。每个子系统下面都可以进行多种不同的配置,需要配置的参数各不相同,详细的参数配置参考cgroups手册。可以使用cgset命令设置cgroups子系统参数,格式为

cgset -r parameter=value path_to_cgroup

  当删除某一个cgroup节点时候,可以使用cgdelete命令,比如要删除test节点,

cgdelete -r cpu:test #删除test节点

 把进程加入到cgroups子节点有很多方法,可以把pid写入到子节点下面的task文件中,也可以通过cgclassify添加进程

cgclassify -g subsystem:path_to_cgroup pidlist

   也可以直接使用cgexec在某个cgroups下启动进程

cgexec -g subsystem:path_to_cgoup command aguments

八、cgroups实践

   Docker在实现不同的Container之间资源隔离和控制的时候,可以创建复杂的cgroups节点和配置文件完成,对于同一个Container中的进程,可以把这些进程的PID添加到同一组cgroups子节点中达到对这些进程进行同样的资源限制。

九、cgroups优点

    1. 在cgroups引入内核之前,想要完成对某一个进程CPU使用率进行限制,只能通过nice命令调整进程的优先级,或者cpulimit命令限制进程使用进程的CPU使用率,缺点是无法限制一个进程组的资源使用限制,也无法完成Docker或者其它云平台所需的这一类轻型容器资源限制。

   2. 在cgroups之前,想要完成一个或者一组进程的物理内存使用率的限制,几乎不可能完成。使用cgroups提供的功能,可以轻易的限制限制系统内某一组物理内存占用率、对于网络包,设备访问或者io资源控制,cgroups同样提供了之前无法完成的精细化控制。


http://chatgpt.dhexx.cn/article/KWSglerW.shtml

相关文章

Cgroup是什么(相关概念、功能、作用、特点、怎么用)

文章目录 Cgroup 什么是CgroupCgroup的相关概念相互关系Cgroup的功能Cgroup的作用Cgroup的层级图及特点Cgroup怎么用 什么是Cgroup cgroups,其名称源自控制组群(control groups)的简写,是Linux内核的一个功能,用来限…

Cgroup简介-概述

Cgroup(Control Groups)是这样一种机制:它以分组的形式对进程使用系统资源的行为进行管理和控制。也就是说,用户通过cgroup对所有进程进行分组,再对该分组整体进行资源的分配和控制。 1 Cgroup的结构 cgroup中的每个分…

J2EE技术架构

一、简介 J2EE(Java 2 Platform, Enterprise Edition)是一个为大企业主机级的计算类型而设计的Java平台。Sun微系统(与其工业伙伴一起,例如IBM)设计了J2EE,以此来简化在受客户级环境下的应用开发。由于创造…

J2EE架构模型

从开始学Java Web到现在,使用的J2EE架构一步一步的在改变,从最简单的到越来越复杂,刚开始都是完全就照着每个架构的形式去开发项目,很少自己会想为什么用这样的架构好?好在哪里?现在学了这么久,…

java开发系统架构_Java开发:ECP系统J2EE架构开发平台

一 体系结构 ECP平台是一个基于J2EE架构设计的大型分布式企业协同管理平台,通过采用成熟的J2EE的多层企业架构体系,充分保证了系统的健壮性、开放性和扩展性。可选择部署于多种系统环境,满足不同类型、不同规模企业的需要。企业可以根据自己的…

J2EE的体系架构

转载自:http://zengbo0710.iteye.com/blog/79490 J2EE 即Java2平台企业版,它提供了基于组件的方式来设计、开发、组装和部署企业应用。J2EE使用多层分布式的应用模型,这个多层通常通过三层或四层来实现: 1、客户层&…

J2EE体系架构

J2EE是Java2平台企业版(Java 2 Platform,Enterprise Edition),它的核心是一组技术规范与指南,提供基于组件的方式来设计、开发、组装和部署企业应用。J2EE使用多层分布式的应用模型。 J2EE分层 客户层,执行在客户计算…

基于J2EE架构的在线考试系统-Java(报告+源码+PPT

目前国内基于B/S、C/S结构的在线考试系统产品已经有许多,本文首先介绍了这些考试系统的形成和发展过程,大致结构。然后通过仔细分析,提出了目前的这些系统还存有系统更新和维护等种种弊端,仍不够成熟。基于对现有产品的思考,结合J…

Spring 架构图

http://it.100xuexi.com/view/otdetail/20130426/38b9d40a-138b-4b24-963c-ac029b034fe7.html 1.Spring 架构图 Spring 是一个开源 框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件…

Scala安装教程

1.Scala官网滑到最下面如图: 选择Allversions 2.我们将下载2.12.16版本,如图下 3.选scala-2.12.16.zip安装 4.先将scala-2.12.16zip解压为文件夹我解压到了D盘的scalal文件夹下面 D:\scalal\scala-2.12.16

linux上安装scala教程

Scala教程 一、介绍 cala 是 Scalable Language 的简写,是一门多范式的编程语言,Scala 语言可以运行在Window、Linux、Unix、 Mac OS X等系统上。 安装scala之前,需要在linux上安装jdk,如果没有安装jdk,可以参考这篇…

Scala教程之:可变和不变集合

文章目录 mutable HashMapimmutable HashMap 集合在程序中是非常有用的,只有用好集合才能真正感受到该语言的魅力。在scala中集合主要在三个包里面:scala.collection, scala.collection.immutable和scala.collection.mutable。 scala中引入不…

Scala语法教程

第一章 Scala入门 1.1概述 Scala是一门以Java虚拟机(JVM)为运行环境并将面向对象和函数式编程的最佳特性结合在一起的 静态类型编程语言(静态语言需要提前编译的如:Java、c、c等,动态语言如:js&#xff0…

Scala入门教程

教程目录 0x00 教程内容0x01 Scala 理论1. Scala 基本概念2. Scala 交互式命令行 0x03 Scala 基本语法1. 基础语法2. 标识符3. 注释4. 数据类型5. 常量和变量6. 基本函数7. 局部应用8. 柯里化函数9. 可变长度参数10. 类11. 构造函数12. 继承13. 重载方法14. 抽象类15. 特质16. …

Scala基础教程

简介 Scala是一种结合了面向对象和函数式编程的、静态类型的高级编程语言。 Scala代码被编译成.class文件,运行在Java虚拟机(JVM)上,可以调用Java类库。 官方网站:https://www.scala-lang.org/ 官方文档:https://docs.scala-lan…

scala php,Scala 教程

Scala 教程 Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。 Scala 运行在Java虚拟机上,并兼容现有的Java程序。 Scala 源代码被编译成Java字节码,所以它可以运行于JVM之上,…

Scala详细教程

Scala详细教程 目录 Scala详细教程 1.Scala 介绍 1.1 什么是 Scala Scala 1.2 为什么要学 Scala 2.开发环境准备 2.1 ScalaSDK 安装 2.1.1Window 下安装 ScalaSDK 2.1.2Linux 下安装 ScalaSDK 2.2 IDEA 安装 2.3 IDEAScala 插件的离线安装 2.4 IDEA 创建 HelloScala…

Scala教程

1. 基础语法 Scala语言是基于Java虚拟机运行的,所以基本的语法和Java是没有区别的。但是为了简化Java的开发以及融合其他的编程语言的优点和特性,Scala在基本的语法上做了大量的修改和优化,让程序员开发起来更简单,方便&#xff…