Podman: Linux-Container einfach gemacht, Teil 3

Seite 4: Systemd, Daemons und Container

Inhaltsverzeichnis

Viele Softwarepakete bauen direkt auf Systemd auf, um bestimmte Services und deren Abhängigkeiten zu starten und zu überwachen. Manche Pakete sind ohne Systemd erst gar nicht installierbar. Allgemein ist Systemd aus dem Alltag zeitgemäßer IT-Systeme nicht mehr wegzudenken, doch dauerte es überraschend lange, bis Container-Tools Systemd korrekt unterstützen konnten.

Wie im ersten Teil der Artikelserie beschrieben, unterscheiden sich Docker und Podman grundlegend in ihrer Architektur. Docker folgt einem Client-Server-Modell, bei dem der Docker-Client über eine API mit dem Docker-Daemon kommuniziert, der die Anfragen bearbeitet und gegebenenfalls an andere Programme weiterleitet. Das Modell bietet viele Vorteile, doch lässt es sich ebenso schwer in bestehende Konzepte eines Linux-Systems integrieren und birgt einige Sicherheitsrisiken, die der zweite Teil der Reihe genauer beleuchtet.

Auch im Kontext von Systemd ist das Client-Server-Modell problematisch, vor allem weil ein Systemd-Service-Container zwar über den Docker-Client starten, aber nicht überwachen kann, da das die Aufgabe des Docker-Daemons ist. Auch Systemd innerhalb eines Docker-Containers auszuführen ist nach wie vor ein schwieriges Unterfangen und ist nur über den Umweg eines OCI-Hooks möglich. Das führte unter anderem dazu, dass viele Anwender sich gezwungen sahen, eigene Startup-Skripte zu schreiben – ein Ärgernis für Nutzer und Linux-Distributionen gleichermaßen, da man sich um Jahre zurückversetzt sah. Mit Podman gehört das Problem der Vergangenheit an.

Podman implementiert ein klassisches Fork-Exec-Modell, das jeden Container als Kindprozess von Podman startet, und sich damit einfach in Systemd-Services integrieren lässt. Damit lassen sich Container über Systemd starten, überwachen und gegebenenfalls auch neu starten. Anwender lässt Podman beim Erstellen von Systemd-Services jedoch nicht alleine, denn Podman erlaubt es, System-Services für Container über den Befehl podman-generate-systemd zu generieren.

[heise]$ podman run --name heise-container -d alpine top
73107a034f88c46613e66083092378d2e1ba54910a03d326749f64e180dfd43d

[heise]$ podman generate systemd --name heise-container > heise-container.service

[heise]$ cat heise-container.service
[Unit]
Description=heise-container Podman Container
[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start heise-container
ExecStop=/usr/bin/podman stop -t 10 heise-container
KillMode=none
Type=forking
PIDFile=/home/valentin/.local/share/containers/storage/overlay-containers/73107a034f88c46613e66083092378d2e1ba54910a03d326749f64e180dfd43d/userdata/73107a034f88c46613e66083092378d2e1ba54910a03d326749f64e180dfd43d.pid
[Install]
WantedBy=multi-user.target

Der generierte Text kann nun dazu dienen, einen Systemd-Service zu erstellen.

[heise]$ cp heise-container.service ~/.config/systemd/user/

[heise]$ systemctl enable --user heise-container

Nun lässt sich der Container bequem über systemctl starten.

[heise]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ca6843ae501 docker.io/library/alpine:latest top 21 minutes ago Up 21 minutes ago heise-container

[heise]$ podman stop heise-container

[heise]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

[heise]$ systemctl start --user heise-container

[heise]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ca6843ae501 docker.io/library/alpine:latest top 22 minutes ago Up 9 seconds ago heise-container

Aufgrund der Restart-Policy des Systemd-Service, startet er den Container automatisch neu, falls er unerwartet abbricht. Um das zu testen, stoppt die folgende Zeile den Container manuell.

[heise]$ podman stop heise-container

[heise]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ca6843ae501 docker.io/library/alpine:latest top 23 minutes ago Up 8 seconds ago heise-container

Wie in den obigen Beispielen gezeigt, lässt sich Podman leicht in Systemd integrieren. Services können Anwender mit podman-generate-systemd schnell generieren und einsetzen. Momentan arbeiten die Podman-Maintainer daran, das Konzept auch auf Pods anzuwenden, um komplexere Abhängigkeiten zwischen Containern zu unterstützen.

Die Systemd-Unterstützung von Podman geht jedoch einen Schritt weiter, denn Systemd lässt sich auch innerhalb eines Podman-Containers einfach ausführen. Dabei setzt Podman bestimmte Mount-Points innerhalb des Containers auf, was automatisch passiert, wenn init oder systemd der erste Container-Prozess ist. Die Mounts lassen sich jedoch auch explizit mit der Kommandozeilenoption --system=true setzen. Durch die native Unterstützung von Systemd lassen sich nun Softwarepakete installieren und ausführen, die sich zuvor nur mühselig aufsetzen ließen und für Anbieter nur schwer zu unterstützen waren. Mit der nativen Systemd-Unterstützung von Podman gehören manuell geschriebene, fehleranfällige Startup-Skripte der Vergangenheit an. Damit lassen sich Softwarepakete in einem Container genauso installieren wie auf "bare metal", so zum Beispiel ein Apache-http-Server:

FROM fedora
RUN yum -y install httpd; yum clean all; systemctl enable httpd;
CMD [ "/sbin/init" ]