D-Bus接続の取得に失敗しました:操作は許可されていません


29

を使用してDockerで実行されているCentOSイメージのサービスを一覧表示しようとしています

systemctl list-units  

しかし、私はこのエラーメッセージを受け取ります:

Failed to get D-Bus connection: Operation not permitted

問題は何か提案はありますか?


1
あなたは使用しませんでしたsudoか?
マイケルハンプトン

systemdを使用する必要がない場合は、使用しないでください。CMDまたはRUNでアプリケーションを起動するか、ラッパースクリプトを使用してアプリケーションを起動してください。
-nelaaro

あなたが必要な場合はsystemdCentOSの上で、この画像を使用します FROM centos/systemd
james.garriss

回答:


24

私の推測では、non-privilegedコンテナを実行しているということです。systemdにはCAP_SYS_ADMIN機能が必要ですが、セキュリティを強化するために、Dockerはその機能を非特権コンテナにドロップします。

systemdには、コンテナ内のcgroupファイルシステムへのROアクセスも必要です。あなたはそれを追加することができます–v /sys/fs/cgroup:/sys/fs/cgroup:ro

そのため、ここでは、Dockerコンテナー内でsystemdを使用してCentOSを実行する方法に関するいくつかの手順を示します。

  1. Centosイメージをプル
  2. 以下のようなドッカーファイルをセットアップします。
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"]
  1. ビルド- docker build --rm -t centos7-systemd - < mydockerfile
  2. コンテナを実行します docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init

  3. コンテナに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.
とおりです。– Snowcrash

1
はっきりしない場合に!まだエラーが発生していますFailed to get D-Bus connection: Operation not permitted
スノークラッシュ

私の答えでコピーしたDockerfileから独自のイメージを作成し、そのイメージからコンテナーを実行しても、まだエラーが発生しますか?
13dimitar

4
ビンゴ!/bin/bashシェルを取得するためにコンテナを実行していました。ただし、これにより前述のエラーが発生しました。/usr/sbin/init提案されたとおりに実行してから、シェルで接続するとすべてうまくいった 明らかに私はについてのニュアンスが欠けてい/usr/sbin/initます。この答えは、かなりの賛成に値します。
スノークラッシュ

私はこれを2日間続けましたが、何/sys/fs/cgroup:/sys/fs/cgroupがどこから来ているのかまだわかりません...ゲストフォルダをhistのようにマウントする方法を知っています:/src/:/var/wwwしかし、あなたのファイルはどこから来ていますか?私はコードを貼り付けたので、多くのエラーを引き起こしています。私はそれらをどこかに作成する必要があると考えています
-samayo

4

これはあなたの質問への直接的な答えではありませんが、実際にはもっと重要かもしれません。ここで他の答えを読んでいたときにこの認識に出会いました。

いくつかの複雑なシステムをDockerに移行した経験がありますが、アプリケーション/サービスまたは「デーモンごと」に1つのDockerコンテナーを用意することが理想です。

これの1つの非常に重要な理由は、Dockerがsystemctl開始したサービスを完全にシャットダウンしないため、実際、予期しない停電に起因する同じ種類のデータベース破損が発生する可能性があることです。

これについてもう少し詳しく説明します。Dockerは、コンテナに「停止」コマンドを発行すると、すべてのサービスおよびデーモンではなく、CMD / ENTRYPOINTで開始された1つのプロセスのみにSIGTERMシグナルを送信します。そのため、1つのサービスにクリーンシャットダウンの警告が表示され、他のすべてのサービスは不意に終了します。

同じコンテナに2つのサービス(つまり、アプリケーションとPostgreSQLデータベースなど)を絶対にパッケージ化する必要がある場合は、CMD / ENTRYPOINTをSIGTERMをキャッチしてそれらを既知のサービスに再ブロードキャストするスクリプトにする必要があります。それはできますが、機会があれば、ソリューションを再考し、複数のコンテナに分割してみてください。

補遺

同じコンテナで複数のサービスを実行する必要がある場合、Supervisordの使用に関する興味深いメモ/ページがDockerサイトにあります。


2

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この特定のエラーを生成します。


systemd-nologin.conf/ nologinCentOS / RHEL 7 UsePAM noはサポートされておらず、ログ自体に不満があると主張しているため、勝ちました。RH opensshポータブルパッチが適用されているか、何らかの理由で破損しているのか、初心者の顧客からサポートサーフェスを低くしようとしているのかはわかりません。

1

init / PID 1としてsystemdを起動する必要はありませんでした。他の人が言及したクリーンアップ手順を実行した後、スタートアップスクリプト内からとしてsystemdを起動します/usr/lib/systemd/systemd --system &

これにより、systemdは登録されたサービスを開始および起動できましたが、systemctlはD-Busエラーで失敗していました。

私にとって、見つからないリンクは/ run / systemd / systemディレクトリがstraceなかったことでした。これはsystemctlを実行することで発見されました。

systemctlを実行する前にこのディレクトリを手動で作成すると、systemctlがwork-for-meになります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.