D-Bus-Verbindung konnte nicht hergestellt werden: Vorgang nicht zulässig

29

Ich versuche, mithilfe von Dienste in 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?

Schneefall
quelle
1
Hast du nicht benutzt sudo?
Michael Hampton
Sie sollten systemd nicht verwenden, wenn Sie es nicht benötigen. Versuchen Sie, die Anwendung zu starten, ohne sie in der CMD oder RUN zu haben, oder verwenden Sie ein Wrapper-Skript.
Nelaaro
Wenn Sie systemdauf CentOS benötigen , verwenden Sie dieses Bild: FROM centos/systemd
james.garriss

Antworten:

24

Ich vermute, dass Sie einen non-privilegedContainer betreiben . Für systemd ist die Funktion CAP_SYS_ADMIN erforderlich. Docker legt diese Funktion jedoch in den nicht privilegierten Containern ab, um die Sicherheit zu erhöhen.

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

Hier ein paar Schritte zum Ausführen von CentOS mit systemd in einem Docker-Container:

  1. Centos Bild ziehen
  2. Richten Sie eine Docker-Datei wie die folgende ein:
FROM centos
MAINTAINER "Yourname" <[email protected]>
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 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

13dimitar
quelle
Ziemlich ordentlich! Zumindest bekomme ich jetzt mehr Informationen zurück. Folgendes werde ich protokolliert:[ 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
Falls ich nicht klar war! Ich erhalte immer noch den FehlerFailed to get D-Bus connection: Operation not permitted
Snowcrash
Sie haben Ihr eigenes Image aus der in meiner Antwort kopierten Docker-Datei erstellt, führen einen Container aus diesem Image aus und erhalten trotzdem eine Fehlermeldung?
13dimitar
4
Bingo! Ich ließ den Container mit laufen /bin/bash, um eine Muschel zu bekommen. Dies gab mir jedoch den zuvor genannten Fehler. Wenn ich es mit /usr/sbin/initwie vorgeschlagen laufen ließ, dann mit einer Muschel befestigt, ging alles gut. Klar, mir fehlt eine Nuance /usr/sbin/init. Diese Antwort verdient einiges an Zustimmung.
Snowcrash
Ich bin seit 2 Tagen dabei, und ich kann immer noch nicht herausfinden, was /sys/fs/cgroup:/sys/fs/cgroupist oder woher es kommt ... Ich weiß, wie ich einen Gastordner mounten kann, um zu sehen, wie: /src/:/var/wwwaber wo kommt deine Datei her? Es verursacht mir viele Fehler, weil ich den Code eingefügt habe. Ich denke, ich sollte diese irgendwo erstellen
samayo
4

Dies ist keine direkte Antwort auf Ihre Frage, aber es ist möglicherweise wichtiger, und ich bin auf diese Erkenntnis gestoßen, als ich die anderen Antworten hier gelesen habe.

Ich habe einige Erfahrungen mit der Migration einiger komplizierter Systeme auf Docker gesammelt und festgestellt, dass Sie idealerweise einen Docker-Container pro Anwendung / Dienst oder "pro Daemon" haben sollten.

Ein sehr wichtiger Grund dafür ist, dass Docker Dienste, die Sie mit systemctl starten, nicht sauber herunterfährt und dass Sie möglicherweise dieselbe Art von Datenbankbeschädigungen erleiden , die von einem unerwarteten Stromausfall herrühren.

Um dies etwas genauer zu erläutern: Wenn Docker einen Stoppbefehl an einen Container ausgibt, sendet es das SIGTERM-Signal nur an den einen einzelnen Prozess, der mit CMD / ENTRYPOINT gestartet wurde, nicht an alle Dienste und Dämonen. Damit ein Dienst die Warnung erhält, dass er sauber heruntergefahren werden muss, und alle anderen sofort beendet werden.

Wenn Sie unbedingt zwei Services in denselben Container packen müssen (z. B. Ihre Anwendung und eine PostgreSQL-Datenbank oder ähnliches), muss CMD / ENTRYPOINT ein Skript sein, das SIGTERM abfängt und an diese bekannten Services weiterleitet. Es ist möglich, aber wenn Sie die Möglichkeit haben, überdenken Sie Ihre Lösung und versuchen Sie, sie in mehrere Container aufzuteilen.

Ein Nachtrag

Auf der Docker-Site gibt es einen interessanten Hinweis / eine interessante Seite zur Verwendung von Supervisord, wenn unbedingt mehrere Dienste im selben Container ausgeführt werden müssen.

Murray Todd Williams
quelle
2

Ich habe es geschafft, dieses Problem in einem CentOS: 7 Docker-Container zu beheben. Ich habe hauptsächlich das Image-Projekt von Guide on CentOS Docker befolgt .

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 Befehlen aus docker run:-v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro

Der wichtigste Punkt ist, dass /usr/sbin/initdies der erste Prozess innerhalb des Docker-Containers sein muss.

Wenn Sie also ein benutzerdefiniertes Skript verwenden möchten, das vor dem Ausführen einige Befehle ausführt /usr/sbin/init, starten Sie es am Ende des 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

Sie haben könnten , System is booting up. See pam_nologin(8)wenn Sie das PAM - System verwendet wird , in diesem Fall löschen Sie /usr/lib/tmpfiles.d/systemd-nologin.confin Ihrem Dockerfileweil es die Datei erstellt , /var/run/nologindie diesen spezifischen Fehler erzeugt.

Anthony O.
quelle
systemd-nologin.conf/ nologinfür den Gewinn, da CentOS / RHEL 7-Ansprüche UsePAM nonicht unterstützt werden und sich in Protokollen als solche beschweren. Ich bin mir nicht sicher, ob RH openssh portable es irgendwie gepatcht / kaputt gemacht hat oder ob sie versuchen, ihre Support-Oberfläche von unerfahrenen Kunden zu senken.
1

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 über ein Startskript als /usr/lib/systemd/systemd --system &.

Dadurch konnte systemd die registrierten Dienste starten und starten, aber systemctl schlug mit dem D-Bus-Fehler fehl.

Das fehlende Glied war für mich das Fehlen des Verzeichnisses / run / systemd / system, das durch stracesystemctl entdeckt wurde.

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

Chaim Geretz
quelle