通常大家都应该通过使用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的管理入口不统一了。是否更麻烦了。所以削弱了直接通过配置文件去管理的特性(异想天开)