|
????????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

?
?
欢迎关注我的公众号:龙叔运维
持续分享运维经验

?
?
|