Linux - Open Source

Docker oder Podman

Bild eines chaotischen Dachboden, mittig 2 offen Kartons mit vielen Büchern. Der eine Karton trägt ein an das Docker-Logo angelehnten Aufdruck, der andere ein an das Podman-Logo angelehnten Aufdruck

Gemeinsamkeiten und Unterschiede der beiden Container-Manager

Wozu überhaupt Container ?

Containering (zB bei Docker oder Podman) beschreibt eine Methode, bei dem unterschiedlichste Instanzen den Kernel eines Hostsystems nutzen können. Oder einfacher beschrieben: komplette Programme, Dienste, Datenbanken oder auch Betriebssysteme laufen in einem abgetrennten Bereich, ohne Zugriff auf den Host oder auf andere Instanzen zu haben.

Theoretisch sollte ein in einem Container laufendes Programm keine Möglichkeit haben, aus diesem auszubrechen und auf das Hostsystem zuzugreifen. Weiterhin bringt ein Container alle zum Betrieb notwendigen Bibliotheken bzw Zusatzprogramme direkt mit. In den meißten Fällen kann man einen Container nach dem Download und einer sehr kurzen Konfiguration starten und damit verwenden. Abhängigkeiten zu bestimmten Versionen anderer Programme oder Bibliotheken werden nahezu ausgeschlossen.

Dieser große Vorteil ist gleichzeitig auch einer der wenigen Nachteile. Da der Container alle für das jeweilige Programm notwendigen Treiber / Bibliotheken mitliefert, bedeutet dies letztlich, dass man einen bestimmten Treiber / Bibliothek in jedem laufenden Container separat auf dem Rechner hat. Wird nun ein schwerwiegender Fehler darin gefunden, müssen alle Container separat aktualisiert werden. Ein Beispiel dafür ist die SSL/TLS-Schwachstelle Heartbleed – jeder Container der die OpenSSL-Bibliothek nutzte, musste aktualisiert werden.

2013 – Docker

Zwar gab es Ansätze zur Containervirtualisierung schon viele Jahre vorher, in der Allgemeinheit bekannt wurden diese aber erst als 2013 von der damaligen Firma dotCloud das Programm Docker für Linux veröffentlicht wurde. Zusammen mit der offenen Verwaltungsplattform für die Container – Docker Hub – konnten Progammierer bzw Anbieter unterschiedlichster Programme dort ihre Anwendungen bereitstellen. Auf Docker Hub kann man verfügbare Container durchsuchen und notwendige kurze Schritte zur jeweiligen Konfiguration finden.

Docker Logo

Die Installation und Konfiguration eines Containers erfolgt anschließend entweder über ein Frontend, oder (eigentlich am einfachsten) über die Kommandozeile.

$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

Das Kommando docker run hello-world installiert den Container hello-world und startet ihn. Im Prizip handelt es sich dabei nur um eine Art proof-of-concept, der Container stoppt nachdem der obige Text ausgegeben wurde.

2018 – Podman

Etwas später wurde mit Podman eine Weiterentwicklung veröffentlicht. Das soll nicht bedeuten, dass Podman ein Nachfolger von Docker ist. Mit Weiterentwicklung ist ein anderer Ansatz gemeint, der Nachteile von Docker zu umgehen versucht. Mehr dazu anschließend im Vergleich.

Podman Logo

Podman ist ebenso wie Docker eine Containervirtualisierung und kann ebenso auf zB Docker Hub zugreifen. Für eine Interoperabilität sind die grundlegenden Kommandos austauschbar. Für einen Umstieg in einer Standard-Umgebung von Docker auf Podman (oder anders herum) ist es ausreichend, die Kommandos via alias auszutauschen.

$ alias docker=podman

Docker oder Podman für Windows

Beide Containervirtualisierungen wurden ursprünglich für Linux entwickelt, laufen aber auch unter Windows. Dadurch kann man fast alle Container direkt auf Windows starten und betreiben. Technisch nutzt Windows dafür eine kleine virtuelle Linux-Umgebung: WSL2 – das Windows Subsystem for Linux 2.

Docker Desktop und Podman Desktop verwenden WSL2 und bringen jeweils ihren eigenen Container-Manager mit. In Kombination mit WSL2 starten sie einen Linux-Kernel, der die Befehle des Container-Managers korrekt ausführt.

Letztlich macht der Betrieb von Containern in einer Windows-Umgebung nicht wirklich Sinn – schließlich kann man den Container ja direkt auf einem Linux-Server ausführen, anstatt dieses zu virtualisieren.

„Der eigentlich beabsichtigte Mischbetrieb (Windows + Linux-Container) ist mäßig erfolgreich“

c’t 5/2018

Die Nutzung von Docker bzw Podman unter Windows ist zumindest recht stark bei Entwicklern verbreitet. Eine Erhebung bei der State of App Dev 2025 ergab einen Anteil von 53% Linux und 47% Windows bei den Entwicklern.

Das bedeutet, die Entwicklungsumgebung für einen Docker-Container befindet in diesen Fällen auf einem Windows-System – dort können die Entwickler die Container lokal ausführen und testen. Der produktive Einsatz findet anschließend fast ausschließlich in Linux-Umgebungen statt.

Symbolbild Programmierung

Technische Unterschiede

Docker nutzt einen zentralen Prozess – dockerd – als Daemon. Dieser verwaltet Images, Container, Netzwerke, Volumes. Historisch läuft dieser Prozess in sehr vielen Umgebungen mit Root-Rechten. Das hat allerdings den Nachteil, dass ein Container oder ein Anwender der einen Container nutzt oder verwaltet, durch etwaige Softwarefehler einen Vollzugriff auf das Hostsystem erlangen könnte. Um diese Gefahr zu umgehen wurde Docker-rootless entwickelt, was meiner Meinung nach das ganze Problem aber nur verschiebt. In einer Multi-User-Umgebung oder auf öffentlichen Servern kann ein eigener „docker-rootless-user“ laufen, auf diesen müssen dann allerdings wieder alle Nutzer bzw Container Zugriff haben. Bei einem theoretischen Bug in Docker hat man so weiterhin Zugriff auf die anderen Container.

Podman ist daemonless. Es gibt keinen permanenten Prozess. Jeder einzelne Container startet einen eigenen Prozess. Genau genommen ist Podman lediglich eine CLI, die Container-Operationen an die darunter liegenden Kernel-Funktionen delegiert. Der Vorteil ist, dass Podman von jedem Nutzer verwendet werden kann – die jeweiligen Container laufen dann ausschließlich mit den Rechten des Nutzers. Auch potentielle Softwarefehler würden keinen Vollzugriff und ebenso keinen Zugriff auf die Container anderer Nutzer erlauben. Ein weiterer Vorteil ist es, „pods“ zu erstellen. Das kann man sich am einfachsten als Container-Gruppe vorstellen.

TypDockerPodman
Architekturdaemon-basiert (dockerd)daemonless (Container laufen als User-Prozess)
SicherheitsmodellDaemon ist Angriffspunktkein daemon, starke isolation
KompatibilitätDocker-Images100% kompatibel
Systemd-Integrationbegrenzt, workarounds notwendigsehr gut, automatische service-files
Multi-Userschlecht, dockerd gehört einem Nutzersehr gut, eigener Nutzer pro Container möglich
Netzwerk (rootless)slirp4netnsslirp4netns oder pasta (schneller)
Pod-Support (Kubernetes-ähnlich)über Docker Composenative Pods
Windows-SupportDocker Desktop + WSL2Podman Machine + WSL2
Linux-Supportnahezu alle DistributionenStandard in Fedora, RHEL, CentOS/Alma, OpenSUSE
ZielgruppeEntwickler, DevOps, klassische Docker-NutzerSicherheit, Enterprise, Kubernetes-Nah
Kubernetes

Kubernetes ist sozusagen ein Betriebssystem für Container-Cluster. Die Container werden vom Kubernetes automatisch auf den verfügbaren Servern im Cluster verteilt, um Ressourcen optimal zu verteilen. Abgestürzte Container werden automatisch neu gestartet, Container von ausgefallenen Servern im Cluster selbstständig auf andere verschoben.

Podman pod vs Docker compose

Podman bringt die Möglichkeit von pods mit, und entspricht der Pod-Architektur von Kubernetes.

Ein Pod ist wie schon kurz angerissen quasi eine Gruppe mehrerer Container, die sich die selbe IP-Adresse teilen. Alle Container in einem pod können untereinander via localhost kommunizieren. Schon in einer kleinen Umgebung kann dies Sinn machen, wenn zB eine Webanwendung läuft die auf eine Datenbank wie MariaDB oder PostgreSQL zugreift.

Symbolbild docker-compose

Als Beispiel erstelle ich hier einen pod mit Namen „MyPod“ und einer Weiterleitung von lokal 8080 auf Port 80 innerhalb des Containers

podman pod create --name MeinPod -p 8088:80

Mit dem Flag „–pod“ binde ich einen neuen Container an den zuvor erstellten pod.

podman run -d --name MeineDB --pod MeinPod -e ...
podman run -d --name MeinWebService --pod MeinPod -e ...

Docker bietet diesen Weg via compose, die notwendige Datei wird für den jeweiligen Einsatzzweck einmalig erstellt.

yaml

version: "3.9"

service:
 meineDB:
  image: meinedb:latest
  container_name: meineDB
  environment:
    ...
  networks:
   - appnet

 webapp:
  image: webapp:latest
  container_name: webapp
  depends_on:
   - meineDB
  ports:
   - "8088:80"
  environment:
   ...
  networks:
   - appnet

Docker ist im späteren Verlauf einfacher zu verwalten. Die initiale Einrichtung ist ein wenig komplizierter, ein Update eines Containers bei neuer Version ist später jedoch einfacher.

docker compose pull webapp
docker compose up -d webapp

Podman erwartet wie bei der initialen Einrichtungen erneut den kompletten Container-Aufruf bei einem Update.

podman pull webapp:latest
podman stop webapp-container
podman rm webapp-container
podman run -d --name MeinWebService --pod MeinPod -e ... webapp:latest

Aber: podman-compose

Allerdings bringt auch podman eine ähnliche Lösung zu docker-compose mit, das Äquivalent lautet podman-compose. Dabei handelt es sich um ein Python-Script, welches weitestgehend (80-90%) die gleiche Syntax verarbeitet wie docker-compose.

Einige docker-spezifische Optionen funktionieren bei podman-compose leider nicht, so zum Beispiel BuildKit-Features in einem build: block, oder der deploy: block. Das betrifft zumeist sehr komplexe compose-Dateien (Swarm, GPU oder spezielle Netzwerk-Features), welche aber fast immer an podman angepasst werden können.

Wozu podman pod wenn es podman-compose gibt

Pods laufen isolierter und sind vom Setup näher an Kubernetes dran als podman-compose. Dabei simulieren die pods exakt die Zusammensetzung eines Cluster-Container. Dies ist zum Beispiel bei der Entwicklung und Tests von großem Vorteil – es ist kein großes Kubernetes notwendig um neue Container in dieser Umgebung auszuprobieren.

Als weiteres kann in einer Multi-User-Umgebung jeder Anwender pods erstellen und starten, Ressourcen und Netzwerk laufen sauber voneinander getrennt. Compose nutzt kein derartiges Netzwerk, sondern kommuniziert über den Service-Namen.

FunktionDocker / Podman composePodman Pod
Interne KommunikationService-Name (zB mariadb:3306)Gleiche IP, Zugriff über localhost:3306
Netzwerk-TypEigenes Netzwerk für jeden Stack (bridge)Jeder Pod hat eigenes Netzwerk
LocalhostZeigt nur auf den einzelnen ContainerZeigt auf die Pod-Host-IP für alle Container im Pod
DNSCompose stellt DNS für Services bereit (Service-Name:Port)Nicht notwendig, localhost oder Container-Name
Host-Port Mappingim Compose YAML definiert (Ports: „8088:80“)beim Erstellen des Pod ( -p 8088:80)

Fazit

Podman und Docker basieren auf der gleichen Grundidee, sind bei vielen alltäglichen Kommandos kompatibel, verfolgen aber unterschiedliche Architekturphilosophien.

Docker verwendet einen zentralen Daemon und bringt ein umfassendes Ökosystem mit. In Desktop-Entwicklungsumgebungen (Docker Desktop / Compose) ist es komfortabel einsetzbar.

Podman läuft rootless + ohne Daemon und ist daher vom Punkt Sicherheit im Vorteil. In seltenen Einzelfällen kann es Probleme geben, einen Container zu nutzen (zB wenn die Docker-API explizit angesprochen wird). Podman unterstütz vom Design her systemd, das Pod-Konzept ist sehr nach an Kubernetes angelehnt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert