Podman selbst kann auf Basis eines Dockerfiles auch neue OCI-konforme Container-Images erzeugen. Das folgende Beispiel verwendet ein sehr einfaches Dockerfile, das ein neues Fedora-Image mit einem nmap-Paket erzeugt:
cat Dockerfile
FROM fedora
RUN dnf -y update && dnf -y install nmap && dnf clean all
Den Build-Prozess starten Sie dann aus dem Verzeichnis, in dem sich das Dockerfile befindet:
podman build --tag nmap
Podman ist auch in der Lage, ein Dockerfile direkt von einem Webserver oder aus einem GitHub-Repository heraus zu beziehen. Nähere Informationen hierzu befinden sich in der Hilfe-Seite "man podman-build". Das neu erzeugte Image befindet sich im Anschluss im lokalen Container-Storage-Repository. Sie können es nun, wie Listing 3 zeigt, für das Erzeugen eines nmap-Containers verwenden.
Listing 3: Erzeugen eines nmap-Containers
$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/nmap latest 53890e393585 34 seconds ago 425 MB $ podman run --rm localhost/nmap rpm -q nmap nmap-7.70-5.fc29.x86_64
Um das Image nun beispielsweise in die öffentliche Registry "quay.io" zu pushen, muss zuerst ein Login auf dem Server stattfinden, bevor Sie das Image dann mittels »podman push
«
in die Registry laden:
podman login quay.io -u benutzer -p password
podman push localhost/nmap quay.io/tscherf/nmap
Wer unabhängig von einem Dockerfile ein neues Container-Image erzeugen möchte, der sollte sich einmal das Tool Buildah [2] ansehen. Das Werkzeug bietet sich gerade dann an, wenn Sie neue Images skriptbasiert aus der Taufe heben wollen. Wir haben Buildah in der Ausgabe 03/2018 näher vorgestellt [3].
Pods sind eigentlich ein Begriff aus der Kubernetes-Welt und bezeichnen eine Ansammlung von Containern, die sich bestimmte Ressourcen teilen. Hierbei kann es sich etwa um den Namespace des Kernels oder auch CGroups handeln. Da die Container somit auch den gleichen Netzwerk-Namespace verwenden, können die Container eines Pods untereinander kommunizieren, ohne dass diese eine routbare IP-Adresse benötigen. Jeder Pod verfügt über einen sogenannten Infrastruktur-Container auf Basis des Images "k8s.gcr.io/pause". Die Aufgabe dieses Containers ist es, die Ressourcen für alle anderen Container in diesem Pod dauerhaft zur Verfügung zu stellen. Dazu zählen beispielsweise die Kernel-Namespaces, aber auch CGroups und Netzwerkressourcen. Des Weiteren kümmert sich dieser Container um die Kommunikation mit dem Tool Podman.
Auch bekommt jeder Container in einem Pod eine eigene Monitoringinstanz zugewiesen (conmon). Diese überwacht den oder die Prozesse, die in dem eigentlichen Container ablaufen, und sorgt auch dafür, dass Podman sich zu jedem Zeitpunkt mit einem »tty
«
innerhalb des Containers verbinden kann. Diese Monitoringinstanz ist notwendig, da Podman keinen Daemon im Hintergrund verwendet, der das Monitoring übernehmen könnte.
Das folgende Beispiel zeigt, wie Sie einen neuen Pod erzeugen und diesem im Anschluss einen Container zuweisen können:
podman pod create --name web
Ob der Pod erfolgreich erzeugt wurde, bringt der Befehl »podman pod ps
«
ans Licht. Bei einem Blick, welche Container in diesem Pod vorhanden sind (Listing 4), ist dies aktuell natürlich nur der Infrastruktur-Container. Um dem Pod einen neuen Container hinzuzufügen, geben Sie den Namen des Pods einfach beim Starten des Containers mit an. Der Aufruf von »podman pod list
«
bestätigt dann auch (Listing 5), dass sich nun zwei Container im Pod befinden.
Listing 4: Container im Pod anzeigen
$ podman ps -a –pod CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD 9062dac6ff19 k8s.gcr.io/pause:3.1 About a minute ago Created dfd09806b03c-infra dfd09806b03c
Listing 5: Zwei Container in einem Pod
$ podman run -d --pod web docker.io/library/httpd httpd -D FOREGROUND $ podman pod list POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID dfd09806b03c web Created 46 seconds ago 2 9062dac6ff19
Seit der Podman-Version 1.0 besteht auch die Möglichkeit, beim Starten eines Containers direkt einen neuen Pod zu erzeugen. Den Befehl dazu und das entsprechende Ergebnis zeigt Listing 6 – in diesem Fall hat also ein einziges Kommando ausgereicht, um einen neuen HTTPD-Container innerhalb eines neuen Pods zu erzeugen. Der Infrastruktur-Container wurde natürlich auch direkt beim Erzeugen des Pods mit angelegt. Da Sie den HTTPD-Port des Webserver-Containers diesmal auf den Host-Port 8080 umgeleitet haben, bedarf es auch keiner root-Rechte, um den Container zu starten.
Listing 6: Pod bei Container-Start erzeugen
$ podman run -dt --pod new:httpd -p 8080:80 docker.io/library/httpd httpd -D FOREGROUND $ podman ps –pod CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD7e337cbed38e docker.io/library/httpd:latest httpd -D FOREGROU 19 seconds ago Up 18 seconds ago 0.0.0.0:8080->80/tcp confident_ritchie 119a122bdab3 $ podman pod list POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID 119a122bdab3 httpd Running 30 seconds ago 2 b8301dde3144 $ links -dump http://localhost:8080 It works!
Die Möglichkeit, lokale Pods zu erzeugen, ist sicherlich für Entwickler am interessantesten, besteht so doch die Möglichkeit für eine Microservice-basierte Anwendung, die über mehrere Container verteilt ist, ohne dass hierfür ein kompletter Kubernetes-Cluster vorhanden sein muss. Um die Anwendung dann aber in einen solchen Cluster zu übertragen, bietet Podman auch eine sehr elegante Option an: Mit dem Aufruf »podman generate kube
«
erzeugt das Tool eine YAML-Datei, die Sie dann auf ein Kubernetes-System kopieren können, um dort die Container und Pods zu erzeugen, so wie es in der YAML-Datei aufgeführt ist.