さきほどの話ですが、PostgreSQLのコマンドを確認したかったので、PostgreSQLをインストールしました。 ちょうどLinuxコマンドの動作確認用に、手元でCent OS 7のDockerを起動していたので、そこにインストールして起動します。
イメージとしては、こんな感じです。
$ docker run -it centos:centos7 /bin/bash [root@15eba360665a /]# whoami root [root@15eba360665a /]# yum install postgresql-server ... Installed: postgresql-server.x86_64 0:9.2.24-4.el7_8 ... [root@15eba360665a /]# systemctl start postgresql Failed to get D-Bus connection: Operation not permitted
PostgreSQLを起動しようとしたのですが、見事に失敗しました。
Failed to get D-Bus connection: Operation not permitted
エラーメッセージで検索したところ、2つの原因がわかりました。
- リソースへのアクセス権限が足りない
- systemdが起動していない
上記のエラーを解決する方法
同じエラーに遭遇した方のページに、解決方法が書いてありました。
$ docker run -d --privileged --name docker_test centos /sbin/init $ docker exec -it docker_test /bin/bash # yum install -y httpd # systemctl start httpd # systemctl status httpd
DockerでCentOS7起動時にsystemctlが動かないとき
普通に適当(雑の方の意味)に起動するだけだと動かないのです。
対策として下記の3つを使用することで、systemctlが使用できるようになります。
- --privilegedを使用する。
- /sbin/initで起動する。
- 上記に合わせ、-itではなく-dで起動し、起動後にexecする。
-—privilegedを使用する
systemctl実行時のエラーメッセージには、「D-Bus connection: Operation not permitted」と書いてあります。 このことから、権限が足りてないことまではわかります。
そこで登場するのが、『--privileged』というコマンドオプションです。 『privileged』は日本語に訳すと特権という意味で、起動するコンテナに特権を付与します。
2.コンテナに特権を与える場合
コンテナからホスト上のファイルへアクセスする際に最も簡単なものがこちらです。
コンテナに特権を付与することで、ホスト上のすべてのデバイスへのアクセスする権限が与えられます。
以下のようにdocker runのオプションとして「--privileged」と入力すると特権が付与されます。
https://armadillo.atmark-techno.com/blog/10899/4191 より
privilegedは危険を伴うオプションである
『--privileged』を付与することによって、無事にPostgreSQLを起動することに成功しました。 しかしながら、さらに調査を続けたところ、『--privileged』は危険を伴うオプションのようです。
Dockerコンテナを特権モードで実行することが危険な理由
Docker の「Privileged(特権)」コンテナ(以下、特権コンテナ)は、簡潔に言えば、ホストコンピュータに対するすべてのルート権限を備えたコンテナであり、通常のコンテナではアクセスできないリソースへのアクセスが可能となります。
https://blog.trendmicro.co.jp/archives/23577 より
トレンドマイクロ社が専用記事で警告しているくらいですから、鬼気迫るものがあります。 『--privileged』は、あくまで今回のような一時的な使用に限定し、本番環境で使用しないほうが無難です。
/sbin/init経由で、systemdを起動する
initはLinuxカーネルの起動後、最初に実行されるプロセスです。 Qiitaのinitまとめ(ざっくり)が、簡潔にまとめてありオススメです。
initとは
- initは他のプロセスを起動させる役割を持っており, 全てのプロセスの親である.
- Linuxカーネルの起動後, 一番最初に起動される.
- PIDは1が付与されている.
https://qiita.com/h_tyokinuhata/items/26b7dd3526e7061596b9 より
なお、実際にCent OS7で確認したところ、実体はsystemdへのシンボリックリンクになっておりました。
[root@0467571e7b9b ~]# ls -l /sbin/init lrwxrwxrwx 1 root root 22 Aug 9 21:38 /sbin/init -> ../lib/systemd/systemd
単純に起動したdockerコンテナは、必要最小限のプロセスしか実行されない
『/sbin/init』のプロセスが起動していないことは、実際にプロセスを確認するとわかります。 コンテナ実行時に指定したコマンド以外は、見事に何もプロセスがありません。
$ docker run --rm -it centos:centos7 /bin/bash [root@d0090488dced /]# ps axuw -w USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 5.0 0.1 11840 2876 pts/0 Ss 08:02 0:00 /bin/bash root 14 0.0 0.1 51768 3540 pts/0 R+ 08:02 0:00 ps axuw -w
まとめ
Dockerコンテナは、必要最小限の権限付与とプロセスしか起動しないため、通常のサーバーとは異なる特性があります。 本記事のようなケースでは、素直に公式のPostgreSQLイメージを使おうと心に誓いました。