High Availability und Cluster-Design
HA-Architekturen für Production-Cluster.
Lernziele
Nach dieser Lektion kannst du eine hochverfügbare Control Plane entwerfen: mindestens drei Control-Plane-Nodes wegen des etcd-Quorums, ein Load Balancer vor den API Servern, Worker über Availability Zones verteilt. Du kennst den Unterschied zwischen Stacked- und External-etcd-Topologie, kannst durchspielen, was bei welchem Ausfall passiert, und kannst begründet entscheiden, wann Managed Kubernetes diese ganze Übung überflüssig macht.
Das Problem: Jede Komponente kann ausfallen — welche tut wirklich weh?
Aus den Lektionen 1–4 kennst du alle Komponenten. Jetzt die Betriebsfrage: Was passiert, wenn jeweils eine ausfällt? Die Antworten fallen sehr unterschiedlich aus, und genau diese Differenzierung wird in Interviews geprüft:
- Ein Worker Node fällt aus: verkraftbar. Der Node Controller merkt es, Pods werden nach der Eviction-Frist auf anderen Nodes neu erstellt (Lektion 3) — vorausgesetzt, es gibt freie Kapazität.
- Der API Server fällt aus (einzige Instanz): Laufende Pods laufen weiter, aber kein
kubectl, kein Scheduling, kein Self-Healing, kein CI-Deployment. Der Cluster ist eingefroren, nicht tot. - etcd verliert sein Quorum oder seine Daten: der Ernstfall. Ohne Quorum read-only; ohne Daten und Backup ist der Cluster faktisch verloren.
HA-Design heißt also: die Komponenten mit dem größten Schadenspotenzial redundant auslegen — und das sind API Server und etcd. „Keine Single Points of Failure” ist das Ziel; der Weg dorthin folgt aus dem, was du über die Komponenten schon weißt.
Die Control Plane redundant: drei Nodes und ein Load Balancer
Der Bauplan einer klassischen HA-Control-Plane:
Mindestens 3 Control-Plane-Nodes — ungerade Anzahl wegen etcd. Die Begründung kommt direkt aus Lektion 2: Raft braucht eine Mehrheit, drei Nodes tolerieren einen Ausfall, fünf tolerieren zwei, und vier bringen gegenüber drei nichts. Da etcd typischerweise mit auf den Control-Plane-Nodes läuft, diktiert seine Quorum-Arithmetik die Knotenzahl.
Ein Load Balancer vor den API Servern. Der API Server ist zustandslos (Lektion 2) — mehrere Instanzen können parallel aktiv sein (active-active), kein Leader nötig. Damit kubelets, Controller und kubectl aber eine stabile Adresse haben, steht davor ein Load Balancer mit Health Checks auf /healthz (bei kubeadm der controlPlaneEndpoint). Dieser Endpoint gehört von Anfang an in alle Zertifikate und kubeconfigs — ihn nachträglich einzuführen ist mühsam.
Scheduler und Controller Manager: aktiv nur einmal. Beide laufen ebenfalls auf jedem Control-Plane-Node, arbeiten aber anders als der API Server nicht parallel: Sie machen Leader Election über ein Lease-Objekt in der API. Eine Instanz führt, die anderen warten im Standby und übernehmen, wenn das Lease ausläuft. Würden zwei Scheduler parallel arbeiten, würden sie sich bei der Platzierung in die Quere kommen — deshalb active-passive statt active-active.
Bei der etcd-Platzierung gibt es zwei Topologien: Stacked (etcd auf den Control-Plane-Nodes, der kubeadm-Standard — einfacher, aber ein Node-Ausfall kostet API Server und etcd-Mitglied zugleich) und External (eigener etcd-Cluster auf separaten Maschinen — entkoppelt die Ausfalldomänen, kostet aber drei zusätzliche Maschinen und mehr Betrieb). Für die meisten Setups ist Stacked der pragmatische Default.
Ausfalldomänen: Zonen, Spreading, Kapazität
Drei Control-Plane-Nodes im selben Rack sind Redundanz auf dem Papier. Echte HA denkt in Ausfalldomänen: Was fällt gemeinsam aus? In der Cloud sind das Availability Zones — je ein Control-Plane-Node pro Zone bedeutet, dass selbst ein Zonen-Ausfall das Quorum (2 von 3) nicht bricht.
Für die Worker gilt dasselbe Prinzip auf Workload-Ebene:
- Nodes über AZs verteilen und Workloads mit Topology Spread Constraints oder Pod-Anti-Affinity über die Zonen streuen — drei Replicas in derselben Zone sind keine drei Replicas.
- Kapazitätsreserve einplanen: Fällt eine von drei Zonen aus, müssen die übrigen zwei die Last tragen können. HA ohne Headroom ist Failover ins Pending.
- PodDisruptionBudgets setzen, damit auch geplante Wartung (Node-Drains, Upgrades) nie zu viele Replicas gleichzeitig nimmt.
Der ehrliche Trade-off: Zonen-Spreading kostet — Cross-AZ-Traffic ist bei den meisten Cloud-Providern kostenpflichtig und minimal langsamer. Multi-Region ist noch einmal eine andere Liga: Ein einzelner etcd-Cluster über Regionen scheitert an der Latenz (Lektion 2 — Quorum-Writes mit fsync), daher heißt Multi-Region praktisch immer mehrere unabhängige Cluster plus Traffic-Steuerung davor.
Managed Kubernetes: HA als Produkt
EKS, GKE und AKS betreiben die komplette Control Plane redundant über mehrere Zonen — API-Server-Replikation, etcd-Quorum, Backups, Leader Election, Upgrades: alles hinter einem Endpoint abstrahiert, mit SLA. Die gesamte erste Hälfte dieser Lektion wird damit zum Providerproblem.
Was dir bleibt, wird gern unterschätzt: Worker-Verteilung über Zonen, Topology Spread, PDBs, Kapazitätsreserve, sauber konfigurierte Probes (Lektion 4) — die Verfügbarkeit deiner Workloads ist nicht Teil des Control-Plane-SLA. Im Interview ist genau diese Trennung die starke Antwort: „Managed nimmt mir die Control-Plane-HA ab, die Workload-HA bleibt mein Job.” Self-Managed lohnt sich nur noch bei On-Premises, Air-Gap oder Spezial-Compliance — dann aber mit allem hier Beschriebenen als Pflichtprogramm, inklusive getestetem etcd-Restore.
Praxis: HA-Control-Plane lokal nachbauen
kind kann mehrere Control-Plane-Nodes simulieren und stellt automatisch einen Load Balancer davor:
kind create cluster --name halab --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
EOF
# Drei Control-Plane-Nodes, ein LB davor (haproxy-Container "halab-external-load-balancer")
kubectl get nodes
docker ps --filter name=halab
# etcd-Cluster-Gesundheit: drei Mitglieder, ein Leader
kubectl exec -n kube-system etcd-halab-control-plane -- sh -c \
'ETCDCTL_API=3 etcdctl \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
endpoint status --cluster -w table'
# Leader Election des Schedulers ansehen
kubectl get lease -n kube-system kube-scheduler -o yaml | grep holderIdentity
# Der Härtetest: einen Control-Plane-Node stoppen
docker stop halab-control-plane2
sleep 30
kubectl get nodes # funktioniert weiter — Quorum 2/3 steht
kubectl create deployment survivor --image=nginx
kubectl rollout status deployment survivor
docker start halab-control-plane2
Der Cluster bleibt voll funktionsfähig, während ein Drittel der Control Plane fehlt — genau das ist der Sinn der Übung. Stoppe testweise einen zweiten Control-Plane-Node und beobachte, wie Schreiboperationen scheitern (Quorum verloren), bevor du aufräumst: kind delete cluster --name halab.
Typische Stolperfallen
Zwei Control-Plane-Nodes „für den Anfang”: Zwei etcd-Mitglieder haben ein Quorum von 2 — fällt einer aus, ist der Cluster read-only. Zwei Nodes sind also nicht halb so gut wie drei, sondern schlechter als einer. Immer 1, 3 oder 5.
HA gebaut, Restore nie getestet: Replikation schützt vor Node-Ausfall, nicht vor versehentlichem kubectl delete namespace prod oder etcd-Korruption — das repliziert sich mit. Ein etcd-Snapshot-Backup (Lektion 2) plus geübter Restore bleibt auch im HA-Cluster Pflicht.
Der Load Balancer als neuer Single Point of Failure: Wer drei API Server hinter eine einzelne haproxy-VM stellt, hat den SPOF nur verschoben. Der LB selbst braucht Redundanz (Cloud-LB, oder on-prem z. B. keepalived mit virtueller IP).
Workload-HA mit Cluster-HA verwechseln: Drei Control-Plane-Nodes helfen nichts, wenn die App mit einem Replica läuft oder alle Replicas in einer Zone liegen. Verfügbarkeit muss auf beiden Ebenen designt werden.
Interview-Vorbereitung
Auf „Wie designst du einen hochverfügbaren Kubernetes-Cluster?” antwortest du in Schichten: etcd (3 oder 5 Mitglieder, Quorum-Begründung, Backup trotzdem) → API Server (zustandslos, active-active hinter redundantem Load Balancer) → Scheduler/Controller Manager (Leader Election, active-passive) → Worker und Workloads (AZ-Spreading, Topology Spread, PDBs, Kapazitätsreserve) → Einordnung (Managed übernimmt die Control-Plane-Schicht, Workload-Schicht bleibt bei dir).
Typische Follow-ups:
- „Warum drei Control-Plane-Nodes und nicht zwei?” — etcd-Quorum: Bei zwei Mitgliedern macht jeder Ausfall den Cluster read-only; Redundanz beginnt bei drei.
- „Stacked oder external etcd?” — Stacked: einfacher, gekoppelte Ausfalldomänen. External: entkoppelt, aber drei Maschinen und ein Betriebsthema mehr. Default Stacked.
- „Warum laufen Scheduler nicht active-active wie der API Server?” — API Server ist zustandslos; Scheduler/Controller würden konkurrierend entscheiden, daher Leader Election per Lease.
- „Ersetzt HA das Backup?” — Nein: Löschungen und Korruption replizieren sich. HA gegen Ausfälle, Backup gegen Fehler.
Zusammenfassung
HA-Cluster-Design folgt aus der Architektur: etcd diktiert mit seinem Raft-Quorum die ungerade Control-Plane-Anzahl, der zustandslose API Server skaliert active-active hinter einem (selbst redundanten) Load Balancer, Scheduler und Controller Manager sichern sich per Leader Election ab. Echte Resilienz entsteht erst mit Ausfalldomänen-Denken — Zonen-Spreading, Kapazitätsreserve, PodDisruptionBudgets — und einem getesteten etcd-Restore. Managed Kubernetes kauft dir die Control-Plane-Hälfte dieser Liste ab; die Workload-Hälfte bleibt deine.
Damit ist der Architektur-Block abgeschlossen. Ab der nächsten Lektion wechseln wir die Perspektive von der Plattform zu den Workloads — beginnend mit der kleinsten deploybaren Einheit: dem Pod, seiner Anatomie und seinem Lifecycle.