- Authors

- Name
- Phillip Pham
- @ddppham
Pod Disruption Budgets: Kubernetes-Wartung ohne Downtime
TL;DR
- Ein PDB definiert, wie viele Pods einer Anwendung bei freiwilligen Unterbrechungen (Node Drain, Cluster-Upgrade) mindestens laufen muessen.
- Verwenden Sie
minAvailablewenn Sie eine feste Mindestanzahl brauchen,maxUnavailablewenn Sie die gleichzeitige Ausfallrate begrenzen wollen. - PDBs schuetzen nur vor freiwilligen Disruptions -- nicht vor Hardwareausfaellen oder OOMKills.
- Fuer StatefulSets ist
maxUnavailable: 1fast immer die richtige Wahl. - Ohne PDBs kann ein
kubectl drainalle Pods Ihrer Anwendung gleichzeitig beenden.
Das Problem: Wartung killt Ihre Pods
Kubernetes muss regelmaessig Nodes warten: Betriebssystem-Updates, Kernel-Patches, Cluster-Version-Upgrades, Hardware-Tausch. Bei all diesen Operationen werden Pods von einem Node entfernt und auf anderen Nodes neu gestartet.
Ohne Schutzmechanismus passiert dabei folgendes: Kubernetes raeumt einen Node mit kubectl drain, und wenn zufaellig alle drei Replikas Ihrer Anwendung auf diesem Node laufen, sind alle gleichzeitig weg. Die neuen Pods starten zwar auf anderen Nodes, aber bis sie bereit sind (Image Pull, Startup, Readiness Probe), ist Ihr Dienst nicht erreichbar.
Ein Pod Disruption Budget verhindert genau das. Es sagt dem Kubernetes API-Server: "Von dieser Anwendung muessen immer mindestens N Pods laufen. Warte mit dem Eviction, bis die Bedingung wieder erfuellt ist."
PDB-Grundlagen: minAvailable vs. maxUnavailable
Es gibt zwei Wege, ein PDB zu konfigurieren. Sie koennen nicht beide gleichzeitig in einem PDB verwenden.
| Parameter | Bedeutung | Beispiel |
|---|---|---|
minAvailable | Mindestanzahl (oder Prozent) der Pods, die jederzeit verfuegbar sein muessen | minAvailable: 2 bei 3 Replikas = max. 1 Pod darf gleichzeitig ausfallen |
maxUnavailable | Maximale Anzahl (oder Prozent) der Pods, die gleichzeitig nicht verfuegbar sein duerfen | maxUnavailable: 1 = immer nur 1 Pod auf einmal weg |
Beide Parameter akzeptieren absolute Zahlen oder Prozentwerte. Bei Prozentwerten rundet Kubernetes ab (bei minAvailable) bzw. auf (bei maxUnavailable).
Beispiel 1: PDB fuer ein stateless Deployment
Ein typischer Web-Service mit 4 Replikas. Wir wollen, dass bei Wartungsarbeiten immer mindestens 3 Pods laufen:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-frontend-pdb
namespace: production
spec:
minAvailable: 3
selector:
matchLabels:
app: web-frontend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-frontend
namespace: production
spec:
replicas: 4
selector:
matchLabels:
app: web-frontend
template:
metadata:
labels:
app: web-frontend
spec:
containers:
- name: web
image: registry.example.com/web-frontend:2.1.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
Wenn jetzt ein Admin kubectl drain node-2 ausfuehrt und auf node-2 zwei Pods dieser Anwendung laufen, wird Kubernetes nur einen davon evicten. Erst wenn der evicted Pod auf einem anderen Node wieder ready ist, darf der zweite Pod entfernt werden.
Beispiel 2: PDB fuer ein StatefulSet
Fuer StatefulSets wie Datenbanken oder Message Queues ist maxUnavailable: 1 die Standard-Empfehlung. Hier am Beispiel eines Redis-Clusters:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: redis-cluster-pdb
namespace: data
spec:
maxUnavailable: 1
selector:
matchLabels:
app: redis-cluster
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-cluster
namespace: data
spec:
serviceName: redis-cluster
replicas: 6
selector:
matchLabels:
app: redis-cluster
template:
metadata:
labels:
app: redis-cluster
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "1"
memory: "2Gi"
Bei einem Cluster-Upgrade werden die Redis-Pods nacheinander verschoben -- nie mehr als einer gleichzeitig. Das gibt dem Redis-Cluster Zeit, Daten zu resynchronisieren, bevor der naechste Pod bewegt wird.
Beispiel 3: PDB mit Prozentwerten und kubectl-Befehle
Prozentwerte sind nuetzlich, wenn sich die Anzahl der Replikas dynamisch aendert (z.B. durch einen HPA):
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-gateway-pdb
namespace: production
spec:
maxUnavailable: 25%
selector:
matchLabels:
app: api-gateway
Bei 8 Replikas duerfen maximal 2 Pods gleichzeitig ausfallen (25% von 8 = 2). Bei 4 Replikas nur 1 Pod (25% von 4 = 1, aufgerundet).
Nuetzliche Befehle zum Pruefen Ihrer PDBs:
# Alle PDBs im Cluster anzeigen
kubectl get pdb --all-namespaces
# Details eines PDBs anzeigen (inkl. erlaubte Disruptions)
kubectl get pdb web-frontend-pdb -n production -o yaml
# Wichtig: "disruptionsAllowed" zeigt, wie viele Pods aktuell evicted werden duerfen
kubectl get pdb -n production -o wide
# Dry-Run: Pruefen was passiert, bevor Sie tatsaechlich drainen
kubectl drain node-2 --dry-run=client --ignore-daemonsets --delete-emptydir-data
Wann greifen PDBs -- und wann nicht?
Das ist ein entscheidender Punkt, der oft missverstanden wird:
| Disruption-Typ | PDB schuetzt? | Beispiele |
|---|---|---|
| Freiwillig (voluntary) | Ja | kubectl drain, Cluster-Upgrade, Cluster Autoscaler Scale-Down, Spot/Preemptible Node Eviction |
| Unfreiwillig (involuntary) | Nein | Hardware-Ausfall, Kernel-Panic, Node-Netzwerkausfall, OOMKill durch den Kernel |
| Anwendungsfehler | Nein | CrashLoopBackOff, fehlgeschlagene Liveness Probes |
Fuer Schutz vor unfreiwilligen Ausfaellen brauchen Sie redundante Replikas in Kombination mit Pod Anti-Affinity, um sicherzustellen, dass Ihre Pods auf verschiedenen Nodes verteilt sind.
PDB + Rolling Updates: So spielen sie zusammen
PDBs interagieren mit der strategy Ihres Deployments. Ein Deployment mit maxUnavailable: 1 in der Rolling-Update-Strategie und einem PDB mit maxUnavailable: 1 koennen sich gegenseitig beeinflussen.
Die wichtigste Regel: PDBs gelten fuer Evictions durch den API-Server (z.B. bei kubectl drain). Rolling Updates werden vom Deployment Controller gesteuert und verwenden die maxUnavailable/maxSurge-Einstellungen der Update-Strategie, nicht das PDB.
Das bedeutet: Waehrend eines Rolling Updates kann ein Pod heruntergefahren werden, auch wenn das PDB eigentlich keine weitere Disruption erlauben wuerde. PDBs und Rolling-Update-Strategie sind zwei unabhaengige Mechanismen. Stellen Sie sicher, dass beide sinnvoll konfiguriert sind.
Typische Fehler
1. PDB blockiert Node Drain komplett
Wenn Sie minAvailable: 3 setzen und nur 3 Replikas haben, ist disruptionsAllowed: 0. Kein Pod darf jemals evicted werden. Ein kubectl drain haengt dann fuer immer (oder bis zum Timeout). Loesung: Entweder die Replikas erhoehen oder minAvailable reduzieren.
2. Selector stimmt nicht mit Pod-Labels ueberein
Das PDB referenziert Pods ueber den selector. Wenn die Labels nicht exakt uebereinstimmen, schuetzt das PDB nichts. Pruefen Sie mit:
# Welche Pods matcht das PDB?
kubectl get pods -n production -l app=web-frontend
# Stimmt die Anzahl mit dem PDB-Status ueberein?
kubectl get pdb web-frontend-pdb -n production
3. Kein PDB fuer kritische Services
Der haeufigste Fehler ist schlicht, kein PDB zu haben. Pruefen Sie systematisch, welche Deployments und StatefulSets in Ihrem Cluster kein PDB haben:
# Alle Deployments ohne PDB finden (vereinfachtes Skript)
for deploy in $(kubectl get deploy -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}'); do
ns=$(echo $deploy | cut -d/ -f1)
name=$(echo $deploy | cut -d/ -f2)
labels=$(kubectl get deploy $name -n $ns -o jsonpath='{.spec.selector.matchLabels}')
echo "Checking $deploy with labels: $labels"
done
4. PDB bei Single-Replica Deployments
Ein PDB mit minAvailable: 1 bei einem Deployment mit replicas: 1 bedeutet: der einzige Pod darf nie evicted werden. Das blockiert jede Wartung. Fuer Single-Replica-Workloads brauchen Sie entweder mehr Replikas oder muessen das PDB weglassen und kurze Downtime akzeptieren.
Empfohlene Standardwerte
| Workload-Typ | Empfohlene Replikas | Empfohlenes PDB |
|---|---|---|
| Stateless Web-Service | 3+ | maxUnavailable: 1 |
| StatefulSet (DB, Queue) | 3+ | maxUnavailable: 1 |
| Batch Job / CronJob | variabel | Kein PDB noetig |
| Singleton (z.B. Controller) | 1 (mit Leader Election) | Kein PDB oder maxUnavailable: 1 mit 2+ Replikas |
| Latenz-kritischer Service | 4+ | minAvailable: 75% |
PDB-Status interpretieren
Der Output von kubectl get pdb -o wide zeigt wichtige Felder:
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
web-frontend-pdb 3 N/A 1 7d
redis-cluster-pdb N/A 1 1 7d
- ALLOWED DISRUPTIONS: Wie viele Pods jetzt gerade evicted werden duerfen. Wenn dieser Wert 0 ist, blockiert das PDB jede Eviction.
- Ueberwachen Sie diesen Wert in Ihrem Monitoring. Ein PDB mit dauerhaft 0 Allowed Disruptions deutet auf ein Problem hin (zu wenig Replikas, fehlende Kapazitaet).
Integration in CI/CD
PDBs gehoeren in dasselbe Repository wie Ihre Deployment-Manifeste. Behandeln Sie sie als Teil Ihres Application Stacks:
my-app/
deployment.yaml
service.yaml
pdb.yaml # Gehoert dazu
hpa.yaml
networkpolicy.yaml
Wenn Sie Helm verwenden, definieren Sie das PDB als Template mit konfigurierbaren Werten:
# values.yaml
pdb:
enabled: true
maxUnavailable: 1
So kann jedes Team die Werte fuer seine Services anpassen, und das PDB wird automatisch mit jedem Deployment ausgerollt.
Zusammenspiel mit Cluster Autoscaler
Der Cluster Autoscaler beruecksichtigt PDBs, wenn er Nodes herunterskalieren will. Ein Node wird nur entfernt, wenn alle Pods darauf unter Einhaltung ihrer PDBs evicted werden koennen. Wenn ein PDB die Eviction blockiert, bleibt der Node bestehen -- auch wenn er unterlastig ist.
Das kann zu unerwuenscht hohen Kosten fuehren: Nodes bleiben laufen, weil PDBs das Herunterskalieren verhindern. Stellen Sie sicher, dass Ihre PDB-Werte mit Ihrer Kapazitaetsplanung und dem Autoscaling-Setup zusammenpassen.
Weitergehende Ressourcen
- Ergaenzend zu PDBs sollten Sie Rolling Updates korrekt konfigurieren, damit Deployments und PDBs nicht in Konflikt geraten.
- Fuer die Verteilung von Pods auf verschiedene Nodes nutzen Sie Pod Affinity und Anti-Affinity in Kombination mit PDBs.
- Ihr Monitoring-Stack sollte PDB-Metriken (z.B. ueber kube-state-metrics) erfassen und bei
disruptionsAllowed: 0einen Alert ausloesen.
Wenn Sie Hilfe bei der PDB-Konfiguration oder bei der Planung Ihrer Cluster-Wartungsstrategie brauchen, sprechen Sie uns an unter /kontakt.
Kubernetes-Beratung gesucht?
Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
PodDisruptionBudgets: Verfügbarkeit bei Updates sichern
PodDisruptionBudgets in Kubernetes konfigurieren: minAvailable vs maxUnavailable, Zusammenspiel mit Drain und Cluster Autoscaler, typische Fallstricke.
Kubernetes Change Management: Sichere Production-Änderungen
Change Management für Kubernetes-Cluster: Risikobewertung, GitOps-basierte Approval-Workflows, Rollback-Strategien und Emergency-Change-Prozesse.
Kubernetes PriorityClass und Preemption konfigurieren
PriorityClasses und Preemption richtig konfigurieren: Scheduling-Regeln, YAML-Beispiele und Anti-Patterns für stabile Production-Cluster.
Kubernetes Notfallplan: Production-Ausfall vermeiden
Kubernetes Production-Ausfall im Mittelstand vermeiden: MTTR-Statistiken, Runbook-Beispiele und warum ein einzelner Admin nicht ausreicht.
Pod Affinity und Anti-Affinity: Latenz senken
Kubernetes Pod Affinity und Anti-Affinity konfigurieren: YAML-Beispiele, topologyKey-Strategien und typische Scheduling-Fehler vermeiden.