TenForward

技術ブログ。はてなダイアリーから移転しました

cgmanager を試す (2)

cgmanager を試す (1) - TenForwardの日記 の続編.Ubuntu 14.04 LTS で LXC をインストールしたときに一緒に入る cgmanager を使ってみます.前回試してからだいぶ変わっている感じがしますね.

cgmanager を試すというより,cgmanager サポートでコンパイルされ,cgmanager が起動した状態での LXC 1.0 の cgroup の色々です.

Ubuntu 14.04 の cgroupfs

OpenSSH server のみインストールした Server 版の cgroup を見てみると,まず LXC をインストールしても cgroup-lite パッケージ *1がインストールされなくなり cgmanager が取って代わっているのがわかります.

/sys/fs/cgroup の下もすっきりしていて

root@lxctest04:~# ls /sys/fs/cgroup/
cgmanager  systemd
root@lxctest04:~# ls -F /sys/fs/cgroup/cgmanager/
sock=

/sys/fs/cgroup/cgmanager 以下は cgmanager が待ち受けるソケットがあるだけです./sys/fs/cgroup/systemd の下も systemd 自身が使う cgroup が作成されているだけで,各種サブシステムもマウントされていません (cgroupfs が none オプションでマウントされている).

root@lxctest04:~# find /sys/fs/cgroup/ -type d
/sys/fs/cgroup/
/sys/fs/cgroup/systemd
/sys/fs/cgroup/systemd/user
/sys/fs/cgroup/systemd/user/1000.user
/sys/fs/cgroup/systemd/user/1000.user/3.session
/sys/fs/cgroup/cgmanager
root@lxctest04:~# mount -l | grep cgroup
none on /sys/fs/cgroup type tmpfs (rw)
systemd on /sys/fs/cgroup/systemd type cgroup (rw,noexec,nosuid,nodev,none,name=systemd)

あれ? コンテナ起動したときの cgroup はいずこへ?

cgmanager のマウント名前空間

cgmanager の管理する cgroup については 公式サイト に記述があります.

This daemon runs on the host, mounts cgroupfs into a separate mount namespace (so it's invisible from the host), binds /sys/fs/cgroup/cgmanager/sock for incoming DBus queries and generally handles all clients running directly on the host.

というわけで見てみました.ここで何を見てるかはこちら(Linux 3.8 で改良された Namespace 機能と lxc-attach コマンド - TenForwardの日記) をどうぞ (手抜き).

root@lxctest04:~# ls -l /proc/1/ns/mnt 
lrwxrwxrwx 1 root root 0 Apr 18 17:00 /proc/1/ns/mnt -> mnt:[4026531840] (Host の mount ns)
root@lxctest04:~# ls -l /proc/`pgrep cgmanager`/ns/mnt
lrwxrwxrwx 1 root root 0 Apr 18 17:16 /proc/232/ns/mnt -> mnt:[4026532154] (cgmanager の mount ns)

つまり cgmanager は違うマウント名前空間で動いている事になります.なのでホスト上で mount -l しても cgmanager のいる名前空間のマウントポイントは見えません.で,ホストから見える /sys/fs/cgroup/cgmanager/sock がそこへの入り口となります.

cgmanager の管理する cgroupfs

cgmanager は /run/cgmanager/fs 以下に cgroupfs を作成,マウントするようです.ホスト上では当たり前ですが見えません.以下のように各サブシステムのディレクトリは作成されていますが,その下は空です.

root@lxctest04:~# ls -F /run/cgmanager/fs
blkio/  cpuacct/  devices/  hugetlb/  none,name=systemd/
cpu/    cpuset/   freezer/  memory/   perf_event/
root@lxctest04:~# ls -F /run/cgmanager/fs/memory/

ここで util-linux 2.23 以降に含まれる nsenter コマンドの出番です.が Ubuntu 14.04 のは 2.20 なので使えませんので,別の場所から持ってきました.これは setns(2) を使って,別の名前空間で動いているプロセスと同じ名前空間上でコマンドを実行するためのコマンドです.

root@lxctest04:~# ./nsenter -t `pgrep cgmanager` --mount -- ls -F /run/cgmanager/fs/memory/ 
cgroup.clone_children  memory.max_usage_in_bytes	memory.swappiness
cgroup.event_control   memory.move_charge_at_immigrate	memory.usage_in_bytes
cgroup.procs	       memory.numa_stat			memory.use_hierarchy
cgroup.sane_behavior   memory.oom_control		notify_on_release
memory.failcnt	       memory.pressure_level		release_agent
memory.force_empty     memory.soft_limit_in_bytes	tasks
memory.limit_in_bytes  memory.stat			user/
root@lxctest04:~# ./nsenter -t 232 --mount -- find /run/cgmanager/fs/memory/ -type d
/run/cgmanager/fs/memory/
/run/cgmanager/fs/memory/user
/run/cgmanager/fs/memory/user/1000.user
/run/cgmanager/fs/memory/user/1000.user/6.session

先にホストの名前空間では空だった /run/cgmanager/fs/memory 以下が,cgmanager と同じマウント名前空間で見てみるとちゃんと cgroupfs がマウントされているのがわかります.systemd と同じようにユーザ用の cgroup も作成されていますね.

コンテナを実行してみる

root@lxctest04:~# lxc-start -n ubuntu01 -d
root@lxctest04:~# lxc-ls --fancy
NAME      STATE    IPV4       IPV6  AUTOSTART  
---------------------------------------------
ubuntu01  RUNNING  10.0.3.18  -     NO         

このようにコンテナを実行してみて先ほどの /run/cgmanager 以下を見てみると,確かにコンテナ用のグループが出来ています.

root@lxctest04:~# ./nsenter -t 232 --mount -- ls -F /run/cgmanager/fs/memory/lxc/ubuntu01
cgroup.clone_children  memory.max_usage_in_bytes	memory.stat
cgroup.event_control   memory.move_charge_at_immigrate	memory.swappiness
cgroup.procs	       memory.numa_stat			memory.usage_in_bytes
memory.failcnt	       memory.oom_control		memory.use_hierarchy
memory.force_empty     memory.pressure_level		notify_on_release
memory.limit_in_bytes  memory.soft_limit_in_bytes	tasks

このグループに対する操作ですが,普通に lxc-cgroup で

root@lxctest04:~# lxc-cgroup -n ubuntu01 memory.limit_in_bytes
18446744073709551615
root@lxctest04:~# lxc-cgroup -n ubuntu01 memory.limit_in_bytes "512M"
root@lxctest04:~# lxc-cgroup -n ubuntu01 memory.limit_in_bytes
536870912

もしくは cgmanager-utils パッケージを入れるとこんな感じで操作できそうです.詳しくは man cgm でね :-)

root@lxctest04:~# cgm getvalue memory '/lxc/ubuntu01' memory.limit_in_bytes
method return sender=(null sender) -> dest=(null destination) reply_serial=1
   string "536870912"

*1:cgroupの各サブシステムを /sys/fs/cgroup 以下にディレクトリを作ってマウントするシェルスクリプトがありました