分类: 系统运维
2014-11-20 15:33:32
1. Control Groups简介 (Cgroups)
Red Hat Enterprise Linux 6 提供了一个新的内核特性: CONTROL GROUPS(Cgroups),它为内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:cpu,memory,IO等等)的机制。
CONTROL GROUPS包括如下子系统:
blkio -- 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等)。
cpu -- 这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。
cpuacct -- 这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。
cpuset -- 这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。
devices -- 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。
freezer -- 这个子系统挂起或者恢复 cgroup 中的任务。
memory -- 这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。
net_cls -- 这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。
ns -- 名称空间子系统。
2. 使用 Control Groups
# yum install –y libcgroup
# service cgconfig start
# service cgconfig stop
/etc/cgconfig.conf在安装Cgroup后会自动建立,文件包含2部分功能----mount and group:
# cat /etc/cgconfig.conf
mount {
cpuset = /cgroup/cpuset;
cpu = /cgroup/cpu;
cpuacct = /cgroup/cpuacct;
memory = /cgroup/memory;
devices = /cgroup/devices;
freezer = /cgroup/freezer;
net_cls = /cgroup/net_cls;
blkio = /cgroup/blkio;
}
它将在服务启动后创建和挂载虚拟文件系统,等价于命令:
# mkdir -p /cgroup/cpuset
# mount -t cgroup -o cpuset cpuset /cgroup/cpuset
…….
Example:
group daemons {
cpuset {
cpuset.mems = 0;
cpuset.cpus = 0;
}
}
group daemons/sql {
perm {
task {
uid = root;
gid = sqladmin;
} admin {
uid = root;
gid = root;
}
}
cpuset {
cpuset.mems = 0;
cpuset.cpus = 0;
}
}
相当于在shell里面执行:
# mkdir -p /cgroup/cpuset/daemons/sql
# chown root:root -R /cgroup/cpuset/daemons
# chown root:sqladmin /cgroup/cpuset/daemons/sql/tasks
# echo $(cgget -n -v -r cpuset.mems /) > /cgroup/cpuset/daemons/cpuset.mems
# echo $(cgget -n -v -r cpuset.cpus /) > /cgroup/cpuset/daemons/cpuset.cpus
# echo 0 > /cgroup/cpuset/daemons/sql/cpuset.mems
# echo 0 > /cgroup/cpuset/daemons/sql/cpuset.cpus
配置文件所在的目录。下面的文件名以conf作为后缀,语法参见/etc/cgconfig.conf。
cgconfig服务启动时第一个读取的文件是/etc/cgconfig.conf,然后是该目录下的*.conf文件。文件的解析没有排序。不要在多个文件内定义同一个group。
# lssubsys -am
ns
perf_event
net_prio
cpuset /cgroup/cpuset
cpu /cgroup/cpu
cpuacct /cgroup/cpuacct
memory /cgroup/memory
devices /cgroup/devices
freezer /cgroup/freezer
net_cls /cgroup/net_cls
blkio /cgroup/blkio
第一列为支持的子系统名称,后面的表示已经挂载的目录。
也可查看指定的子系统:
# lssubsys -m subsystems
subsystems为指定的子系统名称。
对于已经挂载的子系统,同样可以再次挂载:
# mount -t cgroup -o remount,cpu cpu_and_mem /cgroup/cpu
# umount /cgroup/ cpu
2.5.1 创建 Control Groups
语法:cgcreate -t uid:gid -a uid:gid -g subsystems:path
-t
-a
-g subsystems:path group名称及挂载路径
Example:
# cgcreate -g cpu,net_cls:/test-subgroup
创建了cpu及net_cls子系统并挂载到/test-subgroup。
2.5.2 删除 Control Groups
语法:cgdelete subsystems:path
Example:
# cgcreate cpu,net_cls:/test-subgroup
2.5.3 设置 Control Groups参数
语法:cgset -r parameter=value path_to_cgroup
如果cpuset 已经挂载到 /cgroup/cpu_and_mem/ 并且存在目录/cgroup/cpu_and_mem/group1,那么可以:
# cgset -r cpuset.cpus=0-1 group1
也可以:
# echo ‘0-1’ > /cgroup/cpu_and_mem/group1/cpuset.cpus
2.5.4 复制 Control Groups参数
也可以对一个已经存在并设置好的参数进行复制。
语法:cgset --copy-from path_to_source_cgroup path_to_target_cgroup
# cgset --copy-from group1/ group2/
这样croup2的参数将从group1复制而来。
2.6 应用Control Groups
设置好参数后,就可以对进程应用Cgroup。
语法:cgclassify -g subsystems:path_to_cgroup pidlist
# cgclassify -g cpu,memory:group1 1701
ID为1701的进程进程将被应用到cpu及memory子系统中的group1中。也就是说ID为1701的进程将受到cpu及memory子系统中的group1中所设定参数的限制。
也可以:
# echo 1701 > /cgroup/cpu_and_mem/group1/tasks
2.7 cgred Service
Cgred 服务会启动一个守护进程 cgrulesengd ,它可根据在 /etc/cgrules.conf 文件中设定的参数将任务移动到 cgroup 中。/etc/cgrules.conf 文件可以使用以下两个格式之一:
User hierarchies control_group
例如:
maria devices staff
用户maria 的进程根据在 staff cgroup 中指定的参数访问设备子系统。
启动/停止方法:service cgred start/stop
/etc/cgrules.conf 文件中的条目可包括以下特殊符号:
@ - 当在 user 使用前缀时,代表是一个组群而不是单独用户。例如:@admins 是 admins 组群中的所有用户。
* - 代表“所有”。例如:subsystem 字段中的 * 代表所有子系统。
% - 代表与以上行中项目相同的项目。例如:
@adminstaff devices /admingroup
@labstaff % %(等价于
@labstaff devices /admingroup)
2.8 将进程放进cgroup中
语法:cgexec -g subsystems:path_to_cgroup command arguments
subsystems 是用逗号分开的子系统列表或者用 * 表示所有可用的子系统。
path_to_cgroup 是该 cgroup 的路径。
command 是要运行的命令。
arguments 是该命令所有参数。
还可以在 command 前面添加 -- sticky 将所有子进程放在同一 cgroup 中。如果没有设定这个选项,且 cgred 守护进程正在运行,则将根据在/etc/cgrules.conf 中的设置将子进程分配到 cgroup 中。而该进程本身仍保留在启动它的 cgroup 中。
Example:
# cgexec -g cpu:group1 firefox
这样firefox的进程将被放到cpu子系统的group1中。
也可以:
# echo $$ > /cgroup/lab1/group1/tasks
这样的话,不但firefox进程会被放到相应的cgroup中;在当前窗口的所有进程均会被放到该cgroup中。如果不希望这样的后果,可以:
# sh -c "echo \$$ > /cgroup/cpu_and_mem/group1/tasks && firefox"
2.8.1 将服务放进cgroup中
要将一个服务放到cgroup中,服务需要具备以下条件:
ⅰ可以使用 /etc/sysconfig/servicename 文件。
ⅱ必须使用 /etc/init.d/functions 的 daemon() 功能启动该服务
然后编辑文件/etc/sysconfig/servicename,添加内容:CGROUP_DAEMON="subsystem:control_group"
Example:
# cat /etc/sysconfig/httpd
CGROUP_DAEMON="cpuset:group1"
# service httpd start
httpd服务将被加到cpuset子系统的group1中。
2.9 工具
2.9.1 生成配置文件之cgsnapshot
列出当前配置
# cgsnapshot –s
输出配置文件
# cgsnapshot -f ~/test/cgconfig_test.conf
不要将输出文件直接输出到 /etc/cgconfig.conf,因为 -f 参数将会覆盖任何文件。
也可以为子系统创建配置文件。通过指定一个子系统的名称,则输出将包含于该子系统的相应配置的:
# cgsnapshot cpuacct
设置黑名单
# cgsnapshot -b ~/test/my_blacklist.conf
如果不指定文件,则使用默认文件/etc/cgsnapshot_blacklist.conf。
设置白名单
# cgsnapshot -w ~/test/my_whitelist.conf
没有用默认文件。
另,在使用cgsnapshot –f时,如果既不指定黑名单,也不指定白名单,那么会有相关的警告信息。因此可以使用 -t 参数。
2.10 查找某个属于cgroup的进程
# ps -O cgroup
如果已知进程的PID,则可以:
# cat /proc/PID/cgroup
列出系统中的cgroup
# lscgroup
也可以:
# lscgroup controller:path
Example:
# lscgroup cpuset:daemons
显示具体 cgroup 的参数:
# cgget -r parameter list_of_cgroups
Example:
# cgget -r cpuset.cpus -r memory.limit_in_bytes group1 group2
显示 cgroup lab1 和 lab2 的 cpuset.cpus 和 memory.limit_in_bytes 值。
如果不知道 parameter ,可以:
# cgget -g cpuset /
2.11. 卸载控制组群
要清除整个 cgroup 文件系统,请使用 cgclear 命令。
如果有些group没有写在配置文件中那么使用该命令后想要再次恢复,那么只能手动操作。