题干与适用场景
你负责一个 5 副本的有状态服务,需要在节点维护和集群缩容时保持法定人数。请设计 PDB,说明 minAvailable 与 maxUnavailable 如何选择,并解释为什么配置后仍可能中断。假设服务由 StatefulSet 管理,维护工具通过 Eviction API 驱逐 Pod。
面试官考察点
- 能否先定义服务的可用性约束和 quorum,而不是直接写 YAML。
- 能否区分 voluntary disruption 与节点故障、资源压力等 involuntary disruption。
- 能否理解 PDB 只限制驱逐速率,不保证始终有指定数量的 Pod。
- 能否发现滚动升级、标签选择器、百分比向上取整和资源不足导致的阻塞。
回答前需要澄清的问题
- 法定人数是多少? 5 副本的共识服务可能要求至少 3 个健康副本;普通无状态服务可能只要求保留 90% 容量。
- 谁执行驱逐? PDB 由 Eviction API 尊重;直接删除 Deployment 或 Pod 可绕过它。
- 维护是否包含应用滚动升级? PDB 不限制 Deployment/StatefulSet 滚动升级,升级策略需在工作负载中配置。
- 节点是否有足够余量调度替代 Pod? PDB 允许驱逐不等于新 Pod 能立即调度,资源不足会让 drain 卡住。
30 秒回答框架
“我先确认服务需要保留的健康副本数和驱逐来源。5 副本、需要 3 个副本组成 quorum 时,我会设置 minAvailable: 3,或在副本规模会变化时用等价的 maxUnavailable: 2,并让选择器与 StatefulSet 一致。PDB 只约束自愿驱逐,不防节点故障,也不代替滚动升级策略。上线前用 kubectl drain 检查 disruptionsAllowed,同时验证替代 Pod 有资源可调度。”
分步骤深入解答
1. 把可用性目标转换为预算
PDB 的预算是一次自愿干扰允许损失的副本数。若 5 副本服务必须保留 3 个健康副本,预算最多为 2。minAvailable: 3 直接表达剩余健康数;maxUnavailable: 2 表达允许不可用数。两者不能同时设置。
2. 选择适合伸缩的表达
固定 quorum 通常用 minAvailable 更直观。若工作负载副本会伸缩,官方文档建议考虑 maxUnavailable,它按期望副本数计算,能随规模变化。百分比会向上取整:7 个期望副本设置 maxUnavailable: 30%,允许的不可用数是 3,而非向下取 2,因此必须把取整纳入容量评估。
3. 绑定正确的工作负载
PDB 的 label selector 必须匹配 StatefulSet 的 selector,否则预算可能保护不到目标 Pod,或错误地把多个应用算在一起。选择器应保持稳定,发布时不要临时改标签逃避预算。
4. 说明 PDB 的边界
PDB 只约束 voluntary disruption,例如 kubectl drain 和集群自动维护。硬件故障、节点消失、资源压力驱逐属于 involuntary disruption,PDB 无法阻止它们,且这些故障仍会计入预算。直接删除 Pod 或 Deployment 也可能绕过 PDB。
5. 处理 drain 阻塞
如果预算已经用完,Eviction API 会拒绝新的驱逐并重试。即使允许驱逐,替代 Pod 仍可能因没有节点资源而 Pending,导致 drain 无法继续。应把 Pod requests、跨区分布、启动时间和节点余量一起纳入方案,而不是把 PDB 当成容量系统。
6. 与滚动升级和健康策略分开
PDB 不限制 Deployment 或 StatefulSet 自身的滚动升级;更新策略中的 maxUnavailable、maxSurge 和 readiness 才控制发布期间的替换。Kubernetes 还提供 unhealthy pod eviction policy,需结合故障 Pod 是否应先清理来决定。发布、维护和事故恢复应分别测试。
高质量示范回答
我会先确认 5 副本服务的 quorum 是 3,并确认维护工具使用 Eviction API。基础配置用 minAvailable: 3,选择器严格复用 StatefulSet 的标签;如果副本会自动伸缩,我会评估 maxUnavailable: 2 或经过取整验证的百分比。PDB 只限制自愿驱逐,不能阻止节点故障、资源压力或直接删除,也不控制滚动升级。
上线时我会检查 disruptionsAllowed,执行一次受控 drain,观察被驱逐 Pod 的终止时间、替代 Pod 的调度和 quorum 状态。如果预算耗尽,drain 暂停是预期行为;如果替代 Pod Pending,应补足节点余量或调整 requests,而不是把预算设得更宽。最后分别验证升级、节点故障和维护回滚路径。
常见错误
- 错误表现 → 认为 PDB 能防止所有宕机。 失败原因:PDB 不控制 involuntary disruption。修正方法:明确节点故障、资源压力和维护驱逐的边界。
- 错误表现 → 只写
maxUnavailable: 50%。 失败原因:百分比向上取整可能允许超出直觉的副本损失。修正方法:用实际期望副本数计算取整结果。 - 错误表现 → 认为 PDB 控制滚动升级。 失败原因:Deployment/StatefulSet 更新不受 PDB 限制。修正方法:在工作负载更新策略中配置发布行为。
- 错误表现 → 把 drain 卡住归咎于 PDB 错误。 失败原因:预算或节点资源不足都能让驱逐无法完成。修正方法:同时检查
disruptionsAllowed、Pending Pod、requests 和节点容量。
追问及应对
如果 5 副本中只有 3 个健康 Pod,还能驱逐吗?
若 minAvailable: 3,不能再允许自愿驱逐;Eviction API 应拒绝请求。先恢复健康副本或接受维护暂停,不能为了 drain 临时删除 PDB 而失去 quorum 保护。
如果集群自动缩容一直卡住,应该放宽 PDB 吗?
先确认缩容属于 voluntary disruption、预算是否耗尽以及替代 Pod 是否能调度。对 quorum 服务放宽预算可能直接破坏一致性;可以增加节点余量、调整缩容批次或为无状态服务采用容量百分比,而不是统一放宽。
直接删除 Pod 为什么绕过 PDB?
PDB 约束的是 Eviction API 的自愿驱逐请求,不是所有删除操作。治理上应限制直接删除权限,并让维护自动化调用 Eviction API;事故处置仍需保留明确的管理员旁路。
maxUnavailable: 0 有什么风险?
它要求零个自愿不可用 Pod,节点 drain 可能永远无法完成。只有在业务确实不能承受任何自愿中断、且团队有人工协调维护窗口时才使用,并准备解除预算后再恢复。