Zwei Welten auf derselben Maschine
Jede Node eines Clusters ist zunächst ein ganz normaler Linux-Server. Darauf läuft Kubernetes. Beide Welten starten Dinge – nur mit unterschiedlichen Mitteln.
Welt 1 · Linux und systemd
Beim Booten startet der Kernel genau einen Prozess: systemd mit der PID 1. Alles andere auf der Maschine ist ein Kind davon.
systemd startet Dienste, startet sie neu wenn sie abstürzen, und sammelt ihre Logs. Das ist gewöhnliche Server-Administration – älter als Kubernetes und unabhängig davon.
systemctl status <dienst>
journalctl -u <dienst> -f
Welt 2 · Kubernetes und Pods
Kubernetes verwaltet Pods – über viele Maschinen hinweg. Es entscheidet, wo etwas läuft, und sorgt dafür, dass der gewünschte Zustand erhalten bleibt.
Man beschreibt, was laufen soll; Kubernetes kümmert sich um das Wie und Wo.
kubectl get pods -A
kubectl logs <pod> -n <namespace>
Wo die zwei Welten sich berühren
An genau einer Stelle: dem kubelet. Es ist ein systemd-Dienst und gleichzeitig der Agent von Kubernetes auf der Node. Es übersetzt zwischen beiden Welten.
Kernel
└─ systemd (PID 1) ← Linux-Welt
├─ sshd
├─ chronyd
└─ kubelet ← der Übergang
└─ containerd / CRI-O
└─ Container-Prozesse ← Kubernetes-Welt
Was ist ein Pod eigentlich?
Der Begriff, der am Anfang am häufigsten falsch verstanden wird. Ein Pod ist kein Container – er ist eine gemeinsame Hülle für einen oder mehrere Container.
Ein Container ist nur ein Prozess
Der Linux-Kernel kennt keine Container. Er kennt Prozesse. Ein Container ist ein normaler Prozess, dem der Kernel zwei Dinge gegeben hat:
- Namespaces – die Scheuklappen. Der Prozess sieht nur seine eigene Prozessliste, sein eigenes Netzwerk, sein eigenes Dateisystem.
- cgroups – die Fesseln. Wie viel CPU und Arbeitsspeicher er verbrauchen darf.
Mehr ist es nicht. Kein eigenes Betriebssystem, keine virtuelle Maschine. Ein ps aux auf der Node zeigt Container-Prozesse direkt an, gleichberechtigt neben sshd.
Der Pod ist die gemeinsame Hülle
Kubernetes startet für jeden Pod zuerst einen winzigen Hilfscontainer, der nichts tut außer zu schlafen. Sein einziger Zweck ist, die Namespaces zu halten. Alle echten Container des Pods hängen sich dann in dessen Netzwerk-Namespace ein.
Daraus folgt alles, was über Pods zu wissen ist:
- Alle Container eines Pods teilen sich eine IP-Adresse
- Sie erreichen sich gegenseitig über
localhost - Zwei Container im selben Pod können nicht denselben Port belegen
- Sie können sich Volumes teilen
- Sie landen immer gemeinsam auf derselben Node
Zwei Rollen für Nodes
Ein Cluster besteht aus Maschinen in zwei Rollen. Beide sind Linux-Server, beide haben ein kubelet – der Unterschied liegt darin, was zusätzlich darauf läuft.
Der Aufbau eines Clusters
Was auffällt
- Die unteren drei Schichten sind identisch. Linux, kubelet und Container-Runtime gibt es auf jeder Node, egal welche Rolle sie hat.
- Nur die oberste Schicht unterscheidet sich. Control Plane trägt die Steuerung, Worker tragen die Anwendungen.
- kube-proxy und der Netzwerk-Agent laufen überall. Auch Control-Plane-Nodes brauchen Netzwerk.
Control Plane: das Gehirn
Vier Komponenten. Sie entscheiden, was im Cluster passieren soll – führen selbst aber keine Anwendungen aus.
Die vier Komponenten
- etcd Static PodDie Datenbank. Der einzige Ort, an dem der Cluster-Zustand wirklich steht. Alles andere lässt sich wiederherstellen, etcd nicht – deshalb ist es das, was gesichert werden muss.
- kube-apiserver Static PodDie einzige Tür zu etcd. Prüft Anmeldung, Berechtigung und Gültigkeit jeder Anfrage. Jede andere Komponente redet mit ihm – keine redet direkt mit etcd.
- kube-controller-manager Static PodDer Soll-Ist-Abgleicher. Gewünscht sind 3 Replicas, es laufen 2 – also erzeugt er eine nach. Das in Dauerschleife, für dutzende Objekttypen.
- kube-scheduler Static PodDer Platzanweiser. Sieht Pods, denen noch keine Node zugewiesen ist, und entscheidet anhand von Ressourcen und Regeln, wohin sie sollen. Danach ist er fertig – gestartet wird der Pod vom kubelet.
Worker: die Hände
Hier laufen die Anwendungen. Drei Komponenten sorgen dafür, dass das funktioniert – zwei davon startet Linux, eine Kubernetes.
Die drei Komponenten
- kubelet systemdDer Agent auf der Node. Fragt beim apiserver nach, welche Pods hier laufen sollen, weist die Runtime an sie zu starten, meldet den Zustand zurück und startet neu, was ausfällt.
- containerd oder CRI-O systemdDie Container-Runtime. Lädt Images herunter und startet daraus die tatsächlichen Prozesse. Das kubelet redet mit ihr über eine standardisierte Schnittstelle – deshalb sind beide austauschbar.
- kube-proxy DaemonSetSorgt dafür, dass Service-Adressen funktionieren: Anfragen an eine Service-IP landen bei einem passenden Pod. Läuft als Pod, weil es erst gebraucht wird, wenn der apiserver bereits da ist.
Warum das kubelet kein Pod sein kann
Das kubelet ist die Komponente, die Container auf einer Node startet. Liefe es selbst als Container, müsste es sich selbst starten. Deshalb ist es ein gewöhnlicher Systemdienst mit einer Unit-Datei, wie sshd auch.
Gesamtübersicht
Alle Komponenten auf einen Blick – mit den zwei Fragen, um die es geht.
| Komponente | Wo | Was es ist | Aufgabe |
|---|---|---|---|
| etcd | Control Plane | Static Pod | speichert den gesamten Cluster-Zustand |
| kube-apiserver | Control Plane | Static Pod | einzige Tür zu etcd, prüft jede Anfrage |
| kube-controller-manager | Control Plane | Static Pod | gleicht Soll- und Ist-Zustand ab |
| kube-scheduler | Control Plane | Static Pod | weist neuen Pods eine Node zu |
| kubelet | jede Node | systemd | startet und überwacht Pods auf seiner Node |
| containerd / CRI-O | jede Node | systemd | startet die eigentlichen Container-Prozesse |
| kube-proxy | jede Node | DaemonSet | leitet Service-Adressen an Pods weiter |
| CNI-Agent | jede Node | DaemonSet | richtet das Pod-Netzwerk ein |
| deine Anwendungen | Worker | Pod | der eigentliche Zweck des Clusters |
Die Regel dahinter
systemd
Alles, was da sein muss, bevor Kubernetes funktioniert. kubelet und Runtime können nicht darauf warten, von Kubernetes gestartet zu werden – sie sind die Voraussetzung dafür.
Pod
Alles, was danach kommt. Static Pods sind der Sonderfall dazwischen: schon Pods, aber ohne apiserver gestartet – deshalb liegen ihre Manifeste als Datei auf der Node.
kubectl taucht in keiner Zeile auf. Es ist ein reines Client-Programm auf dem eigenen Rechner und läuft nirgends im Cluster.Selbst nachsehen
Die schnellste Art, das Gelesene zu verankern: es im eigenen Cluster bestätigen. Alle Befehle sind lesend und ungefährlich.
Welche Nodes gibt es und welche Rolle haben sie?
kubectl get nodes -o wide
Die Spalte ROLES zeigt control-plane bei Steuerungs-Nodes. Bei kleinen Clustern kann eine Node beide Rollen tragen.
Die Control-Plane-Komponenten als Pods sehen
kubectl -n kube-system get pods -o wide
Dort tauchen etcd-…, kube-apiserver-…, kube-controller-manager-… und kube-scheduler-… auf – jeweils mit dem Node-Namen als Anhängsel. Das ist das Kennzeichen von Static Pods.
Die systemd-Seite auf einer Node prüfen
Dafür braucht es eine Shell auf der Node selbst:
systemctl status kubelet
systemctl status containerd
# Logs mitlesen
journalctl -u kubelet -f
Bei RKE2 heißen die Dienste rke2-server beziehungsweise rke2-agent – dort läuft das kubelet als deren Kindprozess.
Die Manifeste der Static Pods ansehen
ls -l /etc/kubernetes/manifests/
Bei RKE2 liegt das Verzeichnis unter /var/lib/rancher/rke2/agent/pod-manifests.
Die DaemonSets sehen, die überall laufen
kubectl -n kube-system get daemonsets
Die Spalte DESIRED entspricht der Anzahl der Nodes – das ist die Definition eines DaemonSets.
Was hängenbleiben sollte
- Ein Container ist ein Prozess mit Scheuklappen und Fesseln, kein kleines Betriebssystem.
- Ein Pod ist die Hülle um einen oder mehrere Container: eine IP, ein Netzwerk, gemeinsame Volumes.
- Control Plane entscheidet, Worker führen aus – und jede Node ist darunter ein normaler Linux-Server.
- systemd startet, was vor Kubernetes da sein muss: kubelet und Container-Runtime.
- Alles andere ist ein Pod – die Control Plane als Static Pod von der Platte, der Rest über den apiserver.