K8s PodDisruptionBudget 与滚动更新安全策略:从随意驱逐到有序迁移,集群稳定的守护机制
K8s PodDisruptionBudget 与滚动更新安全策略:从随意驱逐到有序迁移,集群稳定的守护机制

一、节点维护的"踩踏"风险:无序驱逐导致服务中断
Kubernetes 集群在节点维护(如内核升级、硬件更换)时,需要驱逐节点上的 Pod。如果没有 PDB(PodDisruptionBudget)保护,多个节点同时维护可能导致大量 Pod 被同时驱逐,服务可用副本数骤降,甚至完全不可用。
更常见的场景是滚动更新:Deployment 更新镜像版本时,K8s 逐个终止旧 Pod 并创建新 Pod。如果更新策略配置不当(如 maxUnavailable=100%),所有旧 Pod 同时终止,新 Pod 尚未就绪,服务出现中断窗口。
二、PDB 机制与滚动更新策略
flowchart TD
A[节点维护/滚动更新] --> B[PDB 检查]
B --> C{当前可用副本 ≥ minAvailable?}
C -->|是| D[允许驱逐 Pod]
C -->|否| E[拒绝驱逐,等待]
D --> F[新 Pod 创建]
F --> G{Readiness Probe 通过?}
G -->|是| H[继续驱逐下一个旧 Pod]
G -->|否| I[等待新 Pod 就绪]
2.1 PDB 配置
# pdb-api-server.yaml — API 服务 PDB 配置
# 设计意图:确保滚动更新或节点维护时,API 服务始终保持最低可用副本
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-server-pdb
spec:
minAvailable: 2 # 至少保持2个副本可用
selector:
matchLabels:
app: api-server
---
# 核心数据库使用 maxUnavailable 更严格
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: postgres-pdb
spec:
maxUnavailable: 1 # 最多1个副本不可用
selector:
matchLabels:
app: postgres
2.2 安全滚动更新策略
# deployment-safe-rollout.yaml — 安全滚动更新配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
replicas: 5
selector:
matchLabels:
app: api-server
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 每次最多1个Pod不可用
maxSurge: 2 # 最多额外创建2个Pod
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api-server
image: api-server:v2.0.0
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
2.3 滚动更新监控脚本
#!/bin/bash
# rollout-monitor.sh — 滚动更新监控脚本
# 设计意图:实时监控滚动更新进度,异常时自动暂停
DEPLOYMENT=$1
NAMESPACE=${2:-default}
echo "监控 Deployment: $DEPLOYMENT"
while true;
do
STATUS=$(kubectl rollout status deployment/$DEPLOYMENT -n $NAMESPACE --timeout=1s 2>&1)
if echo "$STATUS" | grep -q "successfully rolled out"; then
echo "✅ 滚动更新完成"
break
fi
# 检查是否有 CrashLoopBackOff
CRASHING=$(kubectl get pods -n $NAMESPACE -l app=$DEPLOYMENT \
--field-selector=status.phase!=Running -o name 2>/dev/null)
if [ -n "$CRASHING" ]; then
echo "⚠️ 检测到异常 Pod: $CRASHING"
echo "暂停滚动更新..."
kubectl rollout pause deployment/$DEPLOYMENT -n $NAMESPACE
break
fi
echo "更新进行中..."
sleep 5
done
三、多环境 PDB 策略管理
# Kustomize overlay: 生产环境严格 PDB
# overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- target:
kind: Deployment
name: api-server
patch: |
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
replicas: 5
strategy:
rollingUpdate:
maxUnavailable: 1
maxSurge: 2
四、边界分析与架构权衡
PDB 与集群维护的冲突:PDB 可能阻止节点维护操作。如果所有节点都需要维护,而 PDB 要求至少 N 个副本可用,维护操作会被无限期阻塞。需要在维护窗口期间临时调整 PDB。
maxUnavailable=0 的限制:K8s 不允许 Deployment 的 maxUnavailable 设为 0,因为这意味着旧 Pod 终止前必须有新 Pod 就绪。但新 Pod 的创建受集群资源限制,如果资源不足,更新会卡住。
StatefulSet 的滚动更新:StatefulSet 的滚动更新按序号逆序逐个更新,比 Deployment 更安全但更慢。对于有状态服务(如数据库),需要确保每个副本更新后数据同步完成再更新下一个。
PDB 的 minAvailable 计算方式:minAvailable 可以是绝对数量或百分比。使用百分比时,如果副本数变化,PDB 的保护力度也会变化。建议核心服务使用绝对数量。
五、总结
PDB 和滚动更新策略是 K8s 集群稳定性的基础保障。PDB 确保节点维护时服务可用性,滚动更新策略确保版本发布时零中断。落地建议:所有生产服务配置 PDB;滚动更新使用 maxUnavailable=1 确保渐进式发布;核心服务使用绝对数量的 minAvailable;滚动更新期间监控异常 Pod 并配置自动暂停。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)