Podman
Siehe auch
Podman ist ein OCI-kompatibles Container-Management-Tool, dessen CLI explizit mit Docker kompatibel ist, was den Übergang für Docker-Nutzer erleichtert. Das Projekt wurde 2017 ins Leben gerufen und ursprünglich von Red Hat entwickelt. Es bietet erweiterte Sicherheitsfunktionen und unterstützt rootless Container. Im Gegensatz zu Docker benötigt Podman keinen Daemon, wodurch keine Privilegieneskalation für Benutzer in der Docker-Gruppe möglich ist.
Beim Umgang mit Podman stösst man auch auf folgende Tools:
buildah
: zum Bauen von Container Imagespodman
: verwaltet Container und Container Imagesskopeo
: zur Signierung, zum Kopieren und Löschen von Container Images
podman Cheat Sheet
dnf install -y podman systemd-container
podman login $registry
podman search --no-trunc mariadb-103
# inspect without pulling first
skopeo inspect docker://$registry/rhel8/mariadb-103
# local
podman inspect $registry/rhel8/mariadb-103
podman pull $registry/rhel8/mariadb-103
podman images
podman run \
--detach \
--name=myname \
--publish localport:containerport \
--volume localdir:containerdir:z \
--env ENV1=VAL1 \
docker://$registry/rhel8/mariadb-103:tag
podman logs --follow myname
# open shell in running container
podman exec -it myname /bin/bash
# execute and delete
podman run --rm -it $registry/rhel8/mariadb-103 /bin/bash
podman ps --all
podman stop myname
podman kill myname
podman restart myname
podman info
podman rmi $registry/rhel8/mariadb-103:latest
podman rm myname
Im Unterschied zu Docker ein spezielles Feature von Podman: Rootless-Container „mariadb“ als User. Wichtig: statt sudo
oder su
sollte machinectl
verwendet werden.
machinectl shell user@.host
podman run --detach $registry/rhel8/mariadb-103
podman ps
Container als Systemd-Service
Da Container unter Podman nicht über einen Daemon, sondern als einzelne Prozesse laufen, ist die Integration in systemd einfach. Pro Container wird ein Systemd-Service erstellt. Das funktioniert für rootful und rootless Container.
Zuerst muss der Container manuell erstellt werden:
podman create \
--name httpd \
--publish 127.0.0.1:8080:80/tcp \
httpd:latest
podman ps --all
Der Systemd-Service kann nun generiert werden. Der Parameter --new
sorgt dafür, dass der Container bei jedem Neustart des Services neu erstellt wird. Dies ist später für automatische Updates des Containers nützlich.
Unter dem root
-User:
podman generate systemd httpd --new > /etc/systemd/system/httpd-container.service
systemctl daemon-reload
# double check result
systemctl cat httpd-container.service
systemctl enable --now httpd-container.service
systemctl status httpd-container.service
podman ps
Rootless:
loginctl enable-linger user
machinectl shell user@.host
mkdir -p ~/.config/systemd/user/
podman generate systemd httpd --new > ~/.config/systemd/user/httpd-container.service
systemctl --user daemon-reload
# double check result
systemctl --user cat httpd-container.service
systemctl --user enable --now httpd-container.service
systemctl --user status httpd-container.service
podman ps
Tipp
Der Exit Code der Applikation im Container wird richtig an Systemd weitergegeben und ist via systemctl status ...
ersichtlich.
Automatische Updates der Container
Bei der Entwicklung von Podman wurde auch an die automatische Aktualisierung der Container gedacht. Podman wird mit der Funktion auto-update
ausgeliefert, die alle markierten Container auf neue Versionen überprüft.
Damit dies funktioniert muss der Container in einem mit podman generate systemd --new
generiertem Systemd-Service laufen und das --label "io.containers.autoupdate=registry"
gesetzt haben.
podman create \
--name httpd \
--publish 127.0.0.1:8080:80/tcp \
--label "io.containers.autoupdate=registry" \
docker.io/httpd:latest
podman generate systemd httpd --new > /etc/systemd/system/httpd-container.service
Das Update kann manuell ausgeführt werden:
podman auto-update
Oder als Systemd-Timer (standardmässig täglich):
# rootful
systemctl enable --now podman-auto-update.timer
# rootless
systemctl --user enable --now podman-auto-update.timer
Healthchecks
Nur weil der Container (bzw. der Systemd-Service) gestartet wurde, heisst noch lange nicht, dass auch die Applikation innerhalb des Container bereit ist. Um dies zu prüfen können Healthchecks verwendet werden.
Ein Healthchecks besteht aus:
„Command“: Wird innerhalb des Containers ausgeführt. Muss den Status der Applikation ermitteln und als Exit-Code zurückliefern geben (0 = ok, sonst „failure“).
„Retries“: Anzahl der aufeinanderfolgenden Fehlversuche bevor der Container als „unhealthy“ markiert wird.
„Interval“: Zeitabstand zwischen den Ausführungen des Commands.
„Start-period“: Zeitraum, in dem die Healthchecks nach dem Start des Containers fehlschlagen dürfen („grace period“).
„Timeout“: Timeout des Commands selbst.
„Action“: Wie soll ein „unhealthy“ Container behandelt? Optionen:
none
,kill
,restart
undstop
. Zusammen mit Systemd istkill
am sinnvollsten - ein Restart kann dann via SystemdRestart=on-failure
erfolgen.
podman run \
--detach \
--name mariadb \
--publish 127.0.0.1:3306:3306 \
--env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 \
--health-cmd 'mysql --execute ";"' \
--health-retries 5 \
--health-interval 10s \
--health-start-period 5s \
--health-timeout 3s \
--health-on-failure=kill \
docker.io/library/mariadb:10.5
Die Healthchecks können auch manuell ausgeführt werden:
podman healthcheck run mariadb
echo $?
Troubleshooting
ERRO[0000] unable to get systemd connection to add healthchecks: lstat /tmp/podman-run-1001/systemd: no such file or directory
dnf install -y systemd-container machinectl shell user@.host
Alternativ manuell:
sudo -u user -i export XDG_RUNTIME_DIR=/run/user/$(id -u)
Built on 2024-11-18