『第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/
この辺りは必ずしもカーネルの機能でなくても,ツールキットでも対応可能ですから,この機能追加はすばらしいですね.