Podman ======= .. index:: Podman Was ist Podman? Warum Containerisierung? ---------------- .. index:: Was ist Podman? 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​​. Podman Kommandos ---------------- .. index:: Podman Kommandos Im folegenden werden einige Kommandos aufgelistet: .. code-block:: version podman version Zeigt die Remote API Version, Version, Go Version, Git Commit, Build Zeit, Betriebssystem, und Architecture an. .. code-block:: version $ 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 .. code-block:: info podman info Zeigt die Hostinformationen, aktuellen Speicherstatistiken, konfigurierte Containerregister und den Build von Podman an. .. code-block:: Container podman ps Listet alle laufende Container auf. .. code-block:: Contianer $ 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 .. code-block:: start podman start [options] container … Startet einen Container mit der Containerid oder -namen. Mit der Option ``-all`` werden alle Container gestartet. .. code-block:: pause 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. .. code-block:: beenden podman stop [options] container … Beendet einen Container mit der Containerid oder -namen. Mit der Option ``-all`` werden alle Container beendet, ausgeschlossen sind pausierte Container. .. code-block:: events podman events [options] Zeigt den Zeitstempel, Typ, Status, Name und Image eines Events. .. code-block:: events $ podman events 2019-03-02 10:33:42.312377447 -0600 CST container create 34503c192940 (image=docker.io/library/alpine:latest, name=friendly_allen) 2019-03-02 10:33:46.958768077 -0600 CST container init 34503c192940 (image=docker.io/library/alpine:latest, name=friendly_allen) 2019-03-02 10:33:46.973661968 -0600 CST container start 34503c192940 (image=docker.io/library/alpine:latest, name=friendly_allen) 2019-03-02 10:33:50.833761479 -0600 CST container stop 34503c192940 (image=docker.io/library/alpine:latest, name=friendly_allen) 2019-03-02 10:33:51.047104966 -0600 CST container cleanup 34503c192940 (image=docker.io/library/alpine:latest, name=friendly_allen) Unterschied zu Docker --------------------- .. index:: 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. Podman anhand unseres Beispiels ------------------------------- .. index:: 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: .. code-block:: bash 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. .. code-block:: Dockerfile 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: .. code-block:: yaml 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. .. _lit: 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)