Durchführung von Zero-Downtime Rolling Updates in Kubernetes Deployments
Einleitung
In modernen Microservice-Architekturen ist die Aufrechterhaltung der kontinuierlichen Verfügbarkeit während Anwendungsaktualisierungen eine nicht verhandelbare Anforderung. Kubernetes Deployments vereinfachen diesen Prozess durch die Bereitstellung automatisierter Rolling Updates, einer Strategie, die darauf ausgelegt ist, alte Versionen von Pods inkrementell durch neue zu ersetzen.
Um eine echte Zero-Downtime zu erreichen, ist jedoch mehr als nur die Standard-Kubernetes-Konfiguration erforderlich. Es bedarf einer sorgfältigen Koordination zwischen dem Deployment-Manifest, den Health-Endpunkten der Anwendung und dem Prozess der sanften Beendigung. Diese Anleitung bietet einen umfassenden Schritt-für-Schritt-Ansatz zur Konfiguration von Kubernetes Deployments, um sicherzustellen, dass Anwendungsaktualisierungen nahtlos und für den Endbenutzer unsichtbar sind.
Wir werden die entscheidende Rolle von Readiness Probes, die Feinabstimmung der Deployment-Strategieparameter (maxSurge und maxUnavailable) sowie Best Practices für die Beendigung der Anwendung behandeln, um Serviceunterbrechungen während der Deployment-Übergänge zu eliminieren.
Voraussetzungen für Zero-Downtime
Bevor das Kubernetes-Manifest konfiguriert wird, muss die zugrunde liegende Anwendung bestimmte Prinzipien befolgen, um Zero-Downtime-Deployments zu unterstützen:
- Rückwärtskompatibilität der Anwendung: Für die kurze Zeit, in der sowohl die alte als auch die neue Version der Anwendung gleichzeitig laufen, müssen sie mit gemeinsam genutzten Ressourcen (Datenbanken, Warteschlangen, Caches) kompatibel sein.
- Idempotenz: Vorgänge, die von beiden Versionen bearbeitet werden könnten, müssen ohne negative Nebenwirkungen wiederholbar sein.
- Sanfte Beendigung (Graceful Termination): Die Anwendung muss so programmiert sein, dass sie das von Kubernetes gesendete
SIGTERM-Signal erkennt und neue Verbindungen sanft stoppt, während ausstehende Anfragen abgeschlossen werden, bevor sie beendet wird.
Verständnis der Kubernetes Rolling Update Strategie
Kubernetes Deployments verwenden standardmäßig die Strategie RollingUpdate. Diese Methode stellt sicher, dass die alte Anwendungsversion nicht vollständig heruntergefahren wird, bevor die neue Version betriebsbereit ist. Die Übergangsverwaltung erfolgt über zwei Hauptparameter:
| Parameter | Beschreibung | Auswirkung auf Zero-Downtime |
|---|---|---|
maxSurge |
Definiert die maximale Anzahl von Pods, die über die gewünschte Anzahl von Replikas hinaus erstellt werden können. Kann eine absolute Zahl oder ein Prozentsatz sein (Standard: 25%). | Steuert die Geschwindigkeit des Rollouts und stellt sicher, dass die Kapazität vorübergehend erhöht wird. |
maxUnavailable |
Definiert die maximale Anzahl von Pods, die während der Aktualisierung nicht verfügbar sein dürfen. Kann eine absolute Zahl oder ein Prozentsatz sein (Standard: 25%). | Entscheidend für Zero-Downtime. Wenn dieser Wert auf 0% gesetzt wird, werden keine bedienenden Pods beendet, bis die neuen Pods vollständig Ready sind. |
Empfohlene Strategie für Zero Downtime
Für die höchste Verfügbarkeit ist die beste Konfiguration oft die Sicherstellung, dass kein Kapazitätsverlust während der Null-Ausfallzeit auftritt:
maxUnavailable: 0(Sicherstellen, dass die Kapazität niemals unter den Sollwert sinkt).maxSurge: 1oder25%(Erlaubt der Kapazität, das Ziel kurzzeitig zu überschreiten, wodurch sichergestellt wird, dass ein neuer Pod bereit ist, bevor ein alter beendet wird).
Schritt 1: Implementierung von Readiness Probes
Der Readiness Probe ist der wichtigste Mechanismus zur Gewährleistung von Zero-Downtime-Updates. Kubernetes verlässt sich auf diesen Probe, um festzustellen, ob ein neuer Pod bereit ist, Benutzerverkehr zu empfangen, und ob ein alter Pod noch aktiv Verkehr bedient.
Liveness vs. Readiness
- Liveness Probe: Informiert Kubernetes darüber, ob der Container gesund und funktionsfähig ist. Wenn er fehlschlägt, wird der Container neu gestartet.
- Readiness Probe: Informiert Kubernetes darüber, ob der Container bereit ist, Anfragen zu bedienen. Wenn er fehlschlägt, wird der Pod aus den zugehörigen Service-Endpunkten entfernt, wodurch der Verkehr von ihm weggeleitet wird, bis er bereit wird.
Für Rolling Updates wird der Readiness Probe verwendet, um den Übergang zu steuern. Kubernetes fährt erst mit der Beendigung eines alten Pods fort, wenn ein neu erstellter Pod seine Bereitschaftsprüfung erfolgreich bestanden hat.
# Auszug aus deployment.yaml
spec:
containers:
- name: my-app
image: myregistry/my-app:v2.0
ports:
- containerPort: 8080
# --- Konfiguration des Readiness Probe ---
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 15 # Wartezeit vor dem ersten Prüfversuch
periodSeconds: 5 # Wie oft die Prüfung durchgeführt wird
timeoutSeconds: 3
failureThreshold: 3 # Anzahl aufeinanderfolgender Fehler, um den Pod als nicht bereit zu kennzeichnen
# --- Konfiguration des Liveness Probe (Standard-Health-Check) ---
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
Tipp: Stellen Sie sicher, dass der Endpunkt
/health/readyIhrer Anwendung nur dann einen Erfolgscode (HTTP 200-299) zurückgibt, wenn die Initialisierung, Datenbankverbindungen und andere externen Abhängigkeiten vollständig betriebsbereit sind.
Schritt 2: Konfigurieren der Deployment-Strategie
Um echte Zero-Downtime zu erzwingen, konfigurieren wir die Rolling-Update-Strategie explizit so, dass ein Abfall der Anzahl verfügbarer Replikas verhindert wird.
Bei dieser Konfiguration erstellt Kubernetes zuerst einen neuen Pod (maxSurge: 1). Erst wenn der neue Pod seinen Readiness Probe bestanden hat, beendet Kubernetes einen alten Pod. Da maxUnavailable 0 ist, sinkt die Servicekapazität niemals unter die Ziel-Replikaanzahl.
# Auszug aus deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-web-deployment
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
# Stellt sicher, dass die Kapazität niemals unter die gewünschte Replikaanzahl (4) fällt
maxUnavailable: 0
# Erlaubt die Erstellung eines zusätzlichen Pods während des Rollouts
maxSurge: 1
template:
# ... Spezifikation des Containers ...
Schritt 3: Sicherstellung der sanften Beendigung
Selbst bei robusten Readiness Probes kann es zu abgebrochenen Anfragen kommen, wenn die Anwendung beim Empfang des Abbruchsignals sofort beendet wird.
Kubernetes folgt einer bestimmten Beendigungssequenz:
- Der Pod wird als Terminating markiert.
- Der Pod wird aus den Service-Endpunkten entfernt (der Datenverkehr wird nicht mehr an ihn weitergeleitet).
- Der Pre-Stop-Hook (falls definiert) wird ausgeführt.
- Der Container empfängt das
SIGTERM-Signal. - Kubernetes wartet die durch
terminationGracePeriodSecondsdefinierte Dauer ab (Standard: 30 Sekunden). - Wenn der Container noch läuft, erhält er ein nicht verhandelbares
SIGKILL.
Um eine sanfte Beendigung zu gewährleisten, muss die Anwendung SIGTERM verarbeiten, und terminationGracePeriodSeconds muss lang genug sein, damit die Anwendung ausstehende Anfragen beenden kann.
# Auszug aus deployment.yaml, innerhalb der Container-Spezifikation
terminationGracePeriodSeconds: 45 # Erhöhte Zeit für die sanfte Beendigung
containers:
- name: my-app
image: myregistry/my-app:v2.0
lifecycle:
preStop:
exec:
# Beispiel: Ausführen eines Skripts zum sofortigen Entladen von Verbindungen
command: ["/bin/sh", "-c", "sleep 10"]
Best Practice: Die Zeit zwischen dem Fehlschlagen des Readiness Probe (Schritt 2) und dem Empfang von
SIGTERM(Schritt 4) ist kritisch. Wenn Ihre AnwendungSIGTERMkorrekt verarbeitet, verhindert die Festlegung einer etwas längerenterminationGracePeriodSeconds(z. B. 45 oder 60 Sekunden) ein hartes Abschalten.
Schritt 4: Durchführung und Überwachung des Updates
Sobald Ihr Deployment-Manifest die optimierte Strategie und robuste Probes enthält, ist die Durchführung des Updates unkompliziert.
-
Aktualisieren Sie das Image-Tag: Ändern Sie Ihr Deployment-Manifest, um die neue Image-Version widerzuspiegeln (z. B.
v2.0aufv2.1). -
Konfiguration anwenden:
bash kubectl apply -f deployment.yamlAlternativ können Sie das Image direkt patchen:
bash kubectl set image deployment/my-web-deployment my-app=myregistry/my-app:v2.1 -
Rollout-Status überwachen: Beobachten Sie, wie Kubernetes die Phasen durchläuft, und überprüfen Sie, dass die Anzahl der bereitgestellten Pods niemals unter den gewünschten Wert sinkt.
bash kubectl rollout status deployment/my-web-deployment -
Pod-Verfügbarkeit überprüfen: Beobachten Sie den Pod-Status, um zu bestätigen, dass die alten Pods (v2.0) erst dann sanft beendet werden, wenn die neuen Pods (v2.1) vollständig bereit sind.
bash kubectl get pods -l app=my-web-deployment -w
Fortgeschrittene Überlegungen
Verwendung von Pod Disruption Budgets (PDBs)
Während eine Deployment-Strategie freiwillige Aktualisierungen verwaltet, stellt ein Pod Disruption Budget (PDB) sicher, dass selbst bei unvorhergesehenen Störungen (z. B. Knotenwartung, Cluster-Upgrades) eine Mindestanzahl von Pods verfügbar ist. Obwohl PDBs die Geschwindigkeit des Rolling Updates nicht direkt steuern, dienen sie als Sicherheitsnetz.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
minAvailable: 75% # Stellt sicher, dass immer mindestens 75% der Replikas verfügbar sind
selector:
matchLabels:
app: my-web-deployment
Die Bedeutung der anfänglichen Verzögerung (Initial Delay)
Wenn Ihre Anwendung Zeit zum Aufwärmen benötigt (z. B. Laden großer Konfigurationsdateien oder Aufbau von Caches), stellen Sie sicher, dass initialDelaySeconds in Ihrem Readiness Probe ausreichend lang ist. Wenn die Prüfung zu früh fehlschlägt, wird der Pod als fehlerhaft markiert und gerät möglicherweise in eine Crash-Loop, wodurch das gesamte Deployment angehalten wird.
Fazit
Das Erreichen von Zero-Downtime Rolling Updates in Kubernetes ist eine Kombination aus robuster Plattformkonfiguration und disziplinierter Anwendungsentwicklung. Durch die korrekte Nutzung von Readiness Probes zur Signalisierung des Betriebsstatus, die Feinabstimmung der Deployment-Strategie (maxUnavailable: 0) zur Aufrechterhaltung der Kapazität und die Implementierung von Handlern für die sanfte Beendigung stellen Sie sicher, dass Anwendungsaktualisierungen zuverlässig und ohne Unterbrechung des Dienstes für Ihre Benutzer durchgeführt werden. Testen Sie Ihren Aktualisierungsprozess immer gründlich in einer Staging-Umgebung, um die Beendigungsfrist und die Prüflogik zu validieren.