LoginSignup
37
39

More than 5 years have passed since last update.

systemd in docker container without --privileged

Last updated at Posted at 2016-08-16

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

しかし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の発表でこれは参考になった。

37
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
39