一、定义:
Cgroup是Control Groups的缩写,是Linux内核提供一种可以限制、记录、隔离进程组所使用的物理资源的机制。
二、组成:
Cgroup是将任意进程进行分组化管理的Linux内核功能。Ggroup提供将进程进行分组化管理的功能和接口的基础结构,用于实现I/O或者内存的分配控制等具体的资源管理。这些具体的资源管理功能称为Ggroup子系统或控制器。
1、task 任务:在cgroup中任务就是系统的一个进程。
2、control group=cgroup 控制组群:控制族群就是一组按照某种标准划分的进程。cgroup中的资源控制都是以控制组群为单位实现。cfoup绑定一个进程集合到一个或多个子系统。
3、subsystem 子系统:一个通过cgroup提供的工具和接口来管理进程集合的模块。一个子系统就是一个典型的“资源控制器”,用来调度资源或控制资源使用的上限。其实每种资源就是一个子系统。
4、hierarchy 层级树:多个cgroup的集合。可以认为这是一个资源树,附着在这上面的进程可以使用的资源上限必须收树上节点(cgroup)的控制。hierarchy上的层次关系通过cgroupgs虚拟文件系统显示。系统允许多个hierarchy同时存在,每个hierachy包含系统中的部分或者全部进程集合。
5、cgroupfs是用户管理操作cgroup的主要接口:通过在cgroupfs文件系统中创建目录,实现cgroup的创建;通过向目录下的属性文件写入内容,设置cgroup对资源的控制;向task属性文件写入进程ID,可以将进程绑定到某个cgroup,以此达到控制进程资源使用的目的;也可以列出cgroup包含的进程pid。这些操作影响的sysfs关联的hierarchy,对其他hierarchy没有影响。
相互关系:
1、每次在系统中创建新层级时,该系统的所有任务都是那个层级默认cgroup(root cgroup)的初始成员。
2、一个子系统最多附加一个层级。
3、一个层级可以附加多个子系统。
4、一个任务可以是多个cgroup的成员,但这些cgroup必须在不同层级。
5、系统中的进程(任务)创建子进程(任务)时,改子系统自动成为其父进程所在cgroup的成员。
三、功能:
Cgroup提供以下功能:
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子系统可以将进程组挂起和恢复。
四、安装配置:(默认有装)
1、安装Cgroups需要libcap-devel和libcgroup两个相关的包:
yum install gcc libcap-devel
2、Cgroups挂载配置:
Cgroup对应服务名称为cgconfig,cgconfig默认采用“多挂载点”挂载。经过实际测试,发现在CentOS环境中应采用“单挂载点”进行挂载,因此应当卸载原有cgroup文件系统,并禁用cgconfig。
cgclear或者sudo service cgconfig stop # 停止cgconfig,卸载cgroup目录
sudo chkconfig cgconfig off # 禁用cgconfig服务,避免其开机启动
然后采用“单挂载点”方式重新挂载cgroup。
可以直接手动挂载,这样仅当次挂载成功。
mount -t cgroup none /cgroup
然后编辑/etc/fstab/,输入下列内容。这样每次开机后都会自动挂载。
none /cgroup cgroup defaults 0 0
3、相关命令和配置文件:
service cgconfig status|start|stop|restart #查看已存在子系统
lssubsys –am #查看已存在子系统
cgclear # 清除所有挂载点内部文件,相当于service cgconfig stop
cgconfigparser -l /etc/cgconfig.conf #重新挂载
Cgroup默认挂载点(CentOS):/cgroup
cgconfig配置文件:/etc/cgconfig.conf
五、实际例子:
1、cgroup管理进程资源:
跑一个耗cpu的脚本:
x=0 while [ True ];do x=$x+1 done;
top可以看到脚本基本占了100%的cpu资源:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 30142 root 20 0 104m 2520 1024 R 99.7 0.1 14:38.97 sh
下面用cgoup控制整个进程cpu资源
mkdir -p /cgroup/cpu/foo/ #新建一个控制组foo echo 50000 > /cgroup/cpu/foo/cpu.cfs_quota_us #将cpu.cfs_quota_us设为50000,相对于cpu.cfs_period_us的100000是50% echo 30142 > /cgroup/cpu/foo/tasks
然后再top试试统计,cpu占了将近50%。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 30142 root 20 0 105m 2884 1024 R 49.4 0.2 23:32.53 sh
2、cgroup管理进程内存资源:
跑一个耗内存的脚本,内存不断增长:
x="a" while [ True ];do x=$x$x done;
top可以看到该脚本内存占用逐步上升:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 30215 root 20 0 871m 501m 1036 R 99.8 26.7 0:38.69 sh
用cgroup控制整个进程的内存资源:
mkdir -p /cgroup/memory/foo echo 1048576 > /cgroup/memory/foo/memory.limit_in_bytes #分配1MB的内存给这个控制组 echo 30215 > /cgroup/memory/foo/tasks
发现之前的脚本被kill掉,当进程试图占用内存超过cgroup限制。就会触发OOM,导致进程被kill掉。实际情况对进程有一个评估,然后对该进程限制超配50%,比如发生内存泄漏等异常情况,才会因为cgroup的限制被kill掉。
也可以通过配置关掉cgroups oom kill进程,通过memory.oom_control来实现(oom_kill_disable 1),但是尽管进程不会被直接杀死,但进程也进入了休眠状态,无法继续执行,仍让无法服务。
3、cgroup管理进程io资源:
跑一个耗io的脚本:
dd if=/dev/sda of=/dev/null &
通过iotop看io占用情况:
30252 be/4 root 284.71 M/s 0.00 B/s 0.00 % 0.00 % dd if=/dev/sda of=/dev/null
用cgroup控制这个进程的io资源:
mkdir -p /cgroup/blkio/foo echo '8:0 1048576' > /cgroup/blkio/foo/blkio.throttle.read_bps_device #8:0对应主设备号和副设备号,可以通过ls -l /dev/sda查看 echo 30252 > /cgroup/blkio/foo/tasks
在用iotop看,读速度降到1M/s:
30252 be/4 root 993.36 K/s 0.00 B/s 0.00 % 0.00 % dd if=/dev/sda of=/dev/null
转载:
https://blog.csdn.net/kwame211/article/details/78730705
https://www.cnblogs.com/yanghuahui/p/3751826.html
https://www.jianshu.com/p/dc3140699e79
https://blog.csdn.net/huang987246510/article/details/80765628