Block 8 – Troubleshooting
Dauer: ca. 35 Minuten
Ziel: Systematisch Probleme lösen – ohne etwas kaputt zu machen.
💡 Roter Faden: Wir machen unseren nginx absichtlich kaputt – und reparieren ihn wieder.
8.1 Sicher analysieren – ohne etwas kaputt zu machen
Bevor wir troubleshooten: Wie bewege ich mich sicher in einer unbekannten Container-Umgebung?
Goldene Regeln
1. Niemals podman rm -f ohne zu wissen was drin läuft
2. podman exec statt podman attach
3. --rm für Test-Container verwenden
4. podman diff vor Änderungen – Zustand verstehen
5. Read-only Mounts beim Analysieren wenn möglich
exec statt attach:
# Richtig – neuer Prozess, Container bleibt beim CTRL+C
podman exec -it mein-nginx bash
# Gefährlich – Hauptprozess, CTRL+C beendet den Container
podman attach mein-nginx
Test-Container mit --rm:
# Startet, analysiert, löscht sich selbst
podman run --rm -it docker.io/library/nginx:latest bash
# → Container ist nach exit automatisch weg
Read-only in fremde Umgebung:
"
podman execist wie SSH in eine VM – nur ohne Netzwerk, ohne SSH-Daemon, direkt rein. Und--rmist wie eine Wegwerfumgebung zum Testen."
8.2 Exit-Codes verstehen
Wenn ein Container nicht läuft, ist der Exit-Code der erste Hinweis:
podman ps -a
# STATUS
# Exited (0) → Sauber beendet (z.B. einmaliger Job)
# Exited (1) → Fehler im Prozess
# Exited (125) → Podman-Fehler (z.B. Image nicht gefunden)
# Exited (126) → Befehl nicht ausführbar
# Exited (127) → Befehl nicht gefunden
# Exited (137) → SIGKILL (OOM oder podman kill)
# Exited (143) → SIGTERM (graceful stop)
"Exit Code 1 beim Container-Start ist wie ein Dienst der mit
systemctl statusauffailedsteht – erst die Logs lesen, dann raten."
# Immer zuerst Logs anschauen
podman logs mein-nginx
# Dann inspect für Details
podman inspect mein-nginx | grep -A5 '"ExitCode"'
8.3 Systematisches Troubleshooting
Problem gemeldet
│
▼
┌─────────────────┐
│ podman ps -a │ → Läuft der Container?
└────────┬────────┘
│ Nein
▼
┌─────────────────┐
│ podman logs │ → Was sagt der Prozess?
└────────┬────────┘
│ Fehler unklar
▼
┌─────────────────┐
│ podman inspect │ → Config, Mounts, Netzwerk korrekt?
└────────┬────────┘
│ Config ok
▼
┌─────────────────┐
│ podman exec │ → Manuell im Container prüfen
└────────┬────────┘
│
▼
┌─────────────────┐
│ podman run --rm │ → Frischer Container zum Vergleich
└─────────────────┘
8.4 Häufige Probleme und Lösungen
Container startet nicht
# 1. Exit-Code und Logs
podman ps -a
podman logs <container>
# 2. Image vorhanden?
podman images | grep <image>
# 3. Config-Test (nginx)
podman exec <container> nginx -t 2>&1 || \
podman run --rm nginx nginx -t -c /etc/nginx/nginx.conf
# 4. Berechtigungen (häufig bei Bind Mounts)
podman exec <container> ls -la /mnt/
Netzwerkproblem
# Ist der Port gemappt?
podman port mein-nginx
# Lauscht nginx wirklich?
podman exec mein-nginx ss -tlnp
# Falls ss fehlt: dnf install -y iproute
# Alternative: podman port mein-nginx
# Kann Container sich selbst erreichen?
podman exec mein-nginx curl http://localhost
# DNS zwischen Containern
podman exec mein-nginx nslookup mein-backend
# Falls nslookup fehlt: dnf install -y bind-utils
# Alternative: podman exec mein-nginx curl http://mein-backend
# Netzwerk-Konfiguration
podman network inspect kurs-netz
Berechtigungsproblem (Permission denied)
# Welcher User läuft im Container?
podman exec mein-nginx id
# Berechtigungen der gemounteten Dateien
podman exec mein-nginx ls -la /usr/share/nginx/html/
# Host-Seite prüfen
ls -la ~/webroot/
# SELinux-Kontext prüfen (RHEL)
ls -laZ ~/webroot/
# → Wenn Kontext nicht passt: :z oder :Z anhängen
Container frisst zu viel RAM/CPU
"Ohne Resource-Limits kann ein einziger Container den ganzen Server lahmlegen – CPU, RAM, I/O. Das ist eine der häufigsten Ursachen für unerklärliche Performance-Probleme."
# Aktueller Verbrauch aller Container
podman stats --no-stream
# Limits beim Start setzen
podman run --memory 512m --cpus 0.5 nginx
podman run --memory 512m --memory-swap 512m --cpus 0.5 nginx # swap auch begrenzen
# Limits eines laufenden Containers prüfen
podman inspect --format '{{.HostConfig.Memory}}' mein-nginx
# → 0 bedeutet: kein Limit gesetzt!
# cgroup-Übersicht aller Prozesse (wie htop, aber für cgroups)
systemd-cgtop
cgroups v1 vs. v2 – wichtig für rootless: - RHEL 8 → cgroups v1 Standard: rootless Container können keine Resource-Limits setzen - RHEL 9 → cgroups v2 Standard: rootless Resource-Limits funktionieren
# Welche cgroup-Version läuft?
podman info | grep cgroupVersion
# cgroupVersion: v2 ← RHEL 9
# cgroupVersion: v1 ← RHEL 8
8.5 RHEL 8 vs. RHEL 9 – was beim Troubleshooting anders ist
Wenn ihr auf einem älteren RHEL 8 System troubleshootet, können manche Dinge anders funktionieren als erwartet. Hier die wichtigsten Unterschiede:
┌─────────────────────────────────────────────────────────────────┐
│ RHEL 8 RHEL 9 │
├─────────────────────────────────────────────────────────────────┤
│ Netzwerk-Backend CNI Netavark + aardvark-dns │
│ Rootless Netzwerk slirp4netns pasta │
│ cgroups v1 (Standard) v2 (Standard) │
│ Storage (rootless) fuse-overlayfs native overlayfs │
│ Quadlets Ab Podman 4.4 Native │
└─────────────────────────────────────────────────────────────────┘
Symptom-basierte Diagnose
DNS zwischen Containern funktioniert nicht:
# Welches Netzwerk-Backend läuft?
podman info | grep networkBackend
# networkBackend: netavark ← RHEL 9, sollte funktionieren
# networkBackend: cni ← RHEL 8, Plugin prüfen
# RHEL 8: containernetworking-plugins installiert?
rpm -q containernetworking-plugins
# RHEL 9: aardvark-dns installiert?
rpm -q aardvark-dns
Resource-Limits bei rootless werden ignoriert:
# cgroup-Version prüfen
podman info | grep cgroupVersion
# v1 → rootless Limits nicht möglich auf RHEL 8
# v2 → sollte funktionieren
# cgroup v2 auf RHEL 8 aktivieren (Neustart nötig)
# grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"
Storage langsam oder Fehler beim Starten:
# Welcher Storage-Driver wird verwendet?
podman info | grep graphDriverName
# graphDriverName: overlay ← gut
# graphDriverName: vfs ← sehr langsam, Fallback
# Rootless auf RHEL 8: fuse-overlayfs installiert?
rpm -q fuse-overlayfs
# Rootless auf RHEL 9: native overlay verfügbar?
podman info | grep graphOptions
Quadlets funktionieren nicht:
# Podman-Version prüfen
podman --version
# < 4.4 → kein Quadlet-Support, podman generate systemd verwenden
# >= 4.4 → Quadlets verfügbar
# systemd-Version prüfen (Quadlets brauchen systemd >= 236)
systemctl --version | head -1
"Die meisten Unterschiede zwischen RHEL 8 und 9 betreffen das Netzwerk-Backend und cgroups. Ein schneller
podman infozeigt dir sofort womit du es zu tun hast."
# Schnell-Diagnose: alles Wichtige auf einen Blick
podman info | grep -E 'cgroupVersion|networkBackend|graphDriverName|rootlessNetworkCmd'
8.6 Speicher aufräumen
Im Laufe der Zeit sammeln sich Images, gestoppte Container und Volumes an:
# Übersicht was Platz belegt
podman system df
# Typische Ausgabe:
# TYPE TOTAL ACTIVE SIZE RECLAIMABLE
# Images 5 2 1.2GB 800MB
# Containers 3 1 10MB 8MB
# Volumes 2 1 500MB 200MB
# Aufräumen – nur ungenutzte Ressourcen
podman container prune # Gestoppte Container
podman image prune # Ungenutzte Images
podman volume prune # Ungenutzte Volumes
podman network prune # Ungenutzte Netzwerke
# Alles auf einmal (vorsicht!)
podman system prune
# Wirklich alles – auch ungenutzte Images
podman system prune -a
⚠️ Vorsicht mit
system prune -ain Produktion – es löscht alle Images die nicht von laufenden Containern verwendet werden. Beim nächsten Start müssen sie neu gepullt werden.
Orientierungstabelle – Troubleshooting
| Problem | Erster Schritt | Zweiter Schritt |
|---|---|---|
| Container läuft nicht | podman logs <n> |
podman inspect <n> |
| Netzwerk nicht erreichbar | podman port <n> |
podman exec <n> curl localhost |
| Permission denied | podman exec <n> id |
ls -la auf Host-Pfad |
| Container zu langsam / viel RAM | podman stats |
podman inspect → Limits prüfen |
| Disk voll | podman system df |
podman system prune |
| DNS funktioniert nicht | podman network ls |
gemeinsames Netzwerk prüfen |
| DNS auf RHEL 8 kaputt | podman info \| grep networkBackend |
rpm -q containernetworking-plugins |
| Resource-Limits ignoriert | podman info \| grep cgroupVersion |
v1 = rootless Limits nicht möglich |
| Storage langsam | podman info \| grep graphDriverName |
rpm -q fuse-overlayfs (RHEL 8) |
Übung 8 – Break & Fix
🔴 Roter Faden: Wir machen nginx absichtlich kaputt und reparieren ihn.
Aufgabe 8a – Fehlerhafte Config
# 1. Kaputte nginx-Config einrichten
mkdir -p ~/webroot-broken
cat > ~/webroot-broken/nginx.conf << 'EOF'
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html
# Fehler: Semikolon fehlt!
index index.html;
}
}
EOF
# 2. nginx mit kaputter Config starten
podman run -d \
--name broken-nginx \
-p ${PORT}:80 \
-v ~/webroot-broken/nginx.conf:/etc/nginx/conf.d/default.conf:ro \
docker.io/library/nginx:latest
# 3. Was passiert?
podman ps -a | grep broken
# → Welcher Status?
# 4. Ursache finden
podman logs broken-nginx
Fragen: 1. Welchen Exit-Code hat der Container? 2. Was sagen die Logs? 3. Wie reparierst du die Config?
Aufgabe 8b – Netzwerkproblem
# Zwei Container starten – aber im falschen Netzwerk
podman run -d --name app1 --network kurs-netz docker.io/library/nginx:latest
podman run -d --name app2 docker.io/library/httpd:latest
# app2 läuft im Standard-Netzwerk!
# Können sie sich erreichen?
podman exec app1 curl http://app2
# Wie findest du das Problem?
# Wie löst du es?
Aufgabe 8c – Speicher analysieren
podman system df
# Wie viel Platz belegen Images, Container, Volumes?
# Was kannst du sicher aufräumen?
podman container prune
podman system df
# Wie hat sich der Platz verändert?
Musterlösung Übung 8
8a
podman ps -a | grep broken
# Exited (1) – Fehler
podman logs broken-nginx
# nginx: [emerg] invalid number of arguments in "root" directive
# Fix: Semikolon in nginx.conf ergänzen
sed -i 's|root /usr/share/nginx/html$|root /usr/share/nginx/html;|' \
~/webroot-broken/nginx.conf
podman start broken-nginx
podman ps | grep broken
# Up – läuft jetzt
8b
podman exec app1 curl http://app2
# curl: Could not resolve host: app2
# Problem: app2 ist nicht im kurs-netz
podman network inspect kurs-netz
# → app2 nicht aufgelistet
# Lösung: app2 ins Netzwerk aufnehmen
podman network connect kurs-netz app2
# Jetzt funktioniert es
podman exec app1 curl http://app2
# It works!
8c
podman system df
# → Zeigt Gesamtverbrauch
podman container prune
# Removed: b1c2d3... (gestoppte Container gelöscht)
podman system df
# → Reclaimable verringert sich
Weiterführende Links
| Thema | Link |
|---|---|
| Podman Troubleshooting Guide | github.com/containers/podman/blob/main/troubleshooting.md |
| Red Hat – Debugging Containers | access.redhat.com – Investigating containers |