Begriff
Container Lifecycle
Warum wichtig?
Dieser Begriff ist ein Knoten im SengakujiWorks-Wissensnetz. Nutze Level 0 für die erste Einordnung, Level 1 für Praxis, Level 2 für technische Struktur und Level 3 für Grenzen, Fallstricke und Expertenkontext.
Ein Container ist wie ein Lebewesen. Er wird geboren, arbeitet, schläft vielleicht, und stirbt. Den Programmierer interessiert vor allem der Tod:
- Stirbt er unerwartet? (Absturz -> Neustart nötig).
- Stirbt er geplant? (Update -> Graceful Shutdown).
Der Lifecycle beschreibt diese Phasen:
Created->Running->Paused->Exited(Stopped) ->Dead(Deleted). Zu verstehen, warum ein Container in welchem Zustand ist, ist die Basis für Debugging.
Merksatz: Die Abfolge von Zuständen, die ein Container von der Erstellung (Create) über die Ausführung (Run) bis zur Beendigung (Stop/Kill) und Entfernung (Rm) durchläuft.
Befehle für die Phasen:
docker create: Baut den Container, startet ihn aber nicht (Zustand: Created). Selten genutzt.docker start: Weckt ihn auf (Zustand: Running).docker run: Machtcreate+startin einem (Standard).docker stop: Sendet Signal "Bitte fertig werden". Nach 10s -> "Runterfahren" (Zustand: Exited).docker kill: Zieht den Stecker sofort (Zustand: Exited mit Fehlercode).docker rm: Löscht die Hülle (Garbage Collection).
Praxisroutine
In der Praxis lernst du Container Lifecycle, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
1. Signals (SIGTERM vs. SIGKILL)
Das wichtigste Konzept für Ops.
Wenn du stop drückst, sendet Docker SIGTERM (Signal 15) an PID 1.
Die App sollte das fangen (trap), offene Verbindungen schließen, Daten speichern und sich beenden exit(0).
Tut sie das nicht innerhalb der Grace Period (Default 10s), sendet Docker SIGKILL (Signal 9).
Das ist der "Hard Kill". Datenverlust möglich!
Häufiger Fehler: Nginx/Java ignoriert SIGTERM, weil es in einem Shell-Skript (entrypoint.sh) gewrappt ist und das Skript das Signal nicht weiterleitet ("PID 1 Problem").
2. Restart Policies
Was passiert nach dem Tod?
no: Bleib tot. (Standard).on-failure: Nur neu starten, wenn Exit Code != 0 (Crash).always: Immer neu starten (auch wenn ich manuellstopgedrückt habe! Docker Daemon Restart weckt ihn wieder).unless-stopped: Wie always, aber merkt sich, wenn ich manuell gestoppt habe. (Beste Wahl für Server).
3. Init Process (Tini)
Linux-Prozesse erwarten einen "Reaper" (Init System), der Zombie-Prozesse aufräumt.
Ein normaler Container hat kein systemd.
Wenn Prozesse sterben, bleiben sie als "Zombies" (<defunct>) in der Tabelle, bis PID 1 sie "erntet" (waitpid).
Wenn deine App das nicht tut, läuft die Prozess-Tabelle voll -> Server Crash.
Lösung: --init Flag in Docker (nutzt tini) oder Supervisord.
1. PID 1 und das Zombie-Reaping Problem
In Linux-Systemen startet das Betriebssystem beim Boot einen Init-Prozess (oft systemd), der die magische PID 1 erhält. Er hat die harte Pflicht, verwaiste Kindprozesse (Zombies), die beendet sind, "einzusammeln" (Reaping), damit die Process Table im Kernel nicht vollläuft.
Ein Container hat kein systemd. Startet er per ENTRYPOINT ["npm", "start"], wird Node.js zur PID 1. Node hat oft keine Ahnung von Zombie-Reaping oder Signal-Handling für Sub-Prozesse.
Das führt zu Memory Leaks in Form von Process Descriptors. Abhilfe schafft die Option --init im Docker-Befehl (oder init: true in Docker Compose). Das spannt den winzigen C-Daemon tini als PID 1 vor deine App, der das Reaping perfekt übernimmt.
2. OOM-Killer (Exit Code 137)
Eines der gefürchtetsten Lifecycle-Events ist der gewaltsame Tod durch Erschöpfung des Speichers.
Überschreitet ein Container das ihm durch Cgroups diktierte RAM-Limit, wird der Linux Out Of Memory Killer (OOM-Killer) aktiv.
Er scannt die Prozesse, sucht den Container aus und schickt einen asynchronen SIGKILL (Signal 9). Die App hat keine Chance zur Gegenwehr, sie stirbt in Millisekunden. Der Container terminiert mit Exit Code 137 ($128 + 9$). Um solche Abstürze zu debuggen, hilft nur noch ein Memory Profiling der App (z.B. Heap Dumps in Java/Go) und die Lektüre der /var/log/syslog des Host-Systems.
3. Graceful Shutdown & Kubernetes PreStop Hooks
Wenn Kubernetes beschließt, einen Pod (Kubernetes) (Container) herunterzufahren, weil man eine neue Version veröffentlicht (Rolling Update), sendet es SIGTERM (Signal 15).
Das Backend (z.B. Go Server oder Spring Boot) muss den Graceful Shutdown implementieren:
- Sofort aufhören, neue HTTP-Anfragen vom Load Balancer anzunehmen.
- Den aktuellen (in-flight) Anfragen Zeit geben, ihre Datenbank-Transaktionen abzuschließen.
- Danach aktiv und sauber via
exit(0)sterben. In Kubernetes gibt es dazu sogenannte PreStop Hooks — Lebenszyklus-Hooks (Bash-Befehle), die garantiert ausgeführt werden, exakt bevor das SIGTERM-Signal abgefeuert wird, um z.B. einen Container gezielt aus dem internen DNS/Service-Registry abzumelden.
Quick-Check
Was bedeutet Exit Code 137?
128 + 9 = 137. Das ist SIGKILL. Entweder hast dukillgedrückt, oder der OOM Killer (Out of Memory) hat den Prozess erschossen. Ein klassisches Indiz für Speicherprobleme.Was bedeutet Exit Code 0?
Erfolg. "Ich bin fertig und habe keine Fehler." Typisch für "One-Shot" Container (Batch Jobs), aber untypisch für Webserver (die sollten nie Exit 0 machen, außer beim Shutdown).Warum dauert
docker stopmanchmal genau 10 Sekunden?Weil deine App SIGTERM ignoriert. Docker wartet höflich 10s und tötet sie dann. Fixe dein Signal Handling im Code!