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"