文章目录
前言
在 Kubernetes 集群的生命周期中,节点维护、自动伸缩、版本升级是常态。但你是否经历过这样的“惊魂时刻”?
- 执行
kubectl drain node-01进行节点维护时,一个关键的 3 副本应用瞬间全部中断,只因 PDB 配置错误。 - 集群自动伸缩器(CA)为节省成本缩容节点,却意外驱逐了唯一运行中的数据库 Pod,导致服务雪崩。
- 滚动升级时,因
maxUnavailable: 100%的错误设置,所有 Pod 被同时终止,服务不可用长达 5 分钟。
问题的根源在于:Kubernetes 的许多操作(如 drain、eviction)会主动驱逐 Pod,而默认情况下,这些操作不考虑应用的高可用性需求。
Pod Disruption Budgets (PDB) 正是 Kubernetes 提供的“保护机制”。它允许你声明在自愿性干扰(如节点维护、升级)期间,应用必须保持可用的最小副本数或最大不可用副本数,确保服务的连续性。
本文将深入剖析 PDB 的核心参数、工作原理、真实场景与最佳实践,助你为关键应用打造坚不可摧的“抗扰动盾牌”。
一、什么是自愿性干扰(Voluntary Disruptions)?
🎯 定义:由管理员或集群自治系统主动发起的、可被延迟的 Pod 驱逐操作。
常见场景:
| 操作 | 描述 |
|---|---|
kubectl drain | 节点维护前驱逐 Pod |
| 集群自动伸缩 | 缩容节点时驱逐 Pod |
| 节点升级 | kubelet、内核升级 |
| 静态 Pod 更新 | Master 节点组件升级 |
kubectl delete pod | 手动删除(在某些策略下) |
✅ PDB 仅对“自愿性”干扰有效,对节点故障、OOM 等“非自愿性”干扰无效。
二、核心参数:minAvailable vs maxUnavailable
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
selector:
matchLabels:
app: my-app
minAvailable: 2
# 或
# maxUnavailable: 1
2.1 minAvailable
- 含义:必须保持可用的最小副本数。
- 示例:
minAvailable: 2→ 至少 2 个 Pod 必须处于Ready状态。 - 适用:副本数固定的场景(如 3 副本应用)。
2.2 maxUnavailable
- 含义:允许同时不可用的最大副本数。
- 示例:
maxUnavailable: 1→ 最多 1 个 Pod 可被驱逐。 - 支持百分比:
maxUnavailable: 25%→ 适用于副本数动态变化的场景(如 HPA)。
✅ 二者二选一,不能同时设置。
三、工作原理:PDB如何拦截驱逐?
3.1 驱逐流程
3.2 关键行为
- 阻塞式保护:当驱逐会导致违反 PDB 时,
drain或eviction操作会被阻塞。 - 优雅等待:PDB Controller 会持续监控,一旦条件满足(如新 Pod 就绪),立即批准驱逐。
- API 层拦截:通过
Eviction子资源实现,与DELETE操作不同。
四、真实场景与配置示例
4.1 场景1:3副本应用的高可用保障
目标:任何时候至少 2 个 Pod 可用。
spec:
minAvailable: 2
selector:
matchLabels:
app: frontend
- 驱逐时,最多允许 1 个 Pod 不可用。
- ✅ 单个 Pod 驱逐不会导致服务中断。
4.2 场景2:动态副本应用(HPA)
目标:副本数在 5-20 之间,允许 20% 的 Pod 同时不可用。
spec:
maxUnavailable: "20%"
selector:
matchLabels:
app: api-gateway
- 当副本=10时,最多驱逐 2 个。
- 当副本=5时,最多驱逐 1 个。
- ✅ 自适应不同规模,灵活高效。
4.3 场景3:单实例关键服务
目标:数据库 Pod 在驱逐前必须有新实例就绪。
spec:
minAvailable: 1
selector:
matchLabels:
app: mysql
drain操作会一直等待,直到新的 MySQL Pod 就绪并被标记为Ready。- ✅ 实现“滚动切换”,零停机维护。
4.4 场景4:有状态应用(StatefulSet)
# PDB 与 StatefulSet 的序号无关
spec:
minAvailable: 2
selector:
matchLabels:
app: kafka-broker
- 可安全地
drainkafka-0,只要kafka-1和kafka-2可用。 - ✅ 支持有状态应用的滚动维护。
五、与Deployment滚动策略的协同
5.1 配置 Deployment
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
replicas: 3
5.2 PDB 配置
spec:
minAvailable: 2
5.3 协同效果
- 理想情况:Deployment 先创建新 Pod,再删除旧 Pod,始终有 3 个可用。
- 故障情况:如果新 Pod 启动失败,Deployment 会暂停,而 PDB 会阻止
drain操作,形成双重保护。
✅ PDB 是最后一道防线。
六、最佳实践与陷阱规避
6.1 黄金法则
- 关键应用必配:为所有生产级应用创建 PDB。
- 合理设置阈值:
- 副本数 ≥ 3 →
minAvailable: 2或maxUnavailable: 1 - 使用 HPA → 优先
maxUnavailable: "XX%"
- 副本数 ≥ 3 →
- 命名清晰:
<app-name>-pdb,便于管理。 - 定期审查:架构变更后更新 PDB。
6.2 常见陷阱
| 陷阱 | 规避方法 |
|---|---|
| PDB 过于严格 | minAvailable: 3 对 3 副本应用 → 无法进行任何维护 |
| 未覆盖所有组件 | 为前端、后端、数据库分别创建 PDB |
| 与 HPA 冲突 | 确保 maxUnavailable 与 HPA 的最小副本兼容 |
| 忘记删除 | 应用下线后清理 PDB |
七、监控与调试
7.1 查看PDB状态
# 查看 PDB 详情
kubectl get pdb my-app-pdb
# 输出示例
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
my-app-pdb 2 N/A 1 10d
ALLOWED DISRUPTIONS:当前允许被驱逐的副本数。0表示受保护。
7.2 调试驱逐失败
# 查看 drain 失败原因
kubectl drain node-01 --dry-run=server
# 错误信息会明确指出哪个 PDB 阻止了操作
# 查看 PDB 事件
kubectl describe pdb my-app-pdb
八、总结:PDB是高可用的“最后守门员”
- 主动防护:在干扰发生前就设置保护策略。
- 精准控制:基于副本数或百分比定义可用性。
- 无缝集成:与
drain、CA、HPA 等工具协同工作。 - 生产必需:任何严肃的 Kubernetes 部署都不可或缺。
🌟 记住:在 Kubernetes 中,没有 PDB 的应用,就像没有保险的赛车手——任何一次“维护”都可能成为致命事故。
通过为关键应用配置合理的 Pod Disruption Budget,你不仅能安全地执行节点维护和集群升级,还能有效防止自动伸缩等自治系统引发的意外中断,是保障服务 SLA 的基石。
如需获取更多关于Kubernetes性能调优、安全加固、多集群管理、GitOps实践、服务网格深度解析等进阶内容,请持续关注本专栏《云原生技术深度解析》系列文章。
1955

被折叠的 条评论
为什么被折叠?



