Begriff
Pod (Kubernetes)
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.
In Docker ist der Container die kleinste Einheit.
In Kubernetes nicht. Da ist der Pod die kleinste Einheit.
Ein Pod ist eine Hülle um einen oder mehrere Container.
Warum?
Manchmal gehören zwei Container untrennbar zusammen (wie Erbse und Möhre).
Beispiel: Ein Webserver (Nginx) und ein Log-Shipper (Fluentd), der die Logs des Webservers hochlädt.
Sie müssen auf demselben Server landen. Sie müssen sich die IP teilen (localhost).
Der Pod garantiert das.
Du startest nie einen Container direkt. Du startest einen Pod (der einen Container enthält).
Merksatz: Die kleinste deploybare Recheneinheit in Kubernetes, bestehend aus einem oder mehreren Containern, die sich Speicher, Netzwerk und Spezifikationen teilen.
YAML "Manifest":
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-app
image: nginx
kubectl apply -f pod.yaml.
kubectl get pods.
Wichtig: Ein Pod ist vergänglich. Wenn er stirbt, ist er weg.
In Produktion nutzt du deshalb nie kind: Pod, sondern kind: Deployment (das Pods automatisch neu startet).
Praxisroutine
In der Praxis lernst du Pod (Kubernetes), 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. Shared Namespaces
Alle Container im Pod teilen sich:
- Network Namespace: Gleiche IP, gleicher Port-Bereich. Container A erreicht Container B über
localhost:8080. - IPC Namespace: Können über Shared Memory kommunizieren.
- UTS Namespace: Gleicher Hostname. Sie teilen sich nicht:
- PID Namespace: Jeder hat eigene Prozess-IDs (PID 1). (Außer
shareProcessNamespace: trueist gesetzt). - Filesystem: Jeder hat sein eigenes Image. Daten teilen geht nur über Volumes (
emptyDir).
2. Der "Pause" Container
Wenn du docker ps auf dem Node machst, siehst du für jeden Pod einen versteckten Container: k8s_POD_... pause.
Das ist der Pause Container.
Er tut nichts (schläft).
Sein einziger Job ist es, den Network Namespace offen zu halten.
Die "echten" Container (Nginx, Logsidecar) klinken sich in seinen Namespace ein.
Wenn Nginx crasht und neu startet, bleibt die IP gleich, weil der Pause Container (der Anker) weiterlebt.
3. Lifecycle (Phases vs Conditions)
Ein Pod hat einen Status (Phase): Pending -> Running -> Succeeded/Failed.
Aber das reicht nicht.
Ist er bereit (Ready)? Lebt er noch (Liveness)?
K8s nutzt Conditions: PodScheduled, Initialized, Ready.
Ein Pod ist Running, aber Ready: False, wenn der Readiness Probe fehlschlägt.
Services schicken nur Traffic an Ready: True.
Admins müssen lernen, kubectl describe pod zu lesen und Conditions zu verstehen.
1. Init-Container (Die Vorarbeiter)
Neben dem Haupt-Container (z.B. die Spring-Boot-App) und Sidecars (Logs) hat ein Pod das Features der Init-Container. Init-Container starten strikt vor den App-Containern und müssen erfolgreich terminieren (Exit 0). Sie blockieren den Startup-Prozess des gesamten Pods. Nutzen: Stell dir vor, deine Webapp braucht dringend Datenbank-Strukturen. Der Init-Container bootet asynchron, pingt die Postgres-Datenbank alle 5 Sekunden bis sie aktiv antwortet, spielt die DDL-Migrationen (Flyway) ein, und beendet sich. Erst dann öffnet K8s dem echten App-Container den Lifecycle-Gate. Dies entkoppelt fehleranfälligen Set-up Code tiefgreifend vom eigentlichen Microservice. Wenn Init 1 fehlschlägt, fängt K8s mit Backoff-Timer von vorne an.
2. Pod Sandbox (CRI & Linux Kernel Isolation)
Was stoppt Container A physisch davon, den RAM von Container B zu fressen?
Die Kubelet-API kommuniziert über das CRI (Container Runtime Interface) mit containerd oder CRI-O. Die Runtime wendet knallharte Linux Control Groups (cgroups v2) bei Erzeugung der Pod-Sandbox an. Der Node-Kernel kapselt den Pod ein – eine Limit-Rule (memory=500Mi) ist somit kein App-Tipp, sondern ein Kernel-Gesetz.
Überschreitet Nginx die Grenze deines Java-Mem Leaks auch nur um 1 Byte, feuert der Linux OOM-Killer radikal SIGKILL tief im Kernel space, was den Container exekutiert und die API benachrichtigt. kubectl get pods zeigt "OOMKilled". Die cgroups garantieren Multi-Tenancy-Ressourcen fairness auf Cluster-Hardware.
3. QOS Classes (Quality of Service Classes)
Ein Worker Node (64GB RAM) betreibt 20 Pods. Nun knallt der Traffic hart ins Setup, alle Pods fordern mehr Speicher im Limit-Burst an, der Server droht mit einem Kernel-Panic wegzubrechen. Wen killt Kubelet zuerst? Kubernetes nutzt QoS-Klassen, basierend auf den YAML Requests/Limits:
Guaranteed: (Request = Limit). Aristokratie. Diese Pods werden als allerletztes vom OOM-Killer liquidiert. Perfekt für Prod-Datenbanken.Burstable: (Request < Limit). Mittelklasse.BestEffort: (Kein Request/Limit gesetzt). Bauernopfer. Der Node tötet diese Pods absolut mitleidlos bei der kleinsten Ressourcen-Enge gnadenlos ab.
Quick-Check
Warum Mehrere Container?
Sidecar Pattern. Ein Hauptcontainer (App) und Helfer (Proxy, Logger, Backup-Agent). Sie sind eine "logische Einheit". Skalieren immer zusammen (1 App = 1 Sidecar).Kann ein Pod auf 2 Nodes laufen?
Niemals. Ein Pod ist atomar. Er landet ganz oder gar nicht auf einem Node. Wenn du Skalierung brauchst, startest du mehrere Pods (Replicas).Static Pods?
Spezialfall. Pods, die nicht vom API-Server, sondern direkt vom Kubelet auf dem Node (aus/etc/kubernetes/manifests) gestartet werden. Das wird genutzt, um den Cluster selbst (etcd, api-server) zu starten ("Bootstrapping").