Dieser Text ist eine allgemeine Grundlagen-Einfuehrung in Podman, unabhaengig
vom konkreten Projekt. Wer bereits Docker kennt, findet fast alles wieder;
wer noch nie mit Containern gearbeitet hat, findet hier den Einstieg von Null.
Fuer den projektspezifischen Teil (Novaris, OpenShift, shared/enterprise-infrastructure) siehe
Exkurs: Podman im Novaris-Projekt.
Ein Container ist ein isolierter Prozess, der ein eigenes Dateisystem, eigene Umgebungsvariablen und eigene Netzwerksicht mitbringt, sich dabei aber den Kernel des Host-Betriebssystems mit anderen Containern teilt. Im Unterschied zu einer virtuellen Maschine muss also kein eigenes Betriebssystem gebootet werden - ein Container startet in Sekunden statt Minuten.
Zwei Begriffe stehen dabei im Zentrum:
Aus einem Image lassen sich beliebig viele, voneinander unabhaengige Container starten.
Podman verfolgt dieselbe grundlegende Idee wie Docker und ist zur
Docker-Kommandozeile weitgehend kompatibel - die meisten docker-Befehle
funktionieren nahezu unveraendert mit podman statt docker. Der wichtigste
architektonische Unterschied:
podman-Befehl startet einen eigenstaendigen Prozess. Container koennen
dadurch auch ohne Root-Rechte laufen ("rootless"), was aus
Sicherheitssicht ein Vorteil ist.Fuer die taegliche Arbeit an der Kommandozeile macht das kaum einen
Unterschied - der Umstieg besteht meist nur darin, docker durch podman
zu ersetzen.
Nach der Installation (siehe offizielle Podman-Dokumentation fuer das jeweilige Betriebssystem) mit folgendem Befehl pruefen, ob alles funktioniert:
podman version
podman info
Unter Windows und macOS laeuft Podman nicht direkt auf dem Host, sondern in einer schlanken Linux-VM, die Podman selbst verwaltet ("Podman Machine"). Details dazu, inklusive der projektspezifischen Stolpersteine unter Windows, stehen im Podman-Exkurs.
Ein bekanntes Testimage herunterladen und starten:
podman run hello-world
Ein laenger laufender Dienst, im Hintergrund gestartet und mit Port-Weiterleitung:
podman run -d --name web -p 8080:80 nginx:latest
Danach ist der Dienst unter http://localhost:8080 erreichbar. Die
wichtigsten Optionen dabei:
| Option | Bedeutung |
|---|---|
-d |
im Hintergrund ausfuehren ("detached") |
--name web |
Container einen Namen geben, statt einen zufaelligen zu erhalten |
-p 8080:80 |
Host-Port 8080 auf Container-Port 80 weiterleiten |
podman ps # laufende Container anzeigen
podman ps -a # auch gestoppte Container anzeigen
podman logs web # Ausgaben des Containers ansehen
podman exec -it web sh # Shell im laufenden Container oeffnen
podman stop web # Container anhalten
podman start web # gestoppten Container wieder starten
podman rm web # Container endgueltig entfernen
Wichtig: podman rm entfernt nur den Container, nicht das zugrunde liegende
Image. Ein neuer Container aus demselben Image laesst sich danach jederzeit
wieder starten.
podman images # lokal vorhandene Images auflisten
podman pull postgres:16 # Image aus einer Registry herunterladen
podman rmi postgres:16 # Image lokal entfernen
Ein Image besteht aus einem Namen und einem Tag, getrennt durch einen
Doppelpunkt, zum Beispiel postgres:16. Fehlt der Tag, wird latest
angenommen - fuer reproduzierbare Umgebungen ist ein fester Tag jedoch
vorzuziehen, da sich latest unbemerkt aendern kann.
Ein Containerfile (bei Docker meist Dockerfile genannt, von Podman
gleichwertig unterstuetzt) beschreibt, wie ein Image aufgebaut wird:
FROM eclipse-temurin:21-jre
COPY target/app.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
Daraus ein Image bauen und einen Container starten:
podman build -t meine-app:local .
podman run -d --name meine-app -p 8080:8080 meine-app:local
Das beschreibbare Dateisystem eines Containers verschwindet mit
podman rm. Fuer Daten, die einen Container ueberdauern sollen (zum Beispiel
eine Datenbank), dienen Volumes:
podman volume create db-data
podman run -d --name db `
-e POSTGRES_PASSWORD=test `
-v db-data:/var/lib/postgresql/data `
postgres:16
Auch nach podman rm db bleiben die Daten im Volume db-data erhalten und
koennen von einem neuen Container wiederverwendet werden.
Container in einem gemeinsamen Podman-Netzwerk erreichen sich gegenseitig ueber ihren Containernamen als Hostnamen:
podman network create mein-netz
podman run -d --name db --network mein-netz postgres:16
podman run -d --name app --network mein-netz meine-app:local
Die Anwendung im Container app kann die Datenbank also unter dem Hostnamen
db erreichen (nicht localhost).
podman ps -a # Bestandsaufnahme: was existiert ueberhaupt?
podman container prune # gestoppte Container entfernen
podman image prune # ungenutzte Images entfernen
podman volume prune # ungenutzte Volumes entfernen (loescht Daten!)
podman system df -v # Speicherverbrauch aller Ressourcen anzeigen
Vor podman volume prune immer pruefen, ob sich in einem Volume noch
benoetigte Daten befinden - das Entfernen ist nicht rueckgaengig zu machen.
Wer Docker bereits kennt, kann fast jeden Befehl direkt uebertragen:
| Docker | Podman |
|---|---|
docker run ... |
podman run ... |
docker ps |
podman ps |
docker build ... |
podman build ... |
docker images |
podman images |
docker exec ... |
podman exec ... |
docker-compose up |
podman compose up |
Ein Image ist eine Vorlage, ein Container eine laufende Instanz davon. Podman verwaltet beides ohne zentralen Hintergrund-Daemon und ermoeglicht dadurch rootless Container. Fuer dauerhafte Daten sorgen Volumes, fuer die Kommunikation zwischen Containern sorgen Netzwerke - beides ueberlebt das Entfernen eines einzelnen Containers.
⌂ Cockpit