Zum Inhalt

Block 1 – Grundkonzepte & Theorie

Dauer: ca. 40 Minuten
Ziel: Verstehen was Container sind, wie sie funktionieren und warum Podman auf RHEL die erste Wahl ist.

💡 Roter Faden: In diesem Kurs arbeiten wir durchgehend mit einem nginx-Container. Was wir hier starten, werden wir in jedem Block weiter ausbauen.


Einstieg – Eine bekannte Situation

Stell dir vor: Du bekommst einen Anruf.

"Der nginx läuft nicht mehr."

Du loggst dich ein. systemctl status nginx – kein Dienst. ps aux | grep nginx – kein Prozess. Nichts.

Dann bemerkst du:

podman ps -a
# CONTAINER ID  IMAGE   STATUS
# a1b2c3d4e5f6  nginx   Exited (1) 2 minutes ago

Willkommen in der Welt der Container. Alles was du bisher über Dienste und Prozesse weisst, gilt noch – aber die Werkzeuge sind andere. Genau das schauen wir uns heute an.


1.1 Was ist ein Container?

Ein Container ist ein isolierter Prozess auf dem Host-System. Er teilt sich den Kernel mit dem Host, hat aber seine eigene Sicht auf Dateisystem, Netzwerk, Prozesse und Benutzer.

Container vs. Virtuelle Maschine

┌─────────────────────────────────────────────────────────────────┐
│                      VIRTUELLE MASCHINE                         │
│  ┌──────────────────────┐    ┌──────────────────────┐           │
│  │   App A + Libraries  │    │   App B + Libraries  │           │
│  ├──────────────────────┤    ├──────────────────────┤           │
│  │   Guest OS (Linux)   │    │   Guest OS (Linux)   │           │
│  └──────────┬───────────┘    └──────────┬───────────┘           │
│             │           Hypervisor      │                        │
│             └───────────────┬───────────┘                        │
│                         Host OS                                  │
│                         Hardware                                 │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                         CONTAINER (Podman)                       │
│  ┌──────────────────────┐    ┌──────────────────────┐           │
│  │   App A + Libraries  │    │   App B + Libraries  │           │
│  └──────────┬───────────┘    └──────────┬───────────┘           │
│             │     Podman (daemonless)    │                        │
│             └───────────────┬───────────┘                        │
│                   Host OS (gemeinsamer Kernel)                   │
│                         Hardware                                 │
└─────────────────────────────────────────────────────────────────┘
Virtuelle Maschine Container
Startzeit 1–2 Minuten Sekunden
Grösse GBs (volles OS) MBs (nur App + Libs)
Isolation Eigener Kernel Gemeinsamer Kernel
Overhead Hoch Minimal

"Eine VM ist wie ein eigenes Haus mit eigenem Fundament. Ein Container ist wie eine Wohnung im gleichen Gebäude – eigene Türe, eigene Einrichtung, aber gemeinsame Tragstruktur."

Vorteile für den Sysadmin-Alltag

  • Applikation läuft überall gleich – kein "bei mir funktioniert's"
  • Kein Dependency-Chaos mehr auf dem Host
  • Schnell starten, schnell wegwerfen, schnell ersetzen
  • Mehrere Versionen der gleichen App parallel betreiben

1.2 Wie funktioniert das technisch?

Container bauen auf drei Linux-Kernelmechanismen auf:

Mechanismus Aufgabe Analogie
Namespaces Isolation: Container sieht nur seine eigenen Prozesse, sein Netzwerk, sein Dateisystem Wie chroot, aber viel mächtiger
cgroups Ressourcenlimitierung: CPU, RAM, I/O pro Container begrenzen Wie ulimit, aber granularer
Union Filesystem Layer-basiertes Dateisystem: Images aus übereinandergestapelten Schichten Wie Git-Commits übereinandergelegt

1.3 Images, Layer und der R/W-Layer

Das Layer-Modell

Ein Image ist aus mehreren read-only Schichten aufgebaut. Jede Schicht entspricht einem Schritt beim Bauen des Images:

┌───────────────────────────────────────┐
│         nginx config Layer            │  ← COPY nginx.conf  (read-only)
├───────────────────────────────────────┤
│         nginx binary Layer            │  ← RUN dnf install nginx  (read-only)
├───────────────────────────────────────┤
│         UBI Base Image                │  ← FROM ubi9/ubi-minimal  (read-only)
└───────────────────────────────────────┘
  ▲ Image – unveränderlich, shared zwischen allen Containern

Gemeinsame Schichten werden nur einmal auf der Disk gespeichert. Zehn nginx-Container teilen sich das gleiche Basis-Image.

Was passiert beim podman run?

Beim Start legt Podman eine dünne read/write Schicht oben drauf – temporär, nur für diesen Container:

┌───────────────────────────────────────┐  ← R/W Layer  (temporär, nur dieser Container)
├───────────────────────────────────────┤  ← nginx config Layer  (read-only, shared)
├───────────────────────────────────────┤  ← nginx binary Layer  (read-only, shared)
└───────────────────────────────────────┘  ← UBI Base Image      (read-only, shared)

Ein Image – beliebig oft gestartet

Das gleiche Image kann parallel in mehreren Containern laufen. Jede Instanz bekommt ihre eigene R/W-Schicht:

Image: nginx:latest  (read-only, einmal auf Disk)
         ├──→  Container web1  [eigene R/W Schicht]
         ├──→  Container web2  [eigene R/W Schicht]
         └──→  Container web3  [eigene R/W Schicht]
podman run -d --name web1 nginx
podman run -d --name web2 nginx
podman run -d --name web3 nginx
# Alle drei laufen – gleiches Image, unabhängige Container

"Das Image ist wie ein VM-Template. Jedes Mal wenn du einen Container startest, bekommst du eine frische Kopie – beliebig oft, sofort."

Änderungen sind flüchtig

Alles was du im Container änderst, liegt in der R/W-Schicht. Löscht du den Container, ist die R/W-Schicht weg:

podman exec -it mein-nginx bash
echo "test" > /tmp/meinedatei.txt
exit

podman rm mein-nginx
# → /tmp/meinedatei.txt ist weg. Das Image ist unberührt.

Persistenz nur über Mounts oder Volumes:

Bind Mount  →  Ordner vom Host direkt in den Container eingebunden
Volume      →  Von Podman verwalteter Speicher, überlebt den Container

"Was du im Container änderst ist beim nächsten Start weg – ausser du hast einen Mount. Das ist gewollt: jeder Start ist eine saubere, reproduzierbare Umgebung."

→ Mehr dazu in Block 3.


1.4 Docker vs. Podman

Auf RHEL ist Podman der Standard – kein Docker:

Docker Podman
Daemon Zentraler dockerd läuft als root Kein Daemon – daemonless
Root Daemon läuft immer als root Rootless möglich
RHEL-Support Nicht offiziell supportet Red Hat Produkt, vollständig supportet
Befehle docker run, docker ps podman run, podman ps
Kompatibilität Syntax nahezu identisch
Pods Nur via Kubernetes Nativ unterstützt

Wichtig: Wer Docker kennt, kennt 95% von Podman. docker run nginx wird einfach zu podman run nginx.

Warum kein Daemon ein Vorteil ist

Docker:                          Podman:
┌─────────────────────┐          ┌─────────────────────┐
│  dockerd (root)     │          │  kein Daemon        │
│  ┌───────────────┐  │          │                     │
│  │  Container 1  │  │          │  Container 1 ──────→ Kernel
│  │  Container 2  │  │          │  Container 2 ──────→ Kernel
│  │  Container 3  │  │          │  Container 3 ──────→ Kernel
│  └───────────────┘  │          │                     │
└─────────────────────┘          └─────────────────────┘
Daemon kompromittiert             Kein Single Point
= root auf dem System             of Failure

"Der Docker-Daemon ist wie ein Hausmeister mit Generalschlüssel der immer im Gebäude ist. Podman hat keinen Hausmeister – jeder Bewohner öffnet seine eigene Türe."

⚠️ Sicherheitswarnung: sudo podman / sudo docker

Wer sudo podman oder sudo docker ausführen darf – oder Zugriff auf den Docker-Socket hat – hat effektiv root-Rechte auf dem ganzen Host:

# Triviales Beispiel: Host-Filesystem als root lesen
sudo podman run --rm -v /:/host alpine cat /host/etc/shadow

# Noch gefährlicher: Shell als root auf dem Host
sudo podman run --rm -it -v /:/host alpine chroot /host
# → Du bist root auf dem Host!

"sudo podman ist wie sudo bash – wer Container mit root-Rechten starten darf, kann auf alles auf dem Host zugreifen. Rootless Podman ohne sudo ist deshalb kein Komfort-Feature, sondern eine Sicherheitsmassnahme."

Das ist der Grund warum wir in diesem Kurs konsequent rootless arbeiten – ohne sudo.

Podman Pods

Podman kennt das Konzept der Pods – direkt von Kubernetes inspiriert: - Ein Pod gruppiert mehrere Container die sich Netzwerk und Storage teilen - Alle Container in einem Pod kommunizieren über localhost - Im Alltag selten direkt nötig – aber der Begriff begegnet dir bei Kubernetes wieder


1.5 Images und Registry

Was ist eine Registry?

Eine Registry ist ein Speicher für Images:

┌──────────┐   push   ┌──────────────┐   pull   ┌──────────────┐
│Entwickler│ ───────→ │   Registry   │ ───────→ │    Server    │
│baut Image│          │  (Artifactory│          │startet Contai│
└──────────┘          │  docker.io   │          └──────────────┘
                      │  quay.io)    │
                      └──────────────┘

Bekannte Registries:

Registry URL Nutzung
Red Hat Registry registry.redhat.io Offizielle RHEL/UBI-Images
Quay.io quay.io Red Hat Community Registry
Docker Hub docker.io Allgemeine öffentliche Images
Firmen-Registry Artifactory intern Eigene/interne Images

Image-Namen verstehen

registry.redhat.io  /  ubi9/nginx  :  1.24
│                      │              │
│                      │              └─ Tag (Version)
│                      └─ Image-Name
└─ Registry-Adresse

Empfehlung: Immer vollständige Image-Namen verwenden – nie nur nginx, immer docker.io/library/nginx:latest.


1.6 OCI-Standard & verwandte Tools

OCI = Open Container Initiative – offener Standard für Images und Container-Laufzeit. Ein Docker-Image läuft auch mit Podman, und umgekehrt.

Tool Zweck
podman Container starten, verwalten, inspizieren
buildah Images bauen – intern von Podman verwendet
podman compose Compose-Dateien ausführen (integriert seit Podman 4.7)

Übung 1 – Erste Schritte mit nginx

🔴 Roter Faden: Diesen nginx-Container begleiten wir durch den ganzen Kurs.

💡 Variablen setzen – einmalig pro Session, dann in Block 2 erklärt:

export USER_NAME=$(whoami)
export PORT=8100   # deinen Port aus ~/.kurs-info verwenden

Aufgabe 1a – Image pullen und inspizieren

podman pull docker.io/library/nginx:latest
podman images
podman history docker.io/library/nginx:latest

Fragen: 1. Wie viele Layer hat das nginx-Image? 2. Wie gross ist das Image?

Aufgabe 1b – Container starten

# nginx starten – Port aus deiner ~/.kurs-info
podman run -d --name mein-nginx -p ${PORT}:80 docker.io/library/nginx:latest
podman ps
curl http://localhost:${PORT}

Aufgabe 1c – Flüchtigkeit live erleben

# Datei im Container erstellen
podman exec -it mein-nginx bash
echo "ich bin temporaer" > /tmp/test.txt
exit

# Container löschen und neu starten
podman stop mein-nginx && podman rm mein-nginx
podman run -d --name mein-nginx -p ${PORT}:80 docker.io/library/nginx:latest

# Datei noch da?
podman exec -it mein-nginx bash
cat /tmp/test.txt
exit
podman run -d --name mein-nginx -p ${PORT}:80 docker.io/library/nginx:latest

Datei noch da?

podman exec -it mein-nginx bash cat /tmp/test.txt exit

---

## Musterlösung Übung 1

### 1a
```bash
podman images
# REPOSITORY                TAG     IMAGE ID      SIZE
# docker.io/library/nginx   latest  a1b2c3d4e5f6  187 MB

podman history docker.io/library/nginx:latest
# → 7–10 Layer typischerweise

1b

podman ps
# CONTAINER ID  IMAGE   STATUS        PORTS
# a1b2c3d4      nginx   Up 5 seconds  0.0.0.0:${PORT}->80/tcp

curl http://localhost:8100
# <!DOCTYPE html>... ← nginx Welcome Page

1c

cat /tmp/test.txt
# cat: /tmp/test.txt: No such file or directory

Erklärung: Die Datei lag in der R/W-Schicht des Containers. Mit podman rm wurde diese Schicht gelöscht. Der neue Container hat eine frische, leere R/W-Schicht – das Image selbst ist unberührt.

Konsequenz für den Alltag: Logs, Daten, Konfigurationsänderungen die nur im Container gemacht werden, sind beim nächsten Start weg → immer Mounts oder Volumes verwenden für alles was persistiert werden soll.


Thema Link
Podman offizielle Dokumentation docs.podman.io
Red Hat – Container Guide (RHEL 9) access.redhat.com – Building, Running and Managing Containers
Red Hat – Was ist Podman? redhat.com – What is Podman
Red Hat UBI – Universal Base Images catalog.redhat.com/software/base-images
OCI – Open Container Initiative opencontainers.org