linux control group

Linux cgroup能够针对某个/某些进程所能使用的系统资源进行限制。如:分配特定比例的cpu时间,I/O时间,可用内存大小等。

cgroup/control group最初由google工程师提出,后被引入linux内核。cgroup可以限制、记录、隔离进程组所使用的物理资源。可以对任意进程执行分组化管理,并提供了对应的管理接口。

Linux中所有进程都有同一个父进程(init进程或systemd)。Linux进程是一种单一的层级结构,每个进程都会继承父进程的一些属性。cgroups与进程概念相似,且子cgroup会继承父cgroup的某些属性。唯一的区别是cgoups的层级为多个,且互不影响。

查看进程树

pstree
ps auxf
ps -aef --forest

注:pstree工具展示的进程树结构较为全面清晰。

cgroups功能说明

限制进程组能够使用的资源

memory子系统能够为进程组设定memory使用上限,内存使用超出配额时会出现OOM(内存溢出)。内核会因内存溢出而强制杀死进程。

进程组的优先级控制

能够使用cpu子系统为进程组分配特定cpu share。

记录进程组占用的资源数量

使用cpuacct子系统记录某个进程组使用的cpu时间。

进程组隔离

利用ns子系统为进程组分配不同的namespace,以实现隔离。不同进程组拥有各自的进程、网络、文件系统挂载空间。

进程组控制

利用freezer子系统将进程组挂起和恢复。

cgroups应用场景

LXC(Linux Container)是基于cgroups之上的轻量级内核虚拟化技术。

Hadoop使用cgroups对mapper和reducer实施资源控制,防止过度消耗导致服务被杀死。

通过cgroups可对同一台服务上的多个mysql实例实施cpu、内存、I/O的隔离。

cgroup实用程序

使用cgroup最简单的方法是安装libcgroup,libcgroup包含大量与cgroup有关的命令行及相关手册

yum install libcgroup

注:以下示例未依赖libcgroup

cgroup概念

task:cgroup中的task代表一个进程。

control group:一组按规则划分后的进程。cgroups资源限制以control group为单位。进程可以加入control group,或从中删除。加入control group的进程,所能使用的资源受当前分组的资源配额限制。

hierarchy:control group能够以树形结构方式继承父节点的属性。

subsystem:subsystem是一个资源控制器,subsystem须附加到hierarchy上,附加subsystem的hierarchy,其上的所有control group,都会受到subsystem的控制。

cgroup子系统

cat /proc/cgroups

cpu:使用调度程序为cgroup任务提供cpu的访问。

cpuacct:产生cgroup任务的cpu资源报告。

cpuset:多核心cpu时为cgroup任务分配独立的cpu和内存。

blkio:限制块设备的输入输出。

devices:控制cgroup任务对设备的访问。

freezer:控制cgroup中的任务。

memory:限制cgroup中任务所使用的内存,及内存占用报告。

net_cls:标记网络包。

ns:名称空间子系统。

在cgroup中与cpu相关的子系统包括:cpusetscpuacctcpu

配置cgroup

使用control group,需先挂载subsystem。在限制进程的资源时,先挂载memory子系统,在memory子系统中创建一个cgroup节点,在节点中,将需要控制的进程id和控制属性一并写入。

[root@kmaster cpu,cpuacct]# mount|grep cpu
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
[root@kmaster cpu,cpuacct]# cd /sys/fs/cgroup/cpu,cpuacct
[root@kmaster cpu,cpuacct]# mkdir temp
[root@kmaster cpu,cpuacct]# cd temp
[root@kmaster temp]# ls

文件列表中以 cpu.前缀开始的文件与cpu相关,直接修改对应文件内容设置cpu限制。以cfs_period_us、cfs_quota_us为例说明设置的方法。

cfs_period_us设置时间周期长度。

cfs_quota_us设置当前cgroup在指定的周期长度内所能使用的CPU时间数,单位都为微秒(us)。

cpu.cfs_period_us:默认-1表示不受限。

cpu.cfs_quota_us:默认-1表示不受限。

[root@kmaster temp]# echo 250000 > cpu.cfs_quota_us
[root@kmaster temp]# echo 250000 > cpu.cfs_period_us

周期为250ms,配额也是250ms,那么此组将每250毫秒获得1个CPU的运行时间。将此组的运行时限制为1个CPU。

在多CPU机器上,将组限制为2个CPU的运行时间。

[root@kmaster temp]# echo 1000000 > cpu.cfs_quota_us
[root@kmaster temp]# echo 500000 > cpu.cfs_period_us

周期为500毫秒,配额为1000毫秒,该组每500毫秒可以获得2个CPU的运行时间。

相关说明可参考文档

将进程加到cgroup中

[root@kmaster temp]# echo 1701 > tasks

示例中将pid为1701的进程加入temp cgroup中。

查看进程的cgroup

ps -O cgroup

或者

cat /proc/PID/cgroup

查看hierarchies

tree /cgroup/