今回は、
LXCでは設定ファイル内でcgroupの設定を行い、
しかし、
LXCでは、lxc.
という設定を使用して、
しかし、lxc.
は使用できません。
そこでLXC 1.
その後、
それでは、
cgmanager
cgmanagerは、
cgroupはファイルシステムをマウントし、
cgmanagerは、
LXCコンテナは、
また、
ところがコンテナの利用が進み、
LXCをインストールする最も主要なディストリビューションであるUbuntuでもinitがUpstartからsystemdに変更されましたので、
つまりUbuntuをはじめとして、
また、
そこで、
LXCFS
前述のようなcgmanagerが持つ問題を解決するとともに、
LXCFSはふたつの機能を持っています。
- コンテナ向けのcgroupfsツリーの提供
- コンテナ向けの/proc以下のファイルの提供
LXCFSはホスト上で実行されます。ホスト上でどのようにLXCFSが実行され、
$ sudo add-apt-repository ppa:ubuntu-lxc/lxc-lts
$ sudo apt-get update
$ sudo apt-get install lxc lxcfs
$ sudo apt-get remove cgmanager (cgmanagerは削除する)
LXCFSがどのように起動しているかを確認してみましょう。
$ grep lxcfs /proc/self/mounts lxcfs /var/lib/lxcfs fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other 0 0
以上のように/var/
にマウントされています。/var/
を見てみると、
$ ls /var/lib/lxcfs cgroup proc $ ls /var/lib/lxcfs/cgroup/ blkio cpuacct devices hugetlb name=systemd cpu cpuset freezer memory perf_event $ ls /var/lib/lxcfs/proc cpuinfo diskstats meminfo stat swaps uptime
以上のように/var/
以下にはcgroup
とproc
というふたつのディレクトリが存在し、cgroup
以下は各サブシステムごとのディレクトリと、proc
以下は、
LXCコンテナでのLXCFSの利用
以上のように起動したLXCFSが、
lxcfsパッケージをインストールすると、/usr/
というファイルがインストールされます。このファイルには第23回と第24回で説明したフックが設定されています。
$ cat /usr/share/lxc/config/common.conf.d/00-lxcfs.conf lxc.hook.mount = /usr/share/lxcfs/lxc.mount.hook lxc.hook.post-stop = /usr/share/lxcfs/lxc.reboot.hook
このうちコンテナ起動時に読み込まれる/usr/
を見てみると、
:(略)
if [ -d /var/lib/lxcfs/proc/ ]; then
for entry in /var/lib/lxcfs/proc/*; do
[ -e "${LXC_ROOTFS_MOUNT}/proc/$(basename $entry)" ] || continue
mount -n --bind $entry ${LXC_ROOTFS_MOUNT}/proc/$(basename $entry)
done
fi
:(略)
以上で挙げた部分は/proc
以下でLXCFSが対象とするファイルをバインドマウントしている部分ですが、
それでは、
コンテナへのcgroupfsツリーの提供
ひとつめの機能は、
バインドマウントされたcgroupfsツリーが、
ただし、
それではLXCFSがどのようにcgroupfsのツリーをコンテナに見せているかを見てみましょう。
まずはコンテナを起動します。ここではxenial01
という名前の非特権コンテナを起動してみました。
$ lxc-start -n xenial01 $ lxc-ls -f NAME STATE AUTOSTART GROUPS IPV4 IPV6 xenial01 RUNNING 0 - 10.0.3.77 -
まず、
$ sudo mkdir /sys/fs/cgroup/cpu/test01 ("test01" cgroupを作成) $ ls -d /sys/fs/cgroup/cpu/test01 (作成されたことを確認) /sys/fs/cgroup/cpu/test01
起動したコンテナ内でcpuサブシステム以下のcgroupがどのようになっているかを見てみましょう。
$ lxc-attach -n xenial01 -- find /sys/fs/cgroup/cpu -type f (/sys/fs/cgroup以下の全ファイルを表示) /sys/fs/cgroup/cpu/user/1000.user/1.session/lxc/xenial01/cpu.stat /sys/fs/cgroup/cpu/user/1000.user/1.session/lxc/xenial01/cpu.cfs_period_us /sys/fs/cgroup/cpu/user/1000.user/1.session/lxc/xenial01/cpu.cfs_quota_us /sys/fs/cgroup/cpu/user/1000.user/1.session/lxc/xenial01/cpu.shares /sys/fs/cgroup/cpu/user/1000.user/1.session/lxc/xenial01/notify_on_release /sys/fs/cgroup/cpu/user/1000.user/1.session/lxc/xenial01/tasks /sys/fs/cgroup/cpu/user/1000.user/1.session/lxc/xenial01/cgroup.clone_children find: ‘/sys/fs/cgroup/cpu/user/1000.user/1.session/lxc/xenial01/cgroup.event_control’: Permission denied /sys/fs/cgroup/cpu/user/1000.user/1.session/lxc/xenial01/cgroup.procs (コンテナ用のcgroup以下にのみcgroup用ファイルが存在している) $ lxc-attach -n xenial01 -- ls /sys/fs/cgroup/cpu/ user $ lxc-attach -n xenial01 -- ls /sys/fs/cgroup/cpu/user 1000.user (他のcgroupには本来存在するはずのcgroup用のファイルがない)
非特権コンテナですので、user/
に、xenial01
というグループ以下にはcgroup用のファイルが存在しますが、
このように、lxc.
でcgroup:mixed
を指定した場合と同じです。
ここでホストからcpuサブシステム以下に存在するcgroupを見てみます。
$ find /sys/fs/cgroup/cpu -type d (cpu以下のcgroupを確認) /sys/fs/cgroup/cpu /sys/fs/cgroup/cpu/test01 (コンテナ内から見えなかったcgroupが存在している) /sys/fs/cgroup/cpu/lxc (コンテナ内から見えなかったcgroupが存在している) /sys/fs/cgroup/cpu/user /sys/fs/cgroup/cpu/user/1000.user /sys/fs/cgroup/cpu/user/1000.user/1.session /sys/fs/cgroup/cpu/user/1000.user/1.session/lxc /sys/fs/cgroup/cpu/user/1000.user/1.session/lxc/xenial01 /sys/fs/cgroup/cpu/user/1000.user/c1.session $ ls /sys/fs/cgroup/cpu cgroup.clone_children cgroup.procs cpu.cfs_period_us cpu.shares lxc release_agent test01 cgroup.event_control cgroup.sane_behavior cpu.cfs_quota_us cpu.stat notify_on_release tasks user (各cgroup直下にもcgroup用ファイルが存在している)
cpu以下には、lxc
や、test01
というcgroupが存在しており、
このようにホスト上に存在するコンテナと関係のないcgroupは見せずに、
それでは、lxc.
で提供されるcgroupと、
筆者はLXCFSの実装をきちんと読んでないのではっきりとはわからないのですが、lxc.
で起動したコンテナでは、
$ lxc-attach -n xenial01 -- journalctl -b -p 4 (コンテナ内のsystemdのログを見てみる) -- Logs begin at Mon 2016-11-21 12:17:16 UTC, end at Mon 2016-11-21 12:17:16 UTC. -- Nov 21 12:17:16 xenial01 systemd[1]: Failed to reset devices.list on /user/1000.user/1.session/lxc/xenial01/system.slice/systemd-journal-flush.service: Operation not permitted Nov 21 12:17:16 xenial01 systemd[1]: Failed to reset devices.list on /user/1000.user/1.session/lxc/xenial01/system.slice/networking.service: Operation not permitted Nov 21 12:17:16 xenial01 systemd[1]: Failed to reset devices.list on /user/1000.user/1.session/lxc/xenial01/system.slice/systemd-tmpfiles-setup.service: Operation not permitted Nov 21 12:17:16 xenial01 systemd[1]: Failed to reset devices.list on /user/1000.user/1.session/lxc/xenial01/system.slice/systemd-journal-flush.service: Operation not permitted (同様のエラーが多数記録されている)
コンテナへの/proc以下のファイルの提供
ふたつめの機能は、
これまでもPIDやマウント名前空間により、
このため、
LXCFSを使うと、/proc
以下の対象となるファイルが読まれた場合に、
LXCFSでは以下のファイルでコンテナ向けの値を提供します。
- /proc/
cpuinfo - /proc/
diskstats - /proc/
meminfo - /proc/
stat - /proc/
swaps - /proc/
uptime
では、
ホストは以下のようにCPUが2つ、
$ grep processor /proc/cpuinfo processor : 0 processor : 1 $ grep MemTotal /proc/meminfo MemTotal: 1017724 kB
このホスト上で実行するコンテナには以下のようなcgroup関連の設定を行っています。
$ sudo grep cgroup /var/lib/lxc/xenial01/config lxc.cgroup.memory.limit_in_bytes = 512M (メモリ制限を512MBに) lxc.cgroup.cpuset.cpus = 0 (CPUは0番のみ使用)
LXCFSが動作していない場合
まずは比較のためにLXCFSを停止させた状態で確認してみましょう。lxcfsパッケージがインストールされた状態では、
$ service lxcfs status lxcfs stop/waiting $ sudo lxc-start -n xenial01
コンテナ内でいくつか/proc
以下のファイルを見てみましょう。
$ sudo lxc-attach -n xenial01 -- grep processor /proc/cpuinfo processor : 0 processor : 1 $ sudo lxc-attach -n xenial01 -- grep MemTotal /proc/meminfo MemTotal: 1017724 kB
以上のようにホストと同じ値が見えています。/proc/
ファイルの中身とfreeコマンドを実行した結果も見ておきましょう。
$ cat /proc/uptime ; sudo lxc-attach -n xenial01 -- cat /proc/uptime 1322.19 563.45 1322.22 563.45 $ free -m (ホスト上で実行) total used free shared buffers cached Mem: 993 724 269 0 43 583 -/+ buffers/cache: 97 896 Swap: 1019 0 1019 $ sudo lxc-attach -n xenial01 -- free -m (コンテナ上で実行) total used free shared buffers cached Mem: 993 725 268 0 43 583 -/+ buffers/cache: 98 895 Swap: 1019 0 1019
コマンドを実行したタイミングが違いますのでぴったり同じにはなりませんが、/proc/
の中身はホストと同じようですし、
LXCFSが動作している場合
では、
$ service lxcfs status (lxcfsの起動を確認)
lxcfs start/running, process 7965
$ sudo lxc-start -n xenial01
$ sudo lxc-attach -n xenial01 -- grep processor /proc/cpuinfo
processor : 0
$ sudo lxc-attach -n xenial01 -- grep MemTotal /proc/meminfo
MemTotal: 524288 kB
以上のようにCPU数、
ホストとコンテナの/proc/
ファイルの中身を見てみると、
$ cat /proc/uptime ; sudo lxc-attach -n xenial01 -- cat /proc/uptime 839.24 563.43 217.0 217.0
freeコマンドもコンテナの値を出力していますね。totalだけでなくusedやfreeの値も異なります。
$ free -m total used free shared buffers cached Mem: 993 215 778 0 37 118 -/+ buffers/cache: 59 934 Swap: 1019 0 1019 $ sudo lxc-attach -n xenial01 -- free -m total used free shared buffers cached Mem: 512 6 505 0 0 0 -/+ buffers/cache: 6 505 Swap: 1019 0 1019
以上のようにCPU数、
ホストとコンテナの/proc/
ファイルの中身を見てみると、
$ cat /proc/uptime ; sudo lxc-attach -n xenial01 -- cat /proc/uptime 839.24 563.43 217.0 217.0
freeコマンドもコンテナの値を出力していますね。totalだけでなくusedやfreeの値も異なります。
$ free -m total used free shared buffers cached Mem: 993 215 778 0 37 118 -/+ buffers/cache: 59 934 Swap: 1019 0 1019 $ sudo lxc-attach -n xenial01 -- free -m total used free shared buffers cached Mem: 512 6 505 0 0 0 -/+ buffers/cache: 6 505 Swap: 1019 0 1019
以上のようにLXCFSにより、
コンテナ上でリソースの消費状況などをモニタリングする際に、
まとめ
今回はLXCコンテナ内でcgroupを操作するための仕組みの変遷と、
LXCFSは今回説明したように、
これは同様の機能がカーネルに実装されたためです。次回はこの機能について紹介したいと思います。
第10回 コンテナ型仮想化の情報交換会@東京
筆者が主催している
勉強会を始めたころは、
今回もWindowsのコンテナのお話や、
当日の動画の公開や資料へのリンクを以下にまとめてありますので、