3. Podman

3.1. Was ist Podman? Warum Containerisierung?

Podman ist ein fortschrittliches Tool zur Containerverwaltung, das sich durch seine Open-Source-Natur und seine spezielle Entwicklung für Linux-Systeme auszeichnet. Es nutzt Open Containers Initiative (OCI) Container und Container-Images, um eine effiziente Handhabung von Anwendungen zu ermöglichen. Ein Schlüsselelement von Podman ist seine daemonlose Architektur, die es von Docker unterscheidet. Statt auf einem Client-Server-Modell zu basieren, führt Podman jeden Container als unabhängigen Prozess aus. Dies eliminiert die Notwendigkeit eines zentralen Daemons, der über erweiterte Berechtigungen verfügen müsste, was die Sicherheit verbessert und die Systemverwaltung vereinfacht​​.

Podman’s Fähigkeit, sowohl als „root“ als auch „rootless“ zu operieren, ermöglicht es verschiedenen Benutzern, sicher und gleichzeitig Container auf einem einzigen System zu verwenden, ohne dabei zusätzliche Sicherheitsrisiken einzugehen. Die Unterstützung für das rootless Betreiben von Containern ist besonders vorteilhaft, da sie das Potenzial für Sicherheitsverletzungen minimiert, indem sie sicherstellt, dass Containerprozesse nicht mit umfangreichen Systemberechtigungen ausgeführt werden müssen. Dies ist besonders wichtig in Multi-Benutzer-Umgebungen, wo die Isolation von Benutzeraktivitäten entscheidend ist​.

Ein weiterer wesentlicher Vorteil von Podman ist seine nahtlose Integration mit systemd, dem init-System und dem Service Manager für Linux, was die Verwaltung von Container-basierten Diensten wesentlich vereinfacht. Diese Integration ermöglicht es, Container als systemd-Dienste zu behandeln, wodurch sie leicht in automatisierte Workflows und Skalierungsprozesse eingebettet werden können. Dies fördert eine effiziente Nutzung in großen und dynamischen Systemumgebungen, in denen Robustheit und schnelle Anpassungsfähigkeit erforderlich sind​​.

3.2. Podman Kommandos

Im folegenden werden einige Kommandos aufgelistet:

podman version

Zeigt die Remote API Version, Version, Go Version, Git Commit, Build Zeit, Betriebssystem, und Architecture an.

$ podman version
Version:      2.0.0
API Version:  1
Go Version:   go1.14.2
Git Commit:   4520664f63c3a7f9a80227715359e20069d95542
Built:        Tue May 19 10:48:59 2020
OS/Arch:      linux/amd64
podman info

Zeigt die Hostinformationen, aktuellen Speicherstatistiken, konfigurierte Containerregister und den Build von Podman an.

podman ps

Listet alle laufende Container auf.

$ podman ps
CONTAINER ID  IMAGE                            COMMAND    CREATED        STATUS        PORTS                                                   NAMES
4089df24d4f3  docker.io/library/centos:latest  /bin/bash  2 minutes ago  Up 2 minutes  0.0.0.0:80->8080/tcp, 0.0.0.0:2000-2006->2000-2006/tcp  manyports
92f58933c28c  docker.io/library/centos:latest  /bin/bash  3 minutes ago  Up 3 minutes  192.168.99.100:1000-1006->1000-1006/tcp                 zen_sanderson
podman start [options] container …

Startet einen Container mit der Containerid oder -namen. Mit der Option -all werden alle Container gestartet.

podman pause [options] [container…]

Pausiert einen oder mehrere Container. Mit der Option -all werden alle Container pausiert. Ein bestimmter Container kann mit der Containerid oder -name pausiert werden.

podman stop [options] container …

Beendet einen Container mit der Containerid oder -namen. Mit der Option -all werden alle Container beendet, ausgeschlossen sind pausierte Container.

podman events [options]

Zeigt den Zeitstempel, Typ, Status, Name und Image eines Events.

3.3. Unterschied zu Docker

Der Hauptunterschied zwischen Podman und Docker liegt in der Architektur. Docker basiert auf einem Client-Server Modell, während Podman nach dem fork-exec Modell arbeitet. D.h. Podman-Container sind Kind Prozesse des Podman Prozesses.

Mit dem Ansatz von Podman werden die Container direkt vom User gemanaged, was einen Daemon, der im Hintergrund läuft überflüssig macht. Stattdessen baut Podman auf systemd Services auf. Das ist auch, was das starten eines Podman-Containers um einiges beschleunigt.

Dieser Architektur-Unterschied macht erhöht zudem auch die Sicherheit eines Podman-Containers. Bei Docker muss der User den Docker Client aufrufen, welcher wiederum den Docker-Daemon anspricht. Der Daemon started letztendlich den Container. Bei Podman muss nur das CLI aufgerufen werden, welches sofort einen Container-Prozess startet. Dieser Prozess ist durch die Login-Session des User instanziiert.

Ein weiterer großer Unterschied sind die Userprivilegien eines Containers. Um die Sicherheit des Hostsystems zu garantieren, sollte ein Container mit möglichst geringen Rechten laufen. Podman-Container laufen per Default rootless. Der Container läuft außerdem in einem eigenen User-Namespace und ist immer mit einer User-Session verknüpft. Das kann bei der Rückverfolgung von Sicherheitslücken hilfreich sein.

Im Gegensatz dazu laufen Container-Prozesse bei Docker per Default als root. Es ist zwar möglich einen Container in einem eigenen Namespace als rootless laufen zu lassen, ist dies mit erheblichem Aufwand verbunden.

Beide Containerisierungssoftwares können also für Security konfiguriert werden, aber der Aufwand ist wesentlich geringer mit Podman.

3.4. Podman anhand unseres Beispiels

Um Podman und Podman-Compose auf einem Linux-System zu installieren, öffne das Terminal und führe die entsprechende Befehle (für Debian/Ubuntu) aus:

sudo apt-get update
sudo apt-get install podman
sudo apt-get install podman-compose

Nach Abschluss der Installation kannst du Podman verwenden.

In unserem Beispiel haben wir 2 Webserver jeweils in ihre eigenen Container gepackt. Dabei schickt ein Webserver einen POST-Request an den anderen. Eigene Container kann man analog wie bei Docker mit einer Dockerfile bauen, die bei Podman aber Containerfile heißt.

FROM alpine:latest

COPY requirements.txt /
COPY counter.py /

EXPOSE 8000

RUN apk add py3-pip python3
RUN pip install --break-system-packages -r requirements.txt
RUN chmod 755 counter.py

ENTRYPOINT ["python", "-m", "uvicorn", "counter:app", "--reload", "--host", "0.0.0.0", "--port=8000"]

Mit FROM wählt man sich ein bestehendes Image aus, auf dem das eigene Image basieren soll. Hier haben wir Alpine Linux genommen. Mithilfe von ENV kann man Umgebungsvariablen deklarieren die im Image gelten sollen. Mit COPY können Dateien vom Host-System in das Image kopiert werden. Bei uns werden damit die requirements.txt und die Pythondatei, die den Webserver startet, reinkopiert. Mit EXPOSE werden deklarierte Ports aufgemacht. Mit RUN können einfache Shell Kommandos ausgeführt werden. Hier werden zunächst python3 und pip und anschließend die requirements für das Programm installiert. Und der ENTRYPOINT ist der Befehl, der ausgeführt wird, wenn das Image gestartet wird. Die Syntax ist somit identisch wie die von Docker.

Mit dem folgenden Compose Datei können wir mit podman-compose up -d diese builden und direkt starten:

services:
  caller:
    container_name: caller
    build:
      context: ./CallerContainer
      dockerfile: Containerfile
    ports:
      - "8001:8001"

  counter:
    container_name: counter
    build:
      context: ./CounterContainer
      dockerfile: Containerfile
    ports:
      - "8000:8000"

Mit services erstellen wir verschiedene Podman-Containern in unserem Fall caller und counter. container_name wird benutzt um den Container einen spezifischen und eindeutigen Namen zu geben. Das build Schlüsselwort gibt Podman die Anweisung einen eigenen Image zu bauen. Dafür wird eine Anleitung gebraucht, die in unserem Fall die Containerfile ist. Context sorgt dafür, dass zunächst das Workdir gewechselt wird und zwar in den CallerContainer Ordner hinein. ports definiert welche Ports zum Host veröffentlicht werden sollen. Dasselbe gilt analog für den counter.

Um den Versuch zu starten, muss noch der Caller mit curl 127.0.0.1:8001/setup und der Counter mit curl 127.0.0.1:8000/start aufgerufen werden.

3.5. Literatur

Podman Kommandos: https://docs.podman.io/en/latest/Commands.html (01.05.2024)

Podman vs Docker - Betterstack: https://betterstack.com/community/guides/scaling-docker/podman-vs-docker/ (29.04.2024)

Podman vs Docker - Phoenixnap: https://phoenixnap.com/kb/podman-vs-docker (29.04.2024)

Podman: https://podman.io/docs/ (01.05.2024)

Podman Compose: https://linuxhandbook.com/podman-compose/ (01.05.2024)