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?
sudo
?systemd
auf CentOS benötigen , verwenden Sie dieses Bild:FROM centos/systemd
Antworten:
Ich vermute, dass Sie einen
non-privileged
Container 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:
docker build --rm -t centos7-systemd - < mydockerfile
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
Sie sollten systemd in Ihrem Container haben
quelle
[ 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
, um eine Muschel zu bekommen. Dies gab mir jedoch den zuvor genannten Fehler. Wenn ich es mit/usr/sbin/init
wie 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./sys/fs/cgroup:/sys/fs/cgroup
ist oder woher es kommt ... Ich weiß, wie ich einen Gastordner mounten kann, um zu sehen, wie:/src/:/var/www
aber wo kommt deine Datei her? Es verursacht mir viele Fehler, weil ich den Code eingefügt habe. Ich denke, ich sollte diese irgendwo erstellenDies 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.
quelle
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 .
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/init
dies 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 mitexec /usr/sbin/init
(in einem Bash-Skript).Hier ist ein Beispiel:
Und hier ist der Inhalt von
cmd.sh
: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.conf
in IhremDockerfile
weil es die Datei erstellt ,/var/run/nologin
die diesen spezifischen Fehler erzeugt.quelle
systemd-nologin.conf
/nologin
für den Gewinn, da CentOS / RHEL 7-AnsprücheUsePAM no
nicht 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.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
strace
systemctl entdeckt wurde.Wenn Sie dieses Verzeichnis manuell erstellen, bevor Sie systemctl ausführen, kann systemctl für mich arbeiten.
quelle