Zum Inhalt

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:

# Config nur lesen, nicht verändern
podman run --rm \
  -v /etc/nginx:/etc/nginx:ro \
  nginx nginx -t

"podman exec ist wie SSH in eine VM – nur ohne Netzwerk, ohne SSH-Daemon, direkt rein. Und --rm ist 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 status auf failed steht – 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 info zeigt 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 -a in 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

Thema Link
Podman Troubleshooting Guide github.com/containers/podman/blob/main/troubleshooting.md
Red Hat – Debugging Containers access.redhat.com – Investigating containers