Wie führe ich systemd-Dienste im Arch Linux Docker-Container aus?

7

Es scheint unzählige verschiedene Möglichkeiten zu geben, wie Systemdienste in Docker-Containern ausgeführt werden können. Das neueste Beispiel für einen direkten Rat, den ich gefunden habe, ist das Ausführen von Docker mit --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro --cap-add=SYS_ADMIN --security-opt=seccomp:unconfined. Es scheitert jedoch immer noch :

Fehler: Dienst konnte nicht gestartet werden [ntpd]: Die Ausführung von '/ usr / sbin / systemctl start ntpd' wurde zurückgegeben. 1: Verbindung zum Bus fehlgeschlagen: Keine solche Datei oder kein solches Verzeichnis

Was ist das absolute Minimum, das ich tun muss, um einfache Dienste unter systemd 231 auf einem Docker 1.12.1-Container mit einer aktuellen Arch Linux-Distribution auszuführen?

l0b0
quelle
1
Bei Docker geht es mehr darum, den Dämon direkt auszuführen, wenn Sie ihm ein vordefiniertes ENTRYPOINTSystem geben . Wenn Sie nach einer Art Container-Integration mit systemd suchen, können Sie einen nspawn-Service
erstellen
1
Ich verwende Docker nicht, um einen einzelnen Dienst auszuführen. Ich benutze es, um einen Puppet-Lauf zu testen, der (unter anderem) mehrere Dienste startet. Wenn ich in einem speziellen Fall die Testumgebung (benutze nspawn anstelle von systemd), ist der Test irgendwie nutzlos.
10.
"Ich verwende Docker nicht, um einen einzelnen Dienst auszuführen." Dann können Sie Docker überhaupt nicht verwenden. Es ist beabsichtigt, eine einzelne ausführbare Datei auszuführen, und alles basiert auf dieser Tatsache. Das ist wahrscheinlich der Grund, warum dieses Problem für Sie so schwer zu lösen ist. Wenn Sie einen Puppenlauf testen, habe ich in diesem Fall normalerweise eine VM, die ich vor dem Ausführen eines Schnappschusses erstellt habe. Wenn Sie bereits so etwas wie ein Vagrant-Setup haben, ist es ziemlich einfach, neue VMs zu erstellen und sie wegzublasen (im Gegensatz zu einem Schnappschuss).
Bratchley
Das unmittelbare Problem, das Sie zu haben scheinen, ist, dass dbus nicht in Ihrem Container läuft.
Bratchley
1
Ich verwende Docker für diese Arbeit aus zwei Gründen: Ebenen sind einfacher zu bearbeiten als Schnappschüsse, um große Mengen unnötiger Arbeit beim erneuten Ausführen von Tests zu vermeiden, und das aktuelle Docker-Setup ist viel einfacher als das entsprechende Vagrant- Setup . Ich verstehe nicht, warum Docker die Ausführung mehrerer Dienste ausschließen sollte - es handelt sich schließlich nur um Prozesse. Nichts hindert jemanden daran, mehrere Prozesse in Docker auszuführen. Ich möchte nicht, dass einer von ihnen der ist ENTRYPOINT.
10.

Antworten:

2

Ich hatte das gleiche Problem beim Testen meiner Ansible-Playbooks, für die systemd erforderlich ist. Und wie Sie sagten, scheint Docker hier der beste Ansatz zu sein, da es viel einfacher ist, einen Container als eine virtuelle Maschine auf und ab zu bringen.
Zunächst einmal ist das Base / Archlinux- Image veraltet - Sie sollten stattdessen Archlinux / Base verwenden. Um systemd völlig unprivilegiert auszuführen, sollten einige Dinge getan werden:

  • Geben Sie eine Variable "conrainer =" an, damit systemd nicht versucht, eine Reihe von Aufgaben auszuführen, die normalerweise beim Booten einer Hardwaremaschine ausgeführt werden
  • systemd verwendet aktiv cgroups, also binden Sie das Dateisystem mount / sys / fs / cgroup von einem Host
  • bind mount / sys / fs / fuse ist nicht erforderlich, hilft jedoch, Probleme mit sicherungsabhängiger Software zu vermeiden
  • systemd ist der Meinung, dass die Verwendung von tmpfs überall ein guter Ansatz ist, aber das Ausführen von nicht privilegierten Dateien macht es unmöglich, tmpfs zu mounten, wo immer es will, also mounten Sie tmpfs vorab in / tmp, / run und / run / lock
  • Als letztes Bit müssen Sie sysinit.target als Standardeinheit zum Booten anstelle von multi-user.target oder was auch immer angeben, da Sie wirklich keine grafischen Elemente in einem Container starten möchten

Die resultierende Befehlszeile ist

docker run \
  --entrypoint=/usr/lib/systemd/systemd \
  --env container=docker \
  --mount type=bind,source=/sys/fs/cgroup,target=/sys/fs/cgroup \
  --mount type=bind,source=/sys/fs/fuse,target=/sys/fs/fuse \
  --mount type=tmpfs,destination=/tmp \
  --mount type=tmpfs,destination=/run \
  --mount type=tmpfs,destination=/run/lock \
    archlinux/base --log-level=info --unit=sysinit.target

Wenn wir über das Ausführen eines bestimmten Dienstes wie ntpd aus Ihrem Beispiel sprechen, müssen Sie hinzufügen

--cap-add=SYS_TIME

Andernfalls schlägt ntpd mit der Verweigerung der Berechtigung fehl, da niemand möchte, dass ein Container standardmäßig die Systemzeit festlegt.

Ps Ich habe eine ganze Weile gelernt, wie sich systemd verhält, und es geschafft, es mit der Anzahl der Betriebssystem-Images zum Laufen zu bringen. Ich habe meine Erfahrung in einem Artikel beschrieben, in dem systemd im Docker-Container ausgeführt wird . Es ist auf Russisch, aber ich glaube, Google Übersetzer sollte in Ihrem Browser funktionieren. Vielen Dank

Владимир Тюхтин
quelle