podman version
geprüft werden.Einleitung
In dem vorangegangenen Beitrag Einführung in Podman haben wir Podman installiert und grundlegend eingerichtet. Bitte stellt sicher, dass du alle dort genannten Schritte auf deinem System ausgeführt habt, da dies die Grundlage für diesen Beitrag ist.
Mit der Grundinstallation ist es jetzt schon möglich, über einfache podman run
-Befehle Container zu erstellen und zu steuern. Doch wie geht man vor,
wenn man sich nicht die langen Befehle mit all den Einstellungen für den Container merken möchte? Bei Docker nutzt man in diesem
Fall docker-compose.yml-Dateien, die alle Informationen zu Container, Volume und Netzwerk beinhalten.
Für Podman sind dafür Quadlets vorgesehen. Bei Quadlets handelt es sich um systemd Unit Dateien. Andere bekannte Units wären zum Beispiel
- .service
- .timer
- .target
- …
Quadlets bringen jetzt unter anderen zusätzlich
- .container
- .volume
- .network
- …
Systemd generiert aus den Quadlets passende Services, sodass diese dann wie ganz normale Dienste und Programme über systemctl
gesteuert werden können.
Wie man Quadlets erstellt und einsetzt, wird in diesem Beitrag anhand des Flame Dashboard (https://github.com/pawelmalak/flame) beschrieben.
Rootful oder rootless?
Da es bei Podman im Gegensatz zu Docker keinen zentralen Prozess (Daemon) gibt, hängt es vom ausführenden Benutzer ab, ob ein Container rootful oder rootless ist. Von einem rootful Container spricht man, wenn dieser vom Benutzer root erstellt und gestartet wurde. Der Container kann somit alle Privilegien erhalten, die auch root hat. Ein rootless Container dagegen wird von einem normalen Benutzer erstellt und gestartet.
Die meisten Container sollten problemlos rootless ausgeführt werden können und das sollte aus Sicherheitsgründen auch immer die bevorzugte Variante sein. Es kann jedoch Spezialfälle geben, bei denen der Container Berechtigungen benötigt, die nur von root erteilt werden können.
Beispiel: Normale Benutzer können keine Ports öffnen, die kleiner als 1024 sind, dafür ist root notwendig. Wenn es sich bei dem Container um einen Reverse Proxy handelt, benötigt man aber die Ports 80 (http) und 443 (https). In so einem Fall gibt es zwei Möglichkeiten, welche man besser findet muss man abwägen:
- root für den Container nutzen, also rootful. Im Quadlet kann weiterhin ein anderer Benutzer anegegeben werden, sodass der Prozess im Container mit einem unprivilegierten Benutzer läuft.
- Den Container dennoch rootless starten, statt 80/443 höhere Ports nutzen (z.B. 10080/10443) und in der Firewall die Ports 80/443 auf diese höheren Ports umleiten (forward).
In diesem Beitrag werden wir einen rootless Container nutzen.
Wo werden die Dateien abgelegt?
Es gibt vordefinierte Pfade, in denen systemd nach Quadlets sucht. Diese werden nachfolgend einmal für rootful und für rootless aufgelistet, zusätzlich befindet sich in der Übersicht auch noch der Pfad zu den Volumes. Die werden von Podman selbst angelegt, wenn man sie in den Quadlets definiert.
Für rootful:
- Quadlets:
/etc/containers/systemd
- Volumes:
/var/lib/containers/storage/volumes
Für rootless:
- Quadlets:
~/.config/containers/systemd
- Volumes:
~/.local/share/containers/storage/volumes
Die Daten für rootless liegen also komplett im Home-Verzeichnis des ausführenden Benutzers. Für die Quadlets können auch zusätzliche Unterordner, zum Beispiel je Anwendung, angelegt werden, um die Übersicht zu erhöhen.
Verzeichnisse anlegen
Zunächst müssen wir in den Benutzer wechseln, der den Container erstellen und ausführen soll. Wenn das der gleiche Benutzer sein soll, mit dem du dich per SSH eingeloggt hast, kann es direkt los gehen und du kannst den nächsten Befehl überspringen.
Wenn es ein anderer Benutzer sein soll, wechseln wir jetzt in diesen Benutzer:
|
|
machinectl
erfolgen und nicht mit sudo su, weil dies zu Problemen bei der Nutzung von systemctl --user
führen kann.
Wenn der Befehl machinectl
fehlt, muss “systemd-container” nachinstalliert werden.Die Verzeichnisse, in denen später Quadlets und Volumes liegen, existieren noch nicht und müssen angelegt werden. Nachfolgend legen wir die Ordner an und erstellen symbolische Links direkt in die Hauptebene des Home-Verzeichnis, damit wir die Unterordner einfacher erreichen können:
|
|
Im Home-Verzeichnis befinden sich jetzt die beiden Links containers und volumes, über die wir mit cd
schnell in die jeweiligen Zielverzeichnisse
springen können.
Podman Secrets
Für das Flame Dashboard müssen wir ein Passwort definieren, mit dem wir uns dann später in den Adminbereich einloggen können. Damit dieses nicht im Klartext in eine Konfigurationsdatei eingetragen werden muss, bietet Podman eine Funktion an, um diese Art von Daten zu sichern, die Podman Secrets. Mit dieser Funktion erstellen wir ein Secret und geben diesem einen Namen und den dazugehörigen Wert, also das Passwort. Später im Quadlet definieren wir dann, dass dieses Secret abgerufen werden und in dem Container als Umgebungsvariable zur Verfügung gestellt werden soll.
Erstellung des Secrets per Datei
Der Befehl zur Erstellung eines Secrets erwartet eine Datei als Eingabe:
|
|
Dort trägst du einfach nur das gewünschte Passwort ein, dann speichern und schließen mit STRG+O -> ENTER STRG+X (Mac: control statt STRG).
Anschließend erstellen wir ein Secret, als Wert wird der Inhalt der eben erstellten Datei zugewiesen:
|
|
Der Inhalt der Datei befindet sich nun im Secrets Speicher von Podman, die Datei kann also entfernt werden:
|
|
Mit podman secret ls
wir eine Übersicht aller verfügbaren Secrets angezeigt. Es werde nur die Namen der Secrets angezeigt, der Inhalt kann nicht
ausgegeben werden.
Erstellung des Secrets ohne Datei
Alternativ kann mit folgendem Befehl das Passwort direkt gespeichert werden ohne den Umweg mit der Dateierstellung:
|
|
Der Nachteil ist, dass das Passwort jetzt in der Befehlshistorie der Shell zu sehen ist, wenn du mit Pfeil nach oben die vorangegangnen Befehle durchgehst.
Hier sollte dann ggf. einmal history -c
ausgeführt werden, um die komplette Historie zu löschen.
Quadlets erstellen
Jetzt kann es endlich an die Quadlets selbst gehen. Dazu wechseln wir über unseren Symlink in das Verzeichnis, in das die Quadlets abgelegt werden müssen:
|
|
und legen erstmal einen Unterordner für unsere Anwendung flame an und wechseln dann auch in diesen Ordner:
|
|
Flame Container
Zunächst erstellen wir das Quadlet für den Container an sich:
|
|
Inhalt:
|
|
Speichern und Schließen mit STRG+O -> ENTER STRG+X (Mac: control statt STRG)
Detaillierte Beschreibung der einzelnen Angaben:
Schlüsselwort | Beschreibung |
---|---|
[Unit] | Keine Besonderheit von Quadlets, gibt es generell in Service Units. |
Description= | Name / Beschreibung des Service |
After= | Abhängigkeiten zu anderen Diensten. Die Eintragung network-online.target bedeutet, dass der Service erst starten soll, wenn eine Netzwerkverbindung besteht. |
[Container] | Spezifische Beschreibung des Containers (Quadlet-Funktionalität) |
AutoUpdate= | Definiert, dass dieser Container vom automatischen Update berücksichtigt werden soll (podman-auto-update). Der Wert “registry” sagt aus, dass in der angegebenen Registry (z.B. Docker Hub) nach Updates gesucht wird. |
Image= | Das zu verwendende Image. Die Registry muss immer mit angegeben werden, hier “docker.io/” |
ContainerName= | Der Name, den der Container haben soll. |
HostName= | Der Hostname, der innerhalb des Containers genutzt werden soll. |
PublishPort= | Port-Mapping. Die erste Angabe ist der zu verwendende Port auf dem Host-System, die zweite Angabe der im Container. 8080:5005/tcp = TCP-Port, Host: 8080, Container: 5005 |
Volume= | Speicherbereich, in dem die Daten das Löschen des Containers überleben. Vor dem Doppelpunkt steht der Pfad auf dem Host, nach dem Doppelpunkt der Pfad im Container. Es kann direkt ein Pfad angegeben werden oder wie hier der Verweis auf das Quadlet “flame-data.volume”, das später noch erstellt wird. |
Environment= | Angabe von Environment-Variablen im Container im Format: Environment=NAME_DER_VARIABLE=WERT_DER_VARIABLE |
Secret= | Ein in den Podman Secrets eingetragenes Secret in den Container geben. In diesem Fall wird der Inhalt vom Secret “flame_password” im Container in die Environment-Variable PASSWORD geschrieben. |
[Service] | Keine Besonderheit von Quadlets, gibt es generell in Service Units. |
Restart= | Was soll passieren, wenn der Container abstürzt. Bei “always” wird er in diesem Fall immer neu gestartet. Sollte er zu schnell hintereinander abstürzen, bricht systemd dies nach 5 Versuchen ab und der Container bleibt gestoppt. |
[Install] WantedBy= | Die von systemd aus Quadlets erstellten Service-Units sind “transient”. Das bedeutet, dass man sie nicht wie von anderen Services gewohnt für den Autostart aktivieren (systemctl enable) kann. WantedBy=default.target in der Install-Section bedeutet, dass der Service automatisch mit dem System startet. Wenn das nicht so sein soll, kann die komplette [Install]-Section weggelassen werden. |
Flame Volume
In vorangegangenen Quadlet flame.container haben wir als einzubindendes Volume flame-data.volume angegeben. Diese Datei muss nun ebenfalls angelegt werden. Darin beschreiben wir Einzelheiten des Volumes, in unserem Fall muss außer dem Namen, den das Volume haben soll, nichts weiter definiert werden.
|
|
Inhalt:
|
|
Services erstellen und starten
Damit systemd jetzt funktionierende Service-Units aus den Quadlets erstellt, reicht folgender Befehl:
|
|
Dadurch wurde jetzt im System flame.service erstellt und wir können unseren Container einfach über systemctl starten:
|
|
Mit nachfolgendem Befehl können wir uns auch den aktuellen Status ansehen.
|
|
Ebenso ist der Container jetzt unter Podman sichtbar mit:
|
|
Das Log des Containers lässt sich ebenfalls direkt aufrufen:
|
|
WICHTIG: Bei jeder Anpassung an den Quadlets ist danach immer der Befehl systemctl --user daemon-reload
notwendig, damit die dazugehörigen Service-Dateien
von systemd aktualisiert werden.
Container unter systemd-Verwaltung
Wenn der Container gestoppt werden soll, muss dies jetzt über systemd, also systemctl --user stop flame.service
geschehen. Beim Stoppen wird der Container auch
jedes Mal gelöscht und beim Start neu erstellt. Nach dem Stoppen sieht man den Container also mit podman ps
nicht mehr, da er nicht mehr existiert. Alle Daten,
die in Volumes sind, gehen dabei nicht verloren.
Da es sich um einen systemd-Service handelt wird dieser nun genauso wie alle anderen Dienste und Programme überwacht. Stürzt der Container ab, wird er von systemd automatisch neu gestartet. Stoppt ihr den Container mit einem direkten Podman-Befehl, wird er ebenfalls wieder von systemd automatisch gestartet. Für Start/Stop sollte also ausschließlich systemctl genutzt werden.
Dashboard aufrufen
Gemäß unserer Konfiguration ist das Flame Dashboard jetzt über den Port 8080 erreichbar. Davor müsst ihr aber wahrscheinlich erst noch den Port in der Firewall öffnen, da Podman dies bei unprivilegierten Containern nicht von selbst macht. Wenn du unserer Alma Linux Anleitung gefolgt bist, hast du firewalld im Einsatz und kannst den Port folgendermaßen freigeben:
|
|
Jetzt kannst du im Browser das Dashboard unter http://SERVER_IP:8080 erreichen.
Abschluss
Damit hast du deinen ersten Container mit Quadlets beschrieben und in Einsatz genommen. Quadlets bieten noch eine riesige Menge an weiteren Optionen, da hilft häufig ein Blick in die sehr gute Podman Dokumentation. Unten rechts hat man hier auch die Möglichkeit die Version auszuwählen, die man gerade im Einsatz hat. Damit sieht man dann auch wirklich nur die Optionen und Befehle, die in der jeweiligen Version verfügbar sind.