cgroup使用過程中的注意事項

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章