Schlagwort-Archive: podman-generate-systemd

Podman kann auch Systemd-Service-Units generieren

Mit „Kanboard im Container…“ hat mein Ausflug ins Containerland begonnen. Mittlerweile läuft mein Pod bereits eine Weile und ich nutze die Anwendung regelmäßig. Jedoch musste ich nach jedem Neustart des Hosts den Pod kanboardpod manuell starten. Ich hatte mir daher vorgenommen, hierfür eine Systemd-Service-Unit zu erstellen, welche diesen Task automatisiert. Doch habe ich mit Freude festgestellt, dass podman-generate-systemd(1) mir diese Arbeit abnehmen kann.

Also starte ich einen ersten Versuch und erzeuge entsprechende Service-Unit-Dateien in meinem HOME-Verzeichnis. Die Option „--name“ sorgt dafür, dass in den Service-Unit-Dateien die Namen des Pods bzw. der Container verwendet werden, anstatt der UUIDs. Die Option „--files“ sorgt dafür, dass die Ausgabe in Dateien und nicht auf die Standard-Ausgabe geschrieben wird.

$ podman generate systemd --name --files kanboardpod
/home/alice/pod-kanboardpod.service
/home/alice/container-kanboard.service
/home/alice/container-pgsql_db.service

$ cat pod-kanboardpod.service
# pod-kanboardpod.service
# autogenerated by Podman 2.0.5
# Mon Jan 25 13:19:51 CET 2021

[Unit]
Description=Podman pod-kanboardpod.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
Requires=container-kanboard.service container-pgsql_db.service
Before=container-kanboard.service container-pgsql_db.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
ExecStart=/usr/bin/podman start 62cdd29105a4-infra
ExecStop=/usr/bin/podman stop -t 10 62cdd29105a4-infra
ExecStopPost=/usr/bin/podman stop -t 10 62cdd29105a4-infra
PIDFile=/run/user/1000/containers/overlay-containers/b3c9bd9754cdc999108d0f4aad7d808c007cc34eee34faefd41ee39c3e1ca18b/userdata/conmon.pid       
KillMode=none
Type=forking

[Install]
WantedBy=multi-user.target default.target

$ cat container-kanboard.service 
# container-kanboard.service
# autogenerated by Podman 2.0.5
# Mon Jan 25 13:19:51 CET 2021

[Unit]
Description=Podman container-kanboard.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
BindsTo=pod-kanboardpod.service
After=pod-kanboardpod.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
ExecStart=/usr/bin/podman start kanboard
ExecStop=/usr/bin/podman stop -t 10 kanboard
ExecStopPost=/usr/bin/podman stop -t 10 kanboard
PIDFile=/run/user/1000/containers/overlay-containers/99d386a42b186efb3347d909cea265b990469dc33e1889a3006425a71956699b/userdata/conmon.pid
KillMode=none
Type=forking

[Install]
WantedBy=multi-user.target default.target

$ cat container-pgsql_db.service 
# container-pgsql_db.service
# autogenerated by Podman 2.0.5
# Mon Jan 25 13:19:51 CET 2021

[Unit]
Description=Podman container-pgsql_db.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
BindsTo=pod-kanboardpod.service
After=pod-kanboardpod.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
ExecStart=/usr/bin/podman start pgsql_db
ExecStop=/usr/bin/podman stop -t 10 pgsql_db
ExecStopPost=/usr/bin/podman stop -t 10 pgsql_db
PIDFile=/run/user/1000/containers/overlay-containers/fe757283f0662220fee23a563053ea7f30dbdf6d9fbb492c010a01dd7598fc9b/userdata/conmon.pid
KillMode=none
Type=forking

[Install]
WantedBy=multi-user.target default.target

Um die generierten Service-Units zu installieren und zukünftig als derjenige User auszuführen, welcher den Pod und die Container erzeugt hat, verschiebe ich sie in das zu erstellende Verzeichnis ~/.config/systemd/user. Anschließend werden die neuen Units in die Systemd-Konfiguration eingelesen und aktiviert.

$ mkdir -p .config/systemd/user
$ mv *.service .config/systemd/user/
$ systemctl --user enable pod-kanboardpod.service
$ podman pod stop kanboardpod
$ systemctl --user start pod-kanboardpod.service

Nachdem ich die Service-Units an die richtige Stelle verschoben und aktiviert hatte, habe ich meine laufende Pod-Instanz gestoppt und über die entsprechende Service-Unit gestartet.

Ich wähnte mich nun bereits am Ziel. Doch nach einem Neustart des Hosts war die Anwendung wieder nicht verfügbar. Die Service-Unit war nicht gestartet worden. Podman kann hier nichts dafür, denn es ist systemd, welcher dafür sorgt, dass im User-Kontext laufende Services beendet werden, wenn sich der entsprechende User ausloggt und diese erst startet, wenn der User sich einloggt.

Valentin Rothberg von Red Hat gab mir den entscheidenden Tipp, um dieses Problem zu lösen. Die Lösung versteckt sich in der Manpage zu podman-generate-systemd(1):

The systemd user instance is killed after the last session for the user is closed. The systemd user instance can be kept running ever after the user logs out by enabling lingering using

$ loginctl enable-linger <username>

Manual page podman-generate-systemd(1)

@Valentin: Thanks a lot, that solved my issue!

Fazit

Ich bin ehrlich gesagt hoch erfreut, dass die Entwickler hier eine Möglichkeit vorgesehen haben, um aus bestehenden Pods bzw. Container-Instanzen Systemd-Service-Units generieren zu können. Dies ermöglicht es, Container-Instanzen und Pods mit den gewohnten Werkzeugen zu starten, zu stoppen und deren Status zu kontrollieren.

So besteht die Möglichkeit, die rootless-Podman-Container auch als unprivilegierte Dienste laufen zu lassen. Das gefällt mir.