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工具展示的进程树结构较为全面清晰。

功能说明

限制进程组能使用的资源

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

进程组优先级控制

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

记录占用资源数量

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

进程组隔离

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

进程组控制

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

应用场景

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

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

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

cgroup实用程序

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

yum install libcgroup

注:以下示例未依赖libcgroup

概念

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/