📦Container: Lebenszyklus, Isolation, Neustarts

Ein Container ist ein Prozess mit Zuständen, eingeschränkter Sicht (Namespaces) und begrenzten Ressourcen (cgroups). Restart-Policies und Healthchecks sorgen dafür, dass er am Laufen bleibt – oder dass man merkt, wenn nicht.

🔄Lebenszyklus

Probiere die Befehle aus – der Automat zeigt, was in welchem Zustand erlaubt ist.
startpauseunpausestop / kill / Endestart / restartAbsturz + Policyrmcreatecreatedrunningpausedrestartingexitedremoved

Aktueller Zustand: kein Container · blaue Knöpfe sind im aktuellen Zustand erlaubt.

Was passiert?
  • Starte mit docker create.

🛡️Isolation: Namespaces und cgroups

🔭 Namespaces – was sieht wer?

pidPID
ps: PID 1 nginx: master process, PID 29 nginx: worker process
Eigene Prozessnummern. Der Hauptprozess ist PID 1 – er muss Signale selbst behandeln und Zombies einsammeln (oder --init nutzen).
netNetzwerk
lo, eth0 (172.17.0.2/16)
Eigene Schnittstellen, Routen, iptables und Ports. Zwei Container können beide Port 80 nutzen.
mntMount
/ = OverlayFS-merged des Images
Eigener Mount-Baum; per pivot_root wird das Image-Dateisystem zur Wurzel. Volumes werden hineingemountet.
utsUTS
hostname: 3f9c2a7d1b4e (Kurz-ID)
Eigener Hostname und Domainname – standardmäßig die ersten 12 Zeichen der Container-ID.
ipcIPC
getrennte System-V-IPC / POSIX-Queues
Getrennte Interprozess-Kommunikation (Shared Memory, Semaphoren, Message Queues).
cgroupcgroup
/sys/fs/cgroup = eigene cgroup als Wurzel
Der Container sieht seine eigene cgroup als Wurzel und nicht die Hierarchie des Hosts.
userUser (optional)
UID 0 ↦ Host-UID 100000 (mit userns-remap / rootless)
Standardmäßig AUS: root im Container ist root auf dem Host (mit reduzierten Capabilities). Mit userns-remap oder rootless Docker wird UID 0 auf einen unprivilegierten Bereich abgebildet.

PIDs und Kurz-ID sind Beispielwerte. Nachprüfen: ls -l /proc/<pid>/ns auf dem Host.

🎚️ cgroups v2 – Grenzen für Ressourcen

Namespaces begrenzen, was ein Container sieht – cgroups, wie viel er verbraucht. Docker schreibt die Optionen in Steuerdateien der cgroup.

$ docker run --memory 256m --cpus 1.5 --pids-limit 100 nginx

# /sys/fs/cgroup/system.slice/docker-<id>.scope/
memory.max        268435456
memory.swap.max   268435456   ← ohne --memory-swap: gleich viel Swap erlaubt
cpu.max           150000 100000   ← Quota/Periode in µs = 1.5 CPUs
pids.max          100
  • ▸ Überschreitet der Container memory.max, beendet ihn der OOM-Killer (Exit-Code 137, OOMKilled: true).
  • cpu.max drosselt: in jeder 100-ms-Periode höchstens 150 ms CPU-Zeit (über alle Kerne).
  • pids.max schützt vor Fork-Bomben. Live-Verbrauch: docker stats.

🔁Restart-Policies

Wähle eine Policy und löse Ereignisse aus. Der Unterschied zwischen always und unless-stopped zeigt sich nach „docker stop“ + Daemon-Neustart.
running
Neustarts: 0

    Die Policy greift erst, nachdem der Container einmal erfolgreich lief (mindestens 10 Sekunden). Ein unhealthy-Status löst bei reinem Docker keinen Neustart aus – das tun erst Orchestrierer wie Swarm oder Kubernetes.

    🩺Healthchecks

    Docker führt den Prüfbefehl im Container regelmäßig aus. Aus Erfolg und Fehlschlag ergibt sich der Status – den Compose für depends_on: service_healthy nutzt.

    Prüfungen anklicken: ✓ Erfolg → ✗ Fehlschlag → ⏱ zu langsam (länger als timeout).

    t=10sstarting
    t=20sstarting
    t=30shealthy
    t=40shealthy
    t=50shealthy
    t=60shealthy
    t=70sunhealthy
    t=80sunhealthy
    t=90shealthy
    t=100shealthy
    1. t=10s Fehlschlag in der Startphase – zählt nicht.
    2. t=20s Fehlschlag in der Startphase – zählt nicht.
    3. t=30s Prüfung erfolgreich (Exit 0).
    4. t=40s Prüfung erfolgreich (Exit 0).
    5. t=50s Fehlschlag 1/3.
    6. t=60s Zeitüberschreitung (7 s > 5 s) – Fehlschlag 2/3.
    7. t=70s Fehlschlag 3/3.
    8. t=80s Fehlschlag 4/3.
    9. t=90s Prüfung erfolgreich (Exit 0).
    10. t=100s Prüfung erfolgreich (Exit 0).
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:3000/api/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 30s