Linux系统中cgroup功能介绍
1 Cgroups简介
1.1 What are cgroups ?
Cgroups(控制组)是Linux内核的一个功能,用来限制、统计和分离一个进程组的资源(CPU、内存、磁盘输入输出等)。换句话说就是,如果一个进程加入了某一个控制组,该控制组对Linux的系统资源都有严格的限制,进程在使用这些资源时,不能超过其最大的限制数,例如:memory资源,如果加入控制组的进程使用的memory大于其限制,可能会出现OOM错误(关于OOM错误可参看Linux内核OOM机制分析)。cgroup本身提供将进程进行分组化管理的功能和接口的基础结构
控制组提供一种机制,将一组任务和它们的子任务聚合或划分到有特定功能的层级结构(hierarchical)中。在Cgroups中涉及下面的几个概念:
(1)任务(task):在 cgroups 中,任务就是系统的一个进程。
(2)控制族群(control group):控制族群就是一组按照某种资源限制划分的进程。Cgroups 中的资源控制都是以控制族群为单位实现。一个进程可以加入到多个控制族群。假设这里有个进程A,我们要限制其使用的系统内存总量的10%,我们就可以创建一个memory占用10%的cgroups。然后,将进程A添加到cgroups,那么进程A最多占用内存总量的10%,当然,一个cgroups一般情况下不止一个进程。
(3)层级(hierarchy):控制族群可以组织成 hierarchical 的形式,既一颗控制族群树。子控制组自动继承父节点的特定属性,当然子控制组还可以有自己特定的属性。下面是Linux内核关于Cgroups的一种图示:可以看出他的层级表示:
.CPU : "Top cpuset"
/ \
CPUSet1 CPUSet2
| |
(Professors) (Students)
In addition (system tasks) are attached to topcpuset (so
that they can run anywhere) with a limit of 20%
Memory : Professors (50%), Students (30%), system (20%)
Disk : Professors (50%), Students (30%), system (20%)
Network : WWW browsing (20%), Network File System (60%), others (20%)
/ \
Professors (15%) students (5%)
Browsers like Firefox/Lynx go into the WWW network class, while (k)nfsd goes
into the NFS network class.(参考Linux内核的cgroups说明)
(4)Subsystem:子系统是任务组中的一个模块,例如前面的memory就是一个子系统,该子系统是一个内存控制器。在cgroups的框架下,为cgroups提供多种资源限制。(each subsystem has system-specific state attached to each cgroup in the hierarchy. Each hierarchy has an instance of the cgroup virtual filesystem associated with it)。
1.2 Cgroups子系统介绍
(1)blkio --为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等)。
(2)cpu -- 使用调度程序提供对cgroup-bin_0.38-1ubuntu2_i386版本中的cgconfig.conf文件,但是我们可以自己创建该配置文件,这样但mount , group and default 三个段,这三个段的顺序是任意的,并且都是可选参数,该文件中用
mount section has this form:
mount {
= ;
...
}
Controller:
表示内核支持的子系统的名字。通过/proc/cgroups文件查看系统中支持子系统。
Path:
子系统的挂载点。
如果没有mount段,则controllers不会被挂载。
group section has this form:
group {
[permissions]
{
= ;
...
}
...
}
Name:
control group的名字,只能包括目录名字允许的字符。
permissions:
可选项,指定cgroup对应的挂载点文件系统的权限
Controller:
内核中支持的子系统的名字。
param name,param value:参数的名字和参数的值。
如果没有group,则就没有group被创建。
Default段如下面的形式:
default {
perm {
task {
uid = ;
gid = ;
fperm =
}
admin {
uid = ;
gid = ;
dperm =
fperm =
}
}
}
下面举两个例子:
mount {#定义需要创建的cgroup子系统及其挂载点,这里创建cpu与cpuacct(统计)两个cgroup子系统
cpu = /mnt/cgroups/cpu;
cpuacct = /mnt/cgroups/cpu;
}
和下面的shell脚本是等价的:
mkdir /mnt/cgroups/cpu
mount -t cgroup -o cpu,cpuacct cpu /mnt/cgroups/c
group daemons/www {
perm {#定义组的权限
task {
uid = root;
gid = webmaster;
fperm = 770;
}
admin {
uid = root;
gid = root;
dperm = 775;
fperm = 744;
}
}
cpu {
cpu.shares = "1000";
}
}
group daemons/ftp {
perm {
task {
uid = root;
gid = ftpmaster;
fperm = 774;
}
admin {
uid = root;
gid = root;
dperm = 755;
fperm = 700;
}
}
cpu {
cpu.shares = "500";
}
}
相当于使用下面的脚本:
mkdir /mnt/cgroups/cpu
mount -t cgroup -o cpu,cpuacct cpu /mnt/cgroups/cpu
mkdir /mnt/cgroups/cpu/daemons
mkdir /mnt/cgroups/cpu/daemons/www
chown root:root /mnt/cgroups/cpu/daemons/www/*
chown root:webmaster /mnt/cgroups/cpu/daemons/www/tasks
echo 1000 > /mnt/cgroups/cpu/daemons/www/cpu.shares
上面的具体内容可以参考,cfconfig.conf文件说明
1.4 用户空间挂载Cgroup
上面我们分析了一下,cgroup的配置文件,这里我们具体分析一下使用命令如何进行配置。我们知道cgroup的实现有一个文件系统的支持,用户空间的配置可以使用cgroup文件系统。首先,我们可以创建一个层级:在创建层级之前我们需要创建挂载的目录,这里使用的目录是/home/ubuntu /test_cgroup
root@ubuntu:~# mount -t cgroup -o cpu cpu_group /home/ubuntu/test_cgroup/
这个命令就是创建了一个test_cgroup的层级,这个层级有一个子系统cpu,并把层级挂载到了/home/ubuntu /test_cgroup目录下。进入该目录可以看到一些和CPU相关的参数。
root@ubuntu:~# cd test_cgroup/
root@ubuntu:~/test_cgroup# ls
cgroup.clone_children cpu.cfs_period_us cpu.shares tasks
cgroup.event_control cpu.cfs_quota_us cpu.stat cgroup.procs cpu.rt_period_us notify_on_release
cgroup.sane_behavior cpu.rt_runtime_us release_agent
然后创建一个cgroup,名字为foo
root@ubuntu:~/test_cgroup# mkdir foo
root@ubuntu:~/test_cgroup# cd foo/
root@ubuntu:~/test_cgroup/foo# ls
cgroup.clone_children cpu.cfs_period_us cpu.rt_runtime_us notify_on_release
cgroup.event_control cpu.cfs_quota_us cpu.shares tasks
cgroup.procs cpu.rt_period_us cpu.stat
这样就在cpu_group层级上创建了一个foo的cgroup,在Foo目录下有一些文件,这些都是CPU相关的属性。其中cat ~/test_cgroup/task可以看到系统中的所有进程ID。这是因为每创建一个层级,系统会把系统中所以的进程ID添加到task中,而在foo/task文件却是空,这个文件用户可以添加。
在/proc/下面有一个cgroups的文件,记录了所有cgroups子系统的状态信息。
root@ubuntu:~/test_cgroup/foo# cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset 3 1 1
cpu 4 3 1
cpuacct 5 1 1
memory 6 2 1
devices 7 1 1
freezer 8 1 1
blkio 9 1 1
perf_event 10 1 1
hugetlb 11 1 1
从左到右的条目分别是子系统name,hierarchy ID,子系统的cgroup控制组数目,子系统是否可用(1可用,0不可用)
/proc/mounts文件显示了系统中挂载的文件系统信息,前面几个目录表示文件系统name,挂载点绝对路径,文件系统类型
root@ubuntu:~/test_cgroup/foo# cat /proc/mounts
rootfs / rootfs rw 0 0
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
udev /dev devtmpfs rw,relatime,size=503368k,nr_inodes=125842,mode=755 0 0
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=102556k,mode=755 0 0
/dev/disk/by-uuid/612dacd9-3cf7-471b-92a4-f5c7c6e4e88a / ext4 rw,relatime,errors=remount-ro,data=ordered 0 0
none /sys/fs/cgroup tmpfs rw,relatime,size=4k,mode=755 0 0
none /sys/fs/fuse/connections fusectl rw,relatime 0 0
none /sys/kernel/debug debugfs rw,relatime 0 0
none /sys/kernel/security securityfs rw,relatime 0 0
none /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0
none /run/shm tmpfs rw,nosuid,nodev,relatime 0 0
none /run/user tmpfs rw,nosuid,nodev,noexec,relatime,size=102400k,mode=755 0 0
none /sys/fs/pstore pstore rw,relatime 0 0
systemd /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,name=systemd 0 0
vmware-vmblock /run/vmblock-fuse fuse.vmware-vmblock rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other 0 0
gvfsd-fuse /run/user/1000/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0
cgroup /sys/fs/cgroup/cpuset cgroup rw,relatime,cpuset 0 0
cgroup /sys/fs/cgroup/cpu cgroup rw,relatime,cpu 0 0
cgroup /sys/fs/cgroup/cpuacct cgroup rw,relatime,cpuacct 0 0
cgroup /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0
cgroup /sys/fs/cgroup/devices cgroup rw,relatime,devices 0 0
cgroup /sys/fs/cgroup/freezer cgroup rw,relatime,freezer 0 0
cgroup /sys/fs/cgroup/blkio cgroup rw,relatime,blkio 0 0
cgroup /sys/fs/cgroup/perf_event cgroup rw,relatime,perf_event 0 0
cgroup /sys/fs/cgroup/hugetlb cgroup rw,relatime,hugetlb 0 0
gvfsd-fuse /root/.gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=0,group_id=0 0 0
test_group /home/zfz/cgroup cgroup rw,relatime,cpu 0 0
cpu_group /home/zfz/test_cgroup cgroup rw,relatime,cpu 0 0
1.5 Cgroup使用实例
用lssubsys -al来列出系统支持多少种子系统,和使用ls /sys/fs/cgroup/ (ubuntu)来显示已经挂载的子系统。
如果提示下面的错误信息,则表示系统中还没有安装cgroup.
lssubsys -all
The program 'lssubsys' is currently not installed. You can install it by typing:
需要使用下面的方法进行安装:
root@ubuntu:~# apt-get install cgroup-bin
Reading package lists... Done
再次使用lssubsys列出系统中支持的子系统,根据不同的内核版本,支持的子系统也不相同。
root@ubuntu:~# lssubsys --all
cpuset
cpu
cpuacct
memory
devices
freezer
blkio
perf_event
hugetlb
还有一种情况需要进行确认,确认相应的内核部分是否已经编译。
grep CGROUP /boot/config-`uname -r`
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NET_CLS_CGROUP=m
CONFIG_NETPRIO_CGROUP=m
我们可以创建一个cgroup的cpu子系统,创建完成之后就在该目录下有下面的属性文件可以进行设置。
root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# ls
cgroup.clone_children cpu.cfs_period_us cpu.rt_runtime_us notify_on_release
cgroup.event_control cpu.cfs_quota_us cpu.shares tasks
cgroup.procs cpu.rt_period_us cpu.stat
使用cat命令查看其中的默认值。
root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# cat cpu.cfs_quota_us
-1
root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# cat cpu.cfs_period_us
100000
默认挂载在/sys/fs/cgroup/memory,可以通过cfconfig.conf文件查看默认的挂载点。这里有两个小的例子主要是为了测试cgroup对进程使用CPU和memeory的控制,这里使用两个Python脚本来模拟其中的效果。
例子1:设置该进程对CPU的占用率不能超过50%。
root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# echo 50000 > cpu.cfs_quota_us
root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# cat cpu.cfs_quota_us
50000
root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# cat tasks
root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# echo 9477 > tasks
使用的Python程序如下:
root@ubuntu:~# cat python_test_cpu.py
#!/usr/bin/env python
import os
pid_num = os.getpid()
print pid_num
var = 1
count = 1
while var == 1:
count = count + 1
count = 0
在没有把python的进程号添加到tasks中,该进程的CPU占用率接近95%。而把该进程ID添加到tasks中经过持续的观察,该进程的CPU使用率不超出50%,和在cgroup中设置的一致。
例子2:限制内存的使用率
Python代码如下:
root@ubuntu:~# cat python_test_memory.py
#!/usr/bin/env python
import os
import time
pid_num = os.getpid()
print pid_num
var = 1
a = "abcdefgh"
b = "abcdefgh"
c = ""
time.sleep(10)
#while var == 1:
for i in range(1,30000000):
c = "####".join([a,b]) + c
在没有使用cgroups机制的情况下,通过top命令查看该进程占用的memory情况如下:
持续观察一段时间基本维持在40%左右。在使用cgoup机制,限制在10M的情况下,其内存的占有率发生了变化。
root@ubuntu:/sys/fs/cgroup/memory/memory_test# echo 10M > memory.limit_in_bytes
root@ubuntu:/sys/fs/cgroup/memory/memory_test# cat memory.limit_in_bytes
10485760
过一小段时间会出现进程退出的情况,如下:进程被杀掉了。
root@ubuntu:~# ./python_test_memory.py
10608
[8]+ Killed ./python_test_memory.py
Killed
在这里也可以配置内核的OOM机制,默认值是开着呢。
root@ubuntu:/sys/fs/cgroup/memory/memory_test# cat memory.oom_control
oom_kill_disable 0
under_oom 0
在上面我们设置的是memory.limit_in_bytes 值,但在目录下还有一个memory.soft_limit_in_bytes 属性,,该值和 memory.limit_in_bytes 的差异是,memory.soft_limit_in_bytes这个限制并不会阻止进程使用超过限额的内存,只是在系统内存不足时,会优先回收超过限额的进程占用的内存,使之向限定值靠拢
通过上面的分析可以看出来,简单的说Cgroup就是限制了各个不同进程之间使用各种资源的能力。上面两个例子是最常用的CPU和内存,每一个内核子系统都有很多的配置选项信息,其中配置选项的含义可以参考Linux内核文档,Linux的Cgroup子系统解释。Cgroup做到对资源的限制访问,这对于Linux系统上的虚拟化和云计算提供了一种资源配置方式。
参考文献:
http://blog.chinaunix.net/uid-20940095-id-3294134.html
http://files.cnblogs.com/lisperl/cgroups介绍.pdf
Linux系统中cgroup功能介绍相关推荐
- linux子系统gdp调试,Linux系统中GDB功能汇总
在Linux系统操作中,GDB是一款程序调试工具,且拥有多种功能,下面小编将针对GDB的功能给大家做个详细介绍,以便你对GDB有个详细的了解. 或许,各位比较喜欢那种图形界面方式的,像VC.BCB等I ...
- linux rps值大小,Linux系统中RPS/RFS介绍
frankzfz2014-07-27 17:32 demo121:frankzfz您好: 我想请教一个问题,就是将写好的GenericApp项目(没有配置工具),我加入zigbee协议栈的配置工具后还 ...
- 在每个运行中运行多个查询_linux系统中运行级别介绍
CentOS7.3学习笔记总结(五十)- linux系统中运行级别介绍 linux系统中的运行级别是操作系统运行时的功能级别,级别从0到6共7个功能级别,分别是: 0:停机 1:单用户模式 2:多用户 ...
- linux sudo命令全称,你知道Linux系统中的sudo 命令吗?
今天小编要跟大家分享的文章是关于Linux系统中sudo命令介绍.熟悉Linux操作系统的小伙伴们你们是否了解sudo命令.sudo 表示 "superuser do". 它允许已 ...
- linux中bash的功能主要有,Linux系统中的Bash功能的介绍
今天小编要跟大家分享的文章是关于Linux系统中的Bash功能的介绍.一个完整计算机的体系结构包括:硬件与软件,而软件又分为系统软件与应用软件,负责对硬件仅需管理与操作的是系统软件的内核部分,用户是无 ...
- jenkins linux虚拟机,Linux系统中jenkins使用的简单介绍
jenkins是一个开放的软件平台,在Linux系统中的软件平台也不少,但是jenkins一直是比较受欢迎的那一个.本文就来简单介绍一下Linux系统中jenkins安装配置和使用. 安装jenkin ...
- linux常用删除空文件夹,Linux基础 linux系统中的批量删除文件与空文件删除的命令介绍...
Linux基础教程linux系统中的批量删除文件与空文件删除的命令介绍 Linux资料下面删除文件或者目录命令rm(remove): Linux培训功能说明:删除文件或目录. 语 法:rm [-dfi ...
- linux下vim编辑器插件,为你介绍Linux系统中vim编辑器的实用插件!
今天小编要跟大家分享的文章是关于Linux系统中vim编辑器的实用插件.Vim 是 Linux 下的常用文本编辑器,但也经常被称为是一个上古神器,因为它对于初学者而言相当不友好,也不好入门. Linu ...
- 深度Linux下的中望CAD软件,中望CAD Linux预装版的功能介绍,在Deepin和UOS下安装很简单...
如果你使用的是Deepin和UOS操作系统,那么安装中望CAD Linux预装版非常的简单,只需要打开应用商店,然后搜索中望就可以对出来的结果进行安装了,下面介绍一下中望CAD Linux预装版的功能 ...
- linux bzip2 命令,Linux系统中bzip2命令的语法参数介绍
从bzip2这个Linux命令字面上看,它是以个跟压缩有关的命令.事实也确实如此,bzip2 的功能就是用来压缩bz2文件.本文就来介绍一下Linux系统中bzip2命令的语法和参数. 语 法:bzi ...
最新文章
- think in java笔记_Thinking in java读书笔记 PDF 下载
- 大凉山的美术课,怎么就跟英特尔扯上关系了
- 国内外常用Linux服务器控制面板介绍
- Windows_API_函数 参考大全
- JVM编译时和运行时状态
- SAP 电商云 Spartacus UI 有状态 的 url 和 title 属性的赋值代码
- 小程序·云开发的HTTP API调用丨实战
- 你走过最长的路 ,就是机器学习过程中的弯路
- java毕设用的框架_分享四个Java低代码快速开发平台贼好用, 私活毕设神器
- 3 CO配置-企业结构-分配-把公司代码分配给成本控制范围
- API、H5跟风控相关的知识是否了解?
- 蓝桥杯 ALGO-122 算法训练 未名湖边的烦恼
- sql的left join 命令详解
- 安装windows7系统报错
- linux cp 复制目录下文件到另一个目录下
- flv格式php怎么播放不了,FLV格式视频不能在网页播放的解决办法
- (二)java项目中的文档转换案例实战——PDF转换为JPG图片压缩包
- 步道乐跑(最新版本)
- 计算机三级网络架构图,三级网络技术局域网基础:网络拓扑结构
- SQL Server 负载均衡集群方案之Moebius
热门文章
- 用友CDM系统“货位间商品移库单(一步)”表体增加“货位可用数量”字段,根据表头的选择的货位自动带出数值...
- python3 collections模块_python的Collections 模块
- Java NIO框架Netty教程(二)
- axios基于常见业务场景的二次封装
- 23.3. DELETE
- VC++多线程--进程间通信
- 异步消息的性能与激情之Netty开发思路
- js 正则清除html格式
- linux 复制文件时,报cp: omitting directory `XXX'
- IE css hack整理