linux进程资源控制-cgroup

Posted 龙叔运维

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux进程资源控制-cgroup相关的知识,希望对你有一定的参考价值。

        Linux CGroup全称Linux Control Group, 是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)。防止进程间不利的资源抢占。

        一般在较大的公司中会经常用到,例如多个数据库跑在一个物理机上,一般按照需要对不同的数据库进行资源的分配和限制,避免单个库的消耗增加影响其他数据库的性能。

1、概念

        

  • 控制族群(cgroup) - 关联一组task和一组subsystem的配置参数。一个task对应一个进程, cgroup是资源分片的最小单位。
  • 子系统(subsystem) - 资源管理器,一个subsystem对应一项资源的管理,如 cpu, cpuset, memory等
  • 层级(hierarchy) - 关联一个到多个subsystem和一组树形结构的cgroup. 和cgroup不同,hierarchy包含的是可管理的subsystem而非具体参数
  • 任务(task)- 每个cgroup都会有一个task列表文件tasks,一个task就对应一个进程。

        

        相互关系:

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

 

         当你的cgroup 关联了哪些subsystem ,那这个cgroup 目录下就会有对应subsystem 的参数配置文件,可以通过这些文件对对应的资源进行限制

        cgroup目录下的tasks文件里面可以添加你想要进行资源限制管理的进程的PID

 

1.1、subsystem

        centos支持的subsystem如下

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 名称空间子系统。

 1.2、hierarchy 

        hierarchy包含的是可管理的subsystem

        创建hierarchy

        mount -t cgroup -o cpuset cgroup_t  /cg_t1(关联cpuset 这个subsystem

        mount -t cgroup -o memory cgroup_t  /cg_t2(关联memory 这个subsystem

        mount -t cgroup可以看到新增的hierarchy

 

 

        cg_t1目录结构如下(关联的是cpuset ,所以参数都是cpuset 相关的):

[root@blackduck-tool-core-20211006202310-xun2 /]# tree /cg_t1/
/cg_t1/ 【hierarchy的根目录  也是一个cgroup】
├── cgroup.clone_children【subsystem参数】
├── cgroup.event_control
├── cgroup.procs
├── cgroup.sane_behavior
├── cg_t1_1【个人创建的子cgroup】
│   ├── cgroup.clone_children【subsystem参数】
│   ├── cgroup.event_control【subsystem参数】

 

... ...


│   └── tasks【task列表(进程PID)】
├── cpuset.cpu_exclusive【subsystem参数】
├── cpuset.cpus【subsystem参数】
├── cpuset.effective_cpus【subsystem参数】
├── cpuset.effective_mems【subsystem参数】
├── cpuset.mem_exclusive【subsystem参数】
├── cpuset.mem_hardwall【subsystem参数】
├── cpuset.memory_migrate【subsystem参数】
├── cpuset.memory_pressure【subsystem参数】
├── cpuset.memory_pressure_enabled【subsystem参数】
├── cpuset.memory_spread_page【subsystem参数】
├── cpuset.memory_spread_slab【subsystem参数】
├── cpuset.mems【subsystem参数】
├── cpuset.sched_load_balance【subsystem参数】
├── cpuset.sched_relax_domain_level【subsystem参数】
├── notify_on_release【subsystem参数】
├── release_agent
├── tasks【task列表(进程PID)】

 

 

 

 

1.3、cgroup

        cgroup管理的是具体的subsystem的参数

 

        如果需要创建cgroup,在hierarchy的根目录下或者其他cgroup目录下直接创建目录就可以

        创建出来的目录会自动集成父目录的subsystem,自动创建相关文件

        例如,我在如/cg_t1下面创建cg_t1_2,cg_t1_2下会自动生成下面文件

[root@blackduck-tool-core-20211006202310-xun2 cg_t2]# cd /cg_t1
[root@blackduck-tool-core-20211006202310-xun2 cg_t1]# mkdir  cg_t1_2
[root@blackduck-tool-core-20211006202310-xun2 cg_t1]# cd cg_t1_2
[root@blackduck-tool-core-20211006202310-xun2 cg_t1_2]# ll
total 0
-rw-r--r-- 1 root root 0 Oct  6 23:23 cgroup.clone_children
--w--w--w- 1 root root 0 Oct  6 23:23 cgroup.event_control
-rw-r--r-- 1 root root 0 Oct  6 23:23 cgroup.procs
-rw-r--r-- 1 root root 0 Oct  6 23:23 cpuset.cpu_exclusive
-rw-r--r-- 1 root root 0 Oct  6 23:23 cpuset.cpus
-r--r--r-- 1 root root 0 Oct  6 23:23 cpuset.effective_cpus
-r--r--r-- 1 root root 0 Oct  6 23:23 cpuset.effective_mems
-rw-r--r-- 1 root root 0 Oct  6 23:23 cpuset.mem_exclusive
-rw-r--r-- 1 root root 0 Oct  6 23:23 cpuset.mem_hardwall
-rw-r--r-- 1 root root 0 Oct  6 23:23 cpuset.memory_migrate
-r--r--r-- 1 root root 0 Oct  6 23:23 cpuset.memory_pressure
-rw-r--r-- 1 root root 0 Oct  6 23:23 cpuset.memory_spread_page
-rw-r--r-- 1 root root 0 Oct  6 23:23 cpuset.memory_spread_slab
-rw-r--r-- 1 root root 0 Oct  6 23:23 cpuset.mems
-rw-r--r-- 1 root root 0 Oct  6 23:23 cpuset.sched_load_balance
-rw-r--r-- 1 root root 0 Oct  6 23:23 cpuset.sched_relax_domain_level
-rw-r--r-- 1 root root 0 Oct  6 23:23 notify_on_release
-rw-r--r-- 1 root root 0 Oct  6 23:23 tasks

1.4、准则

        1.一个hierarchy可以有多个 subsystem (mount 的时候hierarchy可以attach多个subsystem)

        2.一个已经被挂载的 subsystem 只能被再次挂载在一个空的 hierarchy 上 (已经mount一个subsystem的hierarchy不能挂载一个已经被其它hierarchy挂载的subsystem)

 

        3.每个task只能在一同个hierarchy的唯一一个cgroup里(不能在同一个hierarchy下有超过一个cgroup的tasks里同时有这个进程的pid)

        4.子进程在被fork出时自动继承父进程所在cgroup,但是fork之后就可以按需调整到其他cgroup

 

2、小实验(限制进程CPU消耗)

2.1、创建一个死循环的shell脚本

#/bin/sh
a=1
while (( 1 ))
do

 let a++

done

        然后运行起来,top命令可以查看到这个shell脚本进程的PID的18024,CPU消耗为100%

 

 2.2、给进程添加cpu消耗限制

         我们在原有的/sys/fs/cgroup/cpu下面创建一个新的cgroup为cpu_t,其目录下文件如下

        然后

        echo 20000 >cpu./sys/fs/cgroup/cpu/cpu_t/cpu.cfs_quota_us【将该cgroup的cpu消耗限制为20%】

        echo 18024>> /sys/fs/cgroup/cpu/cpu_t/tasks 【将进程纳入该cgroup限制管理】

        这个时候再用top命令查看  就会发现这个shell脚本进程的cpu消耗变成了20%,限制起了作用

 

3、常见操作

cgroup的配置文件是/etc/cgconfig.conf,常见的操作可以通过配置文件实现,也可以通过命令行实现

3.1、创建一个hierarchy(挂载subsystem)

3.1.1、命令行

  mount -t cgroup -o cpuset,memory cpu_and_mem /cg_t1

3.1.2、配置文件

语法如下:

  mount {
      subsystem = 挂载路径(会自动创建挂载路径);
      。。。
  }

举例:

  mount {
      cpuset  = /
cg_t1;
      memory = /cg_t1;
  }


 

3.2、新建删除cgroup

3.1.1、命令行:

  • 新建方法1 cgcreate -t uid:gid -a uid:gid -g subsystems:path
  • 新建方法2 mkdir /cgroup/hierarchy/name/child_name
  • 删除方法1 cgdelete subsystems:path (使用 -r 递归删除)
  • 删除方法2 rm -rf /cgroup/hierarchy/name/child_name (cgconfig service not running)

3.1.2、配置文件

语法如下:

·name指定cgroup的名称

·permissions,可选项,指定cgroup对应的挂载点文件系统的权限(perm参数)

·controller:子系统的名称

·param name和param value:子系统下具体的某一个属性及其属性值

group <name> {
    [<permissions>]    

    <controller> {  

        <param name> = <param value>;
        …
    }
    …
}

举例:

  group cg_t1_1 {
      cpuset {
          cpuset.mems = 0;
          cpuset.cpus = 0;
      }
  }
 

3.3、权限管理

3.3.1、命令行

chown改变文件属主权限就可以

如:

        chown root:root /cg_t1/cg_t1_2/sql/*

        chown root:root /cg_t1/cg_t1_2/sql/tasks

3.3.2、配置文件

在配置文件中对应的cgroup下面配置prem

语法如下

perm {
    task {
        uid = <task user>;
        gid = <task group>;
    }
    admin {
      uid = <admin name>;
      gid = <admin group>;
    }
}

举例:

  group cg_t1_2 {
      perm {
          task {
              uid = root;
              gid = sqladmin;
          } admin {
              uid = root;
              gid = root;
          }
      }
      cpuset {
          cpuset.mems = 0;
          cpuset.cpus = 0;
      }
  }

3.4、设置cgroup下的参数

3.4.1·命令行

语法

echo value > path_to_cgroup/parameter

举例

echo 20000 >cpu./sys/fs/cgroup/cpu/cpu_t/cpu.cfs_quota_us

3.4.2、配置文件

在对应的group下面添加,如

group cg_t1_1 {
      cpuset {
          cpuset.mems = 0;
          cpuset.cpus = 0;
      }
}
 

3.5、添加task(管理进程)

3.5.1、命令行

语法

echo pid > path_to_cgroup/tasks

举例

echo 13445 > cpu./sys/fs/cgroup/cpu/cpu_t/tasks

3.5.2、配置文件

通过/etc/cgrules.conf 对特定服务限制

这里是对用户或者用户组进行限制

户或@组:命令 子系统 cgroup名称

如:

sqladmin    cpu    cg_t1_1

 

 

欢迎关注我的公众号:龙叔运维

持续分享运维经验

 

 

以上是关于linux进程资源控制-cgroup的主要内容,如果未能解决你的问题,请参考以下文章

linux进程资源控制-cgroup

Linux Cgroup浅析

linux cgroup机制

Linux资源管理之cgroups简介

Linux资源管理之cgroups简介

7 Cgroup