2016-08-23 追記
docker-engineが1.12.1にバージョンアップして少し修正が入った。
Security
- Allow systemd to run with only --cap-add SYS_ADMIN rather than having to also add --cap-add DAC_READ_SEARCH or disabling seccomp filtering #25567
- 関連issue/PR
しかしseccompのプロファイルで実際に変更されている部分を確認してもmount/umount等は追加されていないため、seccompが有効なホストOS + docker-engineのバージョンの組み合わせで使っている場合は未だ--security_opt seccomp:unconfined
が必要。--cap-add SYS_ADMIN
オプションを渡した時のみseccompの追加設定が不要になる修正っぽい。
Docker for Macやdocker-machineのboot2dockerでは--security_opt seccomp:unconfined
が不要になり--cap-add SYS_ADMIN
だけでOKになった。
Dockerコンテナ内でsystemdを動かすときに--privileged
が必要なのか不要なのかググっても全然はっきりしないので色々実験して調べてみた。
- どのような場合でも
--privileged
は 不要- 代わりに
--cap-add sys_admin
を使う
- 代わりに
- Hostでsystemdが動いている場合は
--cap-add sys_admin
は 不要 - docker-engineを公式レポジトリからパッケージインストールしていて、なおかつHostがseccompに対応している場合は
--security-opt seccomp:unconfined
が 必要 - 考えるのが面倒くさい →
--privileged
でどうぞ- これならどのパターンでも確実に動く
コンテナ起動コマンド具体例
pattern 1
Host: Docker for Mac
docker-engine: 1.12.0
docker run -it --rm --cap-add sys_admin --security-opt seccomp:unconfined centos/systemd:latest
- ホストにsystemdが無いパターン。docker-machineのboot2dockerでも同じはず。
- systemdは動いていないが、seccompは有効っぽい
- Dockerfile内で
VOLUME [ "/sys/fs/cgroup" ]
されていない場合は-v /sys/fs/group
が必要
pattern 2
Host: CentOS 7
docker-engine: 1.12.0 or newer (from docker official repo)
docker run -it --rm -v /sys/fs/cgroup:/sys/fs/cgroup:ro -v /run --security-opt seccomp:unconfined centos/systemd:latest
- CentOS 7はdocker-engine 1.12以降でseccomp有効
-
-v /run
が必要- DockerHubのcentosのページの説明では "There have been reports that if you're using an Ubuntu host, you will need to add -v /tmp/$(mktemp -d):/run in addition to the cgroups mount" と記載があるがCentOS 7のホストでも必要だった
pattern 3
Host: CentOS 7
docker-engine: 1.11 or older (from docker official repo)
docker run -it --rm -v /sys/fs/cgroup:/sys/fs/cgroup:ro -v /run centos/systemd:latest
- ホストにsystemdがあり、なおかつseccompが無効なので殆ど何もオプションが要らないパターン
- DockerHubのcentosのページに記載されているのが正にこのパターン。というかこのパターンの時にしかサイトに記載されているコマンドでは起動出来ない。 なのでハマる。
pattern 4
Host: Fedora 23
docker-engine: 1.10.3-24.gitf476348.fc23 (from fedora repo)
docker run -it --rm -v /sys/fs/cgroup:/sys/fs/cgroup:ro -v /run centos/systemd:latest
- ホストにsystemdあり
- seccomp有効だがdocker-engineにfedoraのパッチが当たっていてsystemd起動に必要な操作がseccompのデフォルトプロファイルに対して追加で許可されているため
--security-opt seccomp:unconfined
が不要
現時点でわかったことメモ
そもそも--privileged
と--cap-add sys_admin
で何がどれくらい違うのか不明だが、--privileged
の方がより強力っぽいので--cap-add sys_admin
の方を使ったほうが良さそう。まあ書いたとおり何が違うのかちゃんと調べてなくて不明なのであまり気にしてもしょうがないかもしれない。
続いて、Hostでsystemdが動いている場合は-v /sys/fs/cgroup:/sys/fs/cgroup:ro
してあげることで上記の--cap-add sys_admin
は不要となるようだ。逆に考えると、Host側でsystemdが動いていない場合には/sys/fs/cgroup
の配下の何かが足りないことが原因で、コンテナを--cap-add sys_admin
しないで起動 した時にコンテナの中のsystemdが何かCAP_SYS_ADMINが必要な操作(恐らくマウント)を実行しようとして失敗しているような感じ。失敗時の出力から察するに必要なのは/sys/fs/cgroup/systemd
?
Docker for Macやboot2dockerでホストに使われているOSではsystemdが動いていないので、この上で動かす場合は必ず--cap-add sys_admin
が必要になる。
これに加えて更に1.10から追加されたseccompの仕組みが関わってくる。seccompはcapで与えた権限をさらにマスクする感じで動く。--security-opt seccomp:unconfined
を指定すると、seccompのマスクを完全に無効化する。これはdocker-engine 1.9以下の時の挙動と全く同じ。dockerのデフォルトのseccompのプロファイルではmount/umountがマスクされて使えないようになっているので、恐らくこれがコンテナ内でのsystemdの起動を妨げている。
ややこしいのが、seccompの対応はホストOSとdocker-engineに依存しており、最初にdocker-engineに実装されたのはCHANGELOGから1.10だということがわかるが、CentOS 7のホストで対応したのは1.12から。なのでCentOS 7なら1.11でも未だseccompは使われておらず、したがって--security-opt seccomp:unconfined
の指定は不要。またdocker公式のパッケージではなくてディストリのパッケージでdocker-engineをインストールした場合、この部分に手が加わっていることがある。具体的にはFedora 23のdocker-1.10では、デフォルトのseccompでmount/unmountが許可されるように編集されていて1、Fedora 23のホストでFedora 23のレポジトリからインストールしたdocker-engineを使う場合は1.10以降でも--security-opt seccomp:unconfined
の指定は不要。
あとsystemd.conf 2015の発表でこれは参考になった。