を使用してDockerで実行されているCentOSイメージのサービスを一覧表示しようとしています
systemctl list-units
しかし、私はこのエラーメッセージを受け取ります:
Failed to get D-Bus connection: Operation not permitted
問題は何か提案はありますか?
systemd
CentOSの上で、この画像を使用します FROM centos/systemd
を使用してDockerで実行されているCentOSイメージのサービスを一覧表示しようとしています
systemctl list-units
しかし、私はこのエラーメッセージを受け取ります:
Failed to get D-Bus connection: Operation not permitted
問題は何か提案はありますか?
systemd
CentOSの上で、この画像を使用します FROM centos/systemd
回答:
私の推測では、non-privileged
コンテナを実行しているということです。systemdにはCAP_SYS_ADMIN機能が必要ですが、セキュリティを強化するために、Dockerはその機能を非特権コンテナにドロップします。
systemdには、コンテナ内のcgroupファイルシステムへのROアクセスも必要です。あなたはそれを追加することができます–v /sys/fs/cgroup:/sys/fs/cgroup:ro
そのため、ここでは、Dockerコンテナー内でsystemdを使用してCentOSを実行する方法に関するいくつかの手順を示します。
FROM centos
MAINTAINER "Yourname" <youremail@address.com>
ENV container docker
RUN yum -y update; yum clean all
RUN yum -y install systemd; yum clean all; \
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
docker build --rm -t centos7-systemd - < mydockerfile
コンテナを実行します docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init
コンテナにsystemdが必要です
[ INFO ] Update UTMP about System Boot/Shutdown is not active. [DEPEND] Dependency failed for Update UTMP about System Runlevel Changes. Job systemd-update-utmp-runlevel.service/start failed with result 'dependency'. [ OK ] Started Journal Service. [ OK ] Reached target System Initialization. [ OK ] Reached target Timers. [ OK ] Listening on D-Bus System Message Bus Socket.
Failed to get D-Bus connection: Operation not permitted
/bin/bash
シェルを取得するためにコンテナを実行していました。ただし、これにより前述のエラーが発生しました。/usr/sbin/init
提案されたとおりに実行してから、シェルで接続するとすべてうまくいった 明らかに私はについてのニュアンスが欠けてい/usr/sbin/init
ます。この答えは、かなりの賛成に値します。
/sys/fs/cgroup:/sys/fs/cgroup
がどこから来ているのかまだわかりません...ゲストフォルダをhistのようにマウントする方法を知っています:/src/:/var/www
しかし、あなたのファイルはどこから来ていますか?私はコードを貼り付けたので、多くのエラーを引き起こしています。私はそれらをどこかに作成する必要があると考えています
これはあなたの質問への直接的な答えではありませんが、実際にはもっと重要かもしれません。ここで他の答えを読んでいたときにこの認識に出会いました。
いくつかの複雑なシステムをDockerに移行した経験がありますが、アプリケーション/サービスまたは「デーモンごと」に1つのDockerコンテナーを用意することが理想です。
これの1つの非常に重要な理由は、Dockerがsystemctlで開始したサービスを完全にシャットダウンしないため、実際、予期しない停電に起因する同じ種類のデータベース破損が発生する可能性があることです。
これについてもう少し詳しく説明します。Dockerは、コンテナに「停止」コマンドを発行すると、すべてのサービスおよびデーモンではなく、CMD / ENTRYPOINTで開始された1つのプロセスのみにSIGTERMシグナルを送信します。そのため、1つのサービスにクリーンシャットダウンの警告が表示され、他のすべてのサービスは不意に終了します。
同じコンテナに2つのサービス(つまり、アプリケーションとPostgreSQLデータベースなど)を絶対にパッケージ化する必要がある場合は、CMD / ENTRYPOINTをSIGTERMをキャッチしてそれらを既知のサービスに再ブロードキャストするスクリプトにする必要があります。それはできますが、機会があれば、ソリューションを再考し、複数のコンテナに分割してみてください。
同じコンテナで複数のサービスを実行する必要がある場合、Supervisordの使用に関する興味深いメモ/ページがDockerサイトにあります。
CentOS:7 Dockerコンテナーでこの問題を修正できました。主にCentOS Dockerイメージプロジェクトのガイドに従っています。
FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
# Install anything. The service you want to start must be a SystemD service.
CMD ["/usr/sbin/init"]
次に、イメージをビルドし、少なくとも次のdocker run
コマンドへの引数を使用して実行します。-v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro
次に、要点は/usr/sbin/init
、Dockerコンテナー内の最初のプロセスでなければならないということです。
したがって、実行する前にいくつかのコマンドを実行するカスタムスクリプトを使用する/usr/sbin/init
場合は、exec /usr/sbin/init
(bashスクリプトで)を使用してスクリプトの最後に起動します。
以下に例を示します。
ADD cmd.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/cmd.sh
CMD ["/usr/local/bin/cmd.sh"]
そして、これは次の内容ですcmd.sh
。
#!/bin/bash
# Do some stuffs
exec /usr/sbin/init # To correctly start D-Bus thanks to https://forums.docker.com/t/any-simple-and-safe-way-to-start-services-on-centos7-systemd/5695/8
あなたが持っている可能性がありSystem is booting up. See pam_nologin(8)
、あなたは、PAMシステムを使用している場合、その場合には、削除する/usr/lib/tmpfiles.d/systemd-nologin.conf
あなたにDockerfile
それがファイル作成されるため、/var/run/nologin
この特定のエラーを生成します。
init / PID 1としてsystemdを起動する必要はありませんでした。他の人が言及したクリーンアップ手順を実行した後、スタートアップスクリプト内からとしてsystemdを起動します/usr/lib/systemd/systemd --system &
。
これにより、systemdは登録されたサービスを開始および起動できましたが、systemctlはD-Busエラーで失敗していました。
私にとって、見つからないリンクは/ run / systemd / systemディレクトリがstrace
なかったことでした。これはsystemctlを実行することで発見されました。
systemctlを実行する前にこのディレクトリを手動で作成すると、systemctlがwork-for-meになります。
sudo
か?