通常大家都应该通过使用libcgroup 这样的高级管理接口去玩转cgroup的。而它提供了cgconfig.conf 和cgrules.conf 两个可供配置的文件。
cgconfig.conf:可配置相关的group信息
cgrules.conf: 可配置相应的规则,如某些用户下的某些进程可以放到那个group中被限制
example,cgconfig.conf 的配置如下:
group a.com.cn { cpu { cpu.shares = "100"; } cpuacct { } memory { memory.limit_in_bytes = 100M; memory.soft_limit_in_bytes = 80M; memory.swappiness = 0; } } group b.com.cn { cpu { cpu.shares = "100"; } cpuacct { } memory { memory.limit_in_bytes = 100M; memory.soft_limit_in_bytes = 80M; memory.swappiness = 0; } } group c.com.cn { cpu { cpu.shares = "100"; } cpuacct { } memory { memory.limit_in_bytes = 100M; memory.soft_limit_in_bytes = 80M; memory.swappiness = 0; } }
cgrules.conf 配置如下:
#<user> <controllers> <destination> @auser cpu,cpuacct,memory a.com.cn @buser cpu,cpuacct,memory b.com.cn @cuser cpu,cpuacct,memory c.com.cn # End of file
以上的配置,可以得出结论。以组auser运行的所有进程相应的cpu和内存被隔离到了a.com.cn 这个group组中。
以上都么有任何问题,加入auser、buser、cuser都是php-fpm对应的一个pool的group,而他们运行的用户都为www。若当时建立group的时候同时将www用户放到了这个组里,即:
usermod -G auser www usermod -G buser www usermod -G cuser www
此时,如论怎么运行。都无法发现相应的group中的tasks存在相应组的进程PID。
详细的品味官方文档中关于组的概念:
@ — when prefixed to user, indicates a group instead of an individual user. For example, @admins are all users in the admins group.
也就是说,会将这个组下面所有用户运行的进程全部放到对应的group中。而我们建立的group和user的关系这样就感觉很错论了。我的解决方法是:将www这个用户从各个组中拿出来。即组中没有任何成员。这是将重启类似php-fpm的进程。你会发现cgroup对应的tasks文件中已经有了PID。
另记录Ubuntu12.04 LTS 和 Ubuntu14.04 LTS 中有关cgroup的注意事项:
Ubuntu12.04中启动cgroup的脚本中有一个开启默认group的配置 CREATE_DEFAULT="yes"。 这个选项开启总会启动一个默认的group 叫做sysdefault 。而且会将基本上所有的pid 都扔到这里面去。很讨厌,若不知道这个,肯定以为自己错了。看一下它具体做了什么:
# cat /etc/init/cgconfig.conf
if [ "$CREATE_DEFAULT" = "yes" ]; then /usr/sbin/create_default_cgroups fi
若CREATE_DEFAULT 为YES ,则它会去执行 /usr/sbin/create_default_cgroups。这也是一个shell。
它的行为是去创建一个sysdefault的group。然后将进程放入到这个group中,这个功能会提前与cgrules
因此我们一定要阻止它干坏事。create_default_cgroups 干坏事的代码
# Classify everything to default cgroup. Ignore errors, some processes # may exit after ps is run and before cgclassify moves them. # cgclassify -g $controllers:$defaultcgroup `ps --no-headers -eL o tid` 2>/dev/null || :
在使用Ubuntu 14.04 LTS 时,会发现完全不是那么回事。没有了cgconfig.conf 和cgrules.conf 这两个配置。而且也没有了相应的启动命令。查看Ubuntu的官方文档说,有一个cgmanager这么个东西。就那么一个cgm,感觉特难用。对应运维来说,管理起来不方便了.又要在Ubuntu 14.04 LTS中重新的过一下.
首先安装管理工具吧:
apt-get cgroup-bin cgroup-lite libcgroup1
安装后发现其实在cgrup-lite中有一个相应的启动脚本:
# dpkg -L cgroup-lite /. /usr /usr/share /usr/share/doc /usr/share/doc/cgroup-lite /usr/share/doc/cgroup-lite/copyright /usr/share/doc/cgroup-lite/changelog.gz /usr/bin /etc /etc/init /etc/init/cgroup-lite.conf /bin /bin/cgroups-mount /bin/cgroups-umount /usr/bin/cgroups-mount /usr/bin/cgroups-umount
其中 /etc/init/cgroup-lite.conf 就是这个启动脚本。看一下:
description "mount available cgroup filesystems" author "Serge Hallyn <serge.hallyn@canonical.com>" start on mounted MOUNTPOINT=/sys/fs/cgroup pre-start script test -x /bin/cgroups-mount || { stop; exit 0; } test -d /sys/fs/cgroup || { stop; exit 0; } /bin/cgroups-mount end script post-stop script if [ -x /bin/cgroups-umount ] then /bin/cgroups-umount fi end script
它在开启启动的时候就根据系统支持的各个子系统做好了挂在。跟我们没有毛事了。怎么办? 我还想像原来一样去用。这样管理起来太费劲了。那只能自己动手,丰衣足食了。
更改cgroup-lite.conf 脚本,加入如下配置
test -x /bin/cgroups-mount || { stop; exit 0; } test -d /sys/fs/cgroup || { stop; exit 0; } /bin/cgroups-mount test -f /etc/cgconfig.conf && /usr/sbin/cgconfigparser -l /etc/cgconfig.conf
加入 test -f /etc/cgconfig.conf && /usr/sbin/cgconfigparser -l /etc/cgconfig.conf 就相当于激活了我们原先的cgconfig这个东西了。可以使用cgconfig.conf 的配置了。那cgrules.conf 这个怎么去激活呢? OK,我们将低版本Ubuntu 12.04 LTS 中的相应配置那出来改改吧。
# cat /etc/init/cgred.conf # cgred description "cgred" author "Serge Hallyn <serge.hallyn@canonical.com>" start on started cgroup-lite #注意此处 stop on stopped cgroup-lite #注意此处 pre-start script test -x /usr/sbin/cgrulesengd || { stop; exit 0; } end script script # get default options OPTIONS="" CGRED_CONF=/etc/cgrules.conf if [ -r "/etc/default/cgred" ]; then . /etc/default/cgred fi # Don‘t run if no configuration file if [ ! -s "$CGRED_CONF" ]; then echo "Cgred unconfigured" stop exit 0 fi # Make sure the kernel supports cgroups # This check is retained from the original sysvinit job, but should # be superfluous since we depend on cgconfig running, which will # have mounted this. grep -q "^cgroup" /proc/mounts || { stop; exit 0; } exec /usr/sbin/cgrulesengd --nodaemon $OPTIONS end script
OK 。有了它,我们在/etc/cgrules.conf 这个配置也可以生效了。
后来想了想,为什么Ubuntu 14.04 LTS 会这样呢? CentOS 7 应该也是这样的? 那为什么呢? 为什么高版本后对cgroup的可配置性变差了呢? 而且感觉完全不像让人去参与进去的样子。全是问号。
是否可以认为和Docker有关呢? docker也好使用cgroup去做资源限定。你又想通过配置去做资源限定。对cgroup的管理入口不统一了。是否更麻烦了。所以削弱了直接通过配置文件去管理的特性(异想天开)
本文出自 “扯蛋笔记” 博客,请务必保留此出处http://unixman.blog.51cto.com/10163040/1675426
原文地址:http://unixman.blog.51cto.com/10163040/1675426