通常大家都應該通過使用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 <[email protected]>" 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 <[email protected]>" 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的管理入口不統一了。是否更麻煩了。所以削弱了直接通過配置文件去管理的特性(異想天開)