TenForward

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

lxc 『子の親殺し』とコンテナ内での cgroupfs のマウント

『第2回 コンテナ型仮想化の情報交換会@東京』 では時間の関係でお話できなかったことで一番気になっていることの補足を.

そう! 『子の親殺し』(© @m_bird さん) !!

「コンテナからホストのシャットダウンができる」という件,Linux カーネルから見ると,User Namespace で解決という話ですが,現実問題,XFS への User Namespace の実装が 3.12 になりそうなので,現状のディストリビューションではこの問題がカーネル的には解決できません.

上記 Tweet の Reply に少し書いてるのですが,その辺りを少し.

reboot() システムコール

コンテナからホストのシャットダウンが出来る,と言っても,コンテナ内で reboot() システムコールを呼び出してできるわけではありません.Linux 3.4 以降,カーネル側で対策がされています.

ホスト環境以外の PID Namespace 内で reboot() を呼んでも,シグナルが PID Namespace 内の PID 1 のプロセスに送られることになるだけかと.この辺りは以下をご覧ください.

# CentOS 6 なんかでどうなるかは... :-p (試す気にならないので誰か試してレポートしてください ^^;)

Ubuntu 12.04LTS 以降

reboot() を使わなくても /proc/sysrq-trigger を使ってリブートは可能ですが,Ubuntu 12.04LTS で AppArmor のプロファイルが整備されていますので,12.04 以降ではインストールしてそのまま使っている限りは /proc, /sys 辺りに危険なことはコンテナからはできなくなっているはずです ( echo b > /proc/sysrq-trigger 程度しか確認してないですが ^^;).

lxc-1.0 では

lxc-1.0 では新しい設定項目が追加されています (現時点の実装ベースなので,1.0 リリース時には細かい点が変わっているかもしれませんが...).従来は設定ファイルで

lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
lxc.mount.entry = sysfs sys sysfs defaults 0 0

とやるか,設定を外出しにして lxc.mount オプションで外出ししたファイル名を指定していました.従来は cgroupfs のマウントはコンテナ内ではやっていませんでした(出来たのかどうかは試したことない).1.0 以降は lxc.mount.auto という設定が可能になります.例えば,

lxc.mount.auto = proc sys cgroup

のように書くと勝手に lxc-start したときに /proc, /sys, /sys/fs/cgroup をマウントしてくれます.しかも上記設定だと

  • /proc は rw でマウントするが,/proc/sys と /proc/sysrq-trigger は ro でマウントされる
  • /sys は ro でマウントされる
  • /sys/fs/cgroup 以下は,そのコンテナ自身のディレクトリのみ rw でマウントされる

という風に安全な風にマウントされます (自身の cgroup ディレクトリが rw になってるのはコンテナからリソース制限値が緩められたりするので安全かどうかというのは考えものですが ^^;) もちろん,全て ro にするとか,全て rw にするとか,cgroupfs に関しては親ディレクトリを見えるようにするかとか,様々な設定が可能になっています.

この設定だとこんな危険なことも大丈夫 :-)

root@plamo01:/sys/fs/cgroup/memory/lxc# echo b > /proc/sysrq-trigger 
-bash: /proc/sysrq-trigger: Read-only file system

あと,ホストでこんな風に見えている cgroupfs ですが

$ ls /sys/fs/cgroup/memory/lxc/
cgroup.clone_children               memory.max_usage_in_bytes
cgroup.event_control                memory.memsw.failcnt
cgroup.procs                        memory.memsw.limit_in_bytes
lxc_default-1378273955/             memory.memsw.max_usage_in_bytes
memory.failcnt                      memory.memsw.usage_in_bytes
memory.force_empty                  memory.move_charge_at_immigrate
memory.kmem.failcnt                 memory.oom_control
memory.kmem.limit_in_bytes          memory.pressure_level
memory.kmem.max_usage_in_bytes      memory.soft_limit_in_bytes
memory.kmem.slabinfo                memory.stat
memory.kmem.tcp.failcnt             memory.swappiness
memory.kmem.tcp.limit_in_bytes      memory.usage_in_bytes
memory.kmem.tcp.max_usage_in_bytes  memory.use_hierarchy
memory.kmem.tcp.usage_in_bytes      notify_on_release
memory.kmem.usage_in_bytes          plamo01/
memory.limit_in_bytes               tasks

コンテナ内で見るとこんな風に見えます.

# ls /sys/fs/cgroup/memory/lxc/
plamo01/

この辺りは必ずしもカーネルの機能でなくても,ツールキットでも対応可能ですから,この機能追加はすばらしいですね.