Jede Kubernetes-Migration, die ich begleitet habe, beginnt mit der gleichen Aussage im Kick-off: “Wir brauchen Zero Downtime.” Was danach folgt, ist meistens eine Reise durch Blue-Green-Deployments, Feature-Flags und mehr als eine Nachtschicht.
Hier sind die Muster, die tatsächlich funktionieren – nicht die, die in Blogposts gut klingen.
Das Problem mit der “Big Bang”-Migration
Der klassische Fehler ist der Versuch, alles auf einmal zu migrieren. Ein Datum wird gesetzt, alle Teams arbeiten darauf hin, und dann wird an einem Wochenende der Schalter umgelegt. Das endet fast immer in Chaos.
Was ich stattdessen empfehle: Strangler Fig Pattern.
Du baust die neue Kubernetes-Infrastruktur parallel auf, während die alte weiterläuft. Ein Reverse Proxy (nginx oder ein API Gateway) entscheidet, welcher Traffic wohin geht. Service für Service wird migriert, getestet, und erst dann dauerhaft umgeschaltet.
# nginx upstream config während der Migration
upstream backend {
# 90% auf alt, 10% auf neu
server old-monolith:8080 weight=9;
server new-k8s-service:8080 weight=1;
}
Blue-Green ist nicht immer die Antwort
Blue-Green-Deployments werden als Allheilmittel verkauft. Das Problem: du brauchst doppelte Infrastruktur, und bei zustandsbehafteten Services (Datenbanken, Sessions, Caches) wird es schnell komplex.
Für die meisten Migrationen ist Rolling Updates mit korrekten Health Checks die bessere Wahl:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0 # Kein Ausfall während dem Update
maxSurge: 1 # Maximal 1 Pod extra
template:
spec:
containers:
- name: app
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
Der entscheidende Punkt: maxUnavailable: 0 stellt sicher, dass Kubernetes erst einen neuen Pod hochfährt und dessen Readiness bestätigt, bevor der alte runtergefahren wird.
Das unterschätzte Problem: Datenbankmigrationen
Kubernetes-Deployments sind einfach. Datenbankmigrationen mit Zero Downtime sind schwer.
Die Regel, die ich konsequent anwende: Jede Migration muss sowohl mit der alten als auch der neuen Codeversion funktionieren. Das bedeutet:
- Additive Änderungen zuerst – neue Spalten hinzufügen, bevor alte entfernt werden
- Backwards-compatible Anfragen schreiben – solange beide Versionen laufen können
- Cleanup in einem separaten Deployment – erst alte Spalten/Tabellen entfernen, wenn der neue Code vollständig deployed und stabil ist
-- Migration Phase 1: Additive (safe, deploy)
ALTER TABLE users ADD COLUMN email_verified BOOLEAN DEFAULT false;
-- Migration Phase 2: Backfill (background job)
UPDATE users SET email_verified = true WHERE created_at < '2024-01-01';
-- Migration Phase 3: Cleanup (weeks later, after code stabilized)
-- ALTER TABLE users DROP COLUMN old_verified_field;
Fazit
Zero-Downtime-Migrationen sind kein Hexenwerk, aber sie erfordern Disziplin in der Planung. Die wichtigsten Punkte:
- Strangler Fig statt Big Bang
- Rolling Updates mit korrekten Health Checks für die meisten Services
- Blue-Green nur wenn wirklich nötig (und du die Kosten akzeptierst)
- Datenbankmigrationen immer in mehreren backwards-compatible Phasen
Wer das konsequent umsetzt, schläft deutlich besser am Deployment-Tag.