代表性面试主题

系统设计面试:如何用 Kubernetes PodDisruptionBudget 保护高可用服务?

系统设计困难
Offer.cc 编辑团队发布 更新

题干

一个 5 副本的有状态服务要支持节点升级,你如何设计 PodDisruptionBudget?

题干与适用场景

你负责一个 5 副本的有状态服务,需要在节点维护和集群缩容时保持法定人数。请设计 PDB,说明 minAvailablemaxUnavailable 如何选择,并解释为什么配置后仍可能中断。假设服务由 StatefulSet 管理,维护工具通过 Eviction API 驱逐 Pod。

面试官考察点

  • 能否先定义服务的可用性约束和 quorum,而不是直接写 YAML。
  • 能否区分 voluntary disruption 与节点故障、资源压力等 involuntary disruption。
  • 能否理解 PDB 只限制驱逐速率,不保证始终有指定数量的 Pod。
  • 能否发现滚动升级、标签选择器、百分比向上取整和资源不足导致的阻塞。

回答前需要澄清的问题

  1. 法定人数是多少? 5 副本的共识服务可能要求至少 3 个健康副本;普通无状态服务可能只要求保留 90% 容量。
  2. 谁执行驱逐? PDB 由 Eviction API 尊重;直接删除 Deployment 或 Pod 可绕过它。
  3. 维护是否包含应用滚动升级? PDB 不限制 Deployment/StatefulSet 滚动升级,升级策略需在工作负载中配置。
  4. 节点是否有足够余量调度替代 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 自身的滚动升级;更新策略中的 maxUnavailablemaxSurge 和 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 可能永远无法完成。只有在业务确实不能承受任何自愿中断、且团队有人工协调维护窗口时才使用,并准备解除预算后再恢复。

公开来源

同类题目

相关面试工具

用 Solve 整理系统设计回答

从澄清需求开始,展开规模、架构、组件选择和取舍。

查看工具