sgykfjsm.github.com

Dockerコンテナの中でsystemdを操作したいの注意点

Dockerコンテナを使ってAnsibleのPlaybookをテストする際に、Playbookでsystemctlを実行しようとして以下のようなエラーが発生した。

1
Failed to get D-Bus connection: Operation not permitted

TR;DL

以下の様にコンテナを起動しておいて、それからdocker execsystemctlを実行すればよい。

1
$ docker run --rm --privileged -d -it --security-opt seccomp=unconfined -e "container=docker" centos:7 /sbin/init

説明

今回の問題は大まかに言うとコンテナからホストへのリソースアクセスが制限されていることによるものである。よって、このリソース制限を以下の様に緩和してあげれば良い。なお、これらの設定はプロダクション環境では絶対に行ってはならない。あくまで一時的なテスト環境などでのみ利用するべきであり、プライベート環境であっても持続的に起動するコンテナには付与してはならない。

1. privileged をつける

エラー内容から察するに、どうやらD-Busデーモンへのアクセスに失敗しているっぽい。また、Operation not permittedというよく見るエラーメッセージからは権限の不足が予測される。Dockerはホスト側に色々と依存しているので、きっとコンテナ内部で起動するsystemdはホスト側のD-Busにも依存しているのだろうということで、起動オプションに--privilegedをとりあえずつける。これでホスト側のリソースにほぼ無制限にアクセスできる。当然のことながら、プロダクション環境で--privilegedをつけてはいけない。

cap-add=SYS_ADMIN で十分か?

今回の解決策はGitHubでのIssueコメントを参考にしたけど、コメントで示された--cap-add=SYS_ADMINではダメで、--privilegedでなければならなかった。https://linuxjm.osdn.jp/html/LDP_man-pages/man7/capabilities.7.html によれば、今回のD-Bus Connectionの取得はできそうな気がするけど、もしかしたらSYS_MODULEも必要なのかもしれない。検証してないけれど。

2. security-opt seccomp=unconfined をつける

これは必須ではないけど、Dockerはどんどんセキュリティ(ホスト側へのリソースアクセス)を厳しくしているので、これも付けておいたほうが良い。ここで設定しているseccompは簡単に言うと、コンテナの中での行動に制約を設けるためのプロファイル設定のこと。「行動」とはどういうものを指すのかというと、実行可能なsyscallのこと。具体的な内容は https://docs.docker.com/engine/security/seccomp/#significant-syscalls-blocked-by-the-default-profile を参照すれば良いけど、そんなものがあるんだなぁぐらいの理解でとりあえず良いと思う。ちゃんと使う時は見ておいたほうが良いとは思うけど。

で、結局--security-opt seccomp=unconfinedとは何かというと、プロファイル設定を無効にする、つまり無制限ということになる。これにより、コンテナが実行できるsysycallに制約が無くなる。当然のことながら、これもプロダクション環境で--security-opt seccomp=unconfinedとしてはいけない。

3. /sbin/initでコンテナを起動させる

/sbin/initについては https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Installation_Guide/s2-boot-init-shutdown-init.html を参照すれば良い。要は環境の初期化である。これまでに述べたセキュリティレベルの変更を反映することになる。


docker(そう言えば今はmodyプロジェクトと呼ばれている)は昔からコンテナからホストへのリソースアクセスについて多方面から警告されており、今回の問題もそれらの警告を受けたものなのだと思う。dockerは便利でなんでも出来るように思えるが、実際には微妙なバランスを試行錯誤しながら実現されているので、今後のアップデートでも特にリソースアクセスに関する制約を始めとするセキュリティには注目しておかなければならない。