Frage D-Bus-Verbindung konnte nicht hergestellt werden: Betrieb nicht erlaubt


Ich versuche, Dienste auf meinem CentOS-Image aufzulisten, das in Docker ausgeführt wird

systemctl list-units  

aber ich bekomme diese Fehlermeldung:

Failed to get D-Bus connection: Operation not permitted

Irgendwelche Vorschläge, was das Problem sein könnte?


22
2018-01-08 20:35


Ursprung


Du hast es nicht benutzt sudo? - Michael Hampton♦
Sie sollten systemd nicht verwenden, wenn Sie es nicht benötigen. Versuchen Sie, die Anwendung ohne CMD oder RUN zu starten oder ein Wrapper-Skript zu verwenden. - nelaaro


Antworten:


Meine Vermutung ist, dass Sie eine laufen non-privileged Container. systemd benötigt die CAP_SYS_ADMIN-Fähigkeit, aber Docker legt diese Funktion in den nicht privilegierten Containern ab, um mehr Sicherheit hinzuzufügen.

systemd benötigt außerdem RO-Zugriff auf das cgroup-Dateisystem innerhalb eines Containers. Sie können es mit hinzufügen –v /sys/fs/cgroup:/sys/fs/cgroup:ro

So, hier ein paar Schritte, wie CentOS mit Systemd in einem Docker-Container ausgeführt wird:

  1. Ziehen Sie Centos Bild
  2. Richten Sie eine Andockdatei wie die folgende ein:

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. Baue es - docker build --rm -t centos7-systemd - < mydockerfile
  2. Führen Sie einen Container mit aus docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init

  3. Sie sollten systemd in Ihrem Container haben


13
2018-01-09 07:53



Ziemlich ordentlich! Zumindest bekomme ich jetzt mehr Informationen zurück. Hier ist, was ich eingeloggt bekomme: [ 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
Falls ich nicht klar war! Ich bekomme immer noch den Fehler Failed to get D-Bus connection: Operation not permitted - Snowcrash
Sie haben ein eigenes Bild aus der Dockerdatei erstellt, die in meiner Antwort kopiert wurde. Sie führen einen Container aus diesem Bild aus, und Sie erhalten immer noch einen Fehler? - 13dimitar
Bingo! Ich habe den Container mit ausgeführt /bin/bash um eine Shell zu bekommen. Dies gab mir jedoch den zuvor erwähnten Fehler. Als ich es lief /usr/sbin/init wie vorgeschlagen, dann mit einer Schale befestigt ging alles gut. Natürlich fehlt mir eine Nuance /usr/sbin/init. Diese Antwort verdient eine substanzielle Verbesserung. - Snowcrash
Ich bin seit 2 Tagen dabei, und ich kann immer noch nicht herausfinden, was /sys/fs/cgroup:/sys/fs/cgroup ist oder wo es herkommt ... Ich weiß, wie man Gastordner zu hist wie: /src/:/var/www Aber woher kommt deine Datei? Es verursacht mir viele Fehler, weil ich den Code eingefügt habe, ich denke, ich sollte diese irgendwo erstellen - samayo


Ich habe es geschafft, dieses Problem in einem CentOS: 7 Docker Container zu beheben. Ich bin hauptsächlich gefolgt das Handbuch zum CentOS Docker Image-Projekt.

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"]

Erstellen Sie nun das Image und führen Sie es mit mindestens den folgenden Argumenten aus docker run Befehl: -v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro

Dann ist der Hauptpunkt das /usr/sbin/init muss der erste Prozess im Docker-Container sein.

Wenn Sie also ein benutzerdefiniertes Skript verwenden möchten, das vor der Ausführung einige Befehle ausführt /usr/sbin/init, starten Sie es am Ende Ihres Skripts mit exec /usr/sbin/init (in einem Bash-Skript).

Hier ist ein Beispiel:

ADD cmd.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/cmd.sh

CMD ["/usr/local/bin/cmd.sh"]

Und hier ist der Inhalt von 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

Du könntest haben System is booting up. See pam_nologin(8) Wenn Sie das PAM-System verwenden, löschen Sie in diesem Fall /usr/lib/tmpfiles.d/systemd-nologin.conf in deiner Dockerfile weil es die Datei erstellt /var/run/nologin welches diesen spezifischen Fehler erzeugt.


2
2018-03-01 14:26



systemd-nologin.conf / nologin für den Sieg, weil CentOS / RHEL 7 behauptet UsePAM no wird nicht unterstützt und meldet sich in den Protokollen als solche an. Ich bin mir nicht sicher, ob RH openssh portable es irgendwie gepatcht / kaputt gemacht hat oder ob sie versuchen, ihre Support-Oberfläche von Neukunden zu senken. - Barry


Dies ist keine direkte Antwort auf Ihre Frage, aber es könnte tatsächlich wichtiger sein, und ich stieß auf diese Erkenntnis, als ich die anderen Antworten hier las.

Ich habe einige Erfahrung damit gemacht, einige komplizierte Systeme auf Docker zu migrieren, und eine der wichtigsten Erkenntnisse, die ich hatte, ist, dass Sie idealerweise einen Docker-Container pro Anwendung / Dienst oder "pro Daemon" haben sollten.

Ein sehr wichtiger Grund dafür ist, dass Docker wird Dienste, die Sie mit Systemctl starten, nicht ordnungsgemäß herunterfahren und in der Tat können Sie die gleiche Art von Datenbankbeschädigungen bekommen, die von einem unerwarteten Stromausfall herrühren.

Um etwas tiefer hinein zu gehen: Wenn Docker einen "Stop" -Befehl an einen Container ausgibt, sendet es das Signal SIGTERM nur an den einen einzigen Prozess, der mit dem CMD / ENTRYPOINT gestartet wurde, nicht an alle Dienste und Daemons. So dass ein Dienst die Warnung hat sauber herunterzufahren und alle anderen werden kurzerhand beendet.

Wenn Sie unbedingt zwei Dienste in denselben Container packen müssen (d. H. Ihre Anwendung und eine PostgreSQL-Datenbank oder Ähnliches), müssen Sie CMD / ENTRYPOINT als Skript verwenden, das SIGTERM abfängt und dann an diese bekannten Dienste weiterreicht. Es kann getan werden, aber wenn Sie die Gelegenheit haben, überdenken Sie Ihre Lösung und versuchen Sie es in mehrere Container zu brechen.

Ein Nachtrag

Es gibt ein interessantes Hinweis / Seite auf der Docker-Website über die Verwendung von Supervisord, wenn Sie unbedingt mehrere Dienste in demselben Container ausführen müssen.


2
2018-05-18 13:22





Ich wollte systemd nicht als init / PID 1 starten müssen. Nachdem ich die von anderen erwähnten Bereinigungsschritte ausgeführt habe, starte ich systemd in einem Startskript als /usr/lib/systemd/systemd --system &.

Dies ermöglichte es Systemd, die registrierten Dienste zu starten und zu starten, aber systemctl schlug mit dem D-Bus-Fehler fehl.

Für mich war der fehlende Link das Fehlen des Verzeichnisses / run / systemd / system, das von stracesystemctl.

Wenn Sie dieses Verzeichnis manuell erstellen, bevor Sie systemctl ausführen, kann systemctl für mich arbeiten.


0
2017-08-09 17:45