PodDisruptionBudget解决什么问题
Kubernetes集群在节点维护、自动扩缩容、版本滚动更新时,kube-scheduler和controller-manager会主动驱逐Pod。如果没有保护机制,驱逐操作可能同时终止同一服务的多个Pod副本,导致服务可用性急剧下降甚至完全中断。
PodDisruptionBudget(PDB)是一种声明式约束,告诉Kubernetes在 voluntary disruption(自愿驱逐)场景下,必须保留多少Pod处于可用状态。它只对自愿驱逐生效,不影响节点硬件故障这种 involuntary disruption(非自愿驱逐)。
自愿驱逐与非自愿驱逐的区分
理解这两种驱逐的区别是正确使用PDB的前提:
- 自愿驱逐:由管理员或控制器主动触发——
kubectl drain排空节点、集群自动扩缩容缩容节点、kubectl delete pod等。这类驱逐可以被PDB拦截或延迟。 - 非自愿驱逐:由硬件故障、内核panic、网络分区等不可控因素导致。PDB无法阻止这类驱逐,需要通过多副本+反亲和性+跨可用区部署来保证高可用。
PDB的保护范围仅限于自愿驱逐。不要指望PDB能防住节点宕机——那是亲和性调度和多副本部署的职责。
PDB的两种约束模式
PDB通过minAvailable或maxUnavailable两个字段定义约束,两者互斥,只能使用其中一个:
# 模式一:minAvailable(最少保留可用Pod数)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-server-pdb
namespace: production
spec:
minAvailable: 2
selector:
matchLabels:
app: api-server
---
# 模式二:maxUnavailable(最多不可用Pod数)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: worker-pdb
namespace: production
spec:
maxUnavailable: 1
selector:
matchLabels:
app: worker
两种模式的选择取决于部署规模:
- 副本数固定且较少(2-5个):用
minAvailable,确保绝对数量 - 副本数较多或会自动扩缩容:用
maxUnavailable,按比例控制
minAvailable和maxUnavailable也支持百分比形式,如minAvailable: 50%,在HPA自动扩缩容场景下更灵活。
PDB在节点维护中的实际行为
执行kubectl drain排空节点时,PDB的工作流程如下:
- kubelet收到drain命令,开始逐个驱逐节点上的Pod
- eviction API检查每个被驱逐Pod所属的PDB约束
- 如果驱逐该Pod会导致可用Pod数低于minAvailable,驱逐请求被拒绝
- kubectl drain会等待并重试,默认超时时间为0(无限等待)
实际操作中的现象——PDB阻止驱逐时,kubectl drain会报错:
error when evicting pods/"api-server-7b5f6c8d4-xkg2m" -n "production"
(to retry pass --force=false): Cannot evict pod as it would violate
the pod's disruption budget.
处理方式有两种:等待其他节点的Pod就绪后再重试drain,或者使用--disable-eviction强制删除(不推荐,会绕过PDB保护)。正确的做法是确保集群有足够的冗余节点,使得drain一个节点时,Pod可以在其他节点重建。
滚动更新与PDB的配合
Deployment的滚动更新本身不受PDB约束——Deployment控制器通过maxUnavailable和maxSurge参数控制更新节奏。但PDB会影响更新过程中节点维护的可行性。
一个常见问题:PDB的minAvailable设置过高,导致滚动更新期间所有Pod无法被驱逐,节点维护被阻塞。例如Deployment有3个副本,PDB设置minAvailable=3,意味着所有Pod都必须可用,任何驱逐都会被拒绝。
合理的配置示例——3副本Deployment,PDB保证至少2个可用:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: api-server
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api-server
image: api-server:v2.1.0
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-server-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: api-server
readinessProbe的配置至关重要。PDB计算可用Pod数时,只计算Ready状态的Pod。如果readinessProbe配置不当(探测间隔过长或路径错误),新Pod迟迟不就绪,PDB会一直阻止旧Pod被驱逐,导致更新卡住。
PDB配置的常见错误
- minAvailable等于副本数——PDB要求所有Pod都必须可用,任何驱逐都会被拒绝。在3副本场景下设minAvailable=2或maxUnavailable=1。
- selector匹配范围过大——PDB的selector误匹配了不该保护的Pod,导致不相关的驱逐也被阻止。通过
kubectl get pods -l app=api-server --all-namespaces确认selector精确匹配目标。 - 忘配readinessProbe——PDB依赖Pod的Ready状态判断可用性,没有readinessProbe的Pod启动后立即Ready,但可能无法处理请求,PDB的数据不准确。
- 单可用区部署——所有副本在同一可用区,该可用区节点维护时PDB会阻塞驱逐。通过
topologySpreadConstraints将副本分散到多个可用区。
PDB状态检查与故障排查
查看PDB状态:
# 查看所有PDB
kubectl get pdb -A
# 查看PDB详情
kubectl describe pdb api-server-pdb -n production
输出中的关键字段:
Allowed Disruptions:当前允许驱逐的Pod数量。如果为0,说明PDB正在阻止驱逐。Current/Desired:当前可用Pod数 / 期望可用Pod数Expected/Disruptions Allowed:预期Pod总数 / 允许驱逐数
排查PDB阻塞问题时的命令组合:
# 检查Pod状态是否Ready
kubectl get pods -n production -l app=api-server \
-o custom-columns=NAME:.metadata.name,STATUS:.status.phase,READY:.status.containerStatuses[0].ready
# 检查PDB事件
kubectl get events -n production --field-selector reason=NoPodDisruptionBudget
# 模拟驱逐测试(dry-run)
kubectl drain node-3 --dry-run --ignore-daemonsets --delete-emptydir-data
--dry-run参数可以预演drain操作,不实际驱逐Pod,用于验证PDB配置是否正确。
集群级PDB管理策略
生产集群中建议为所有关键服务配置PDB。运维操作准则:
- 每个Deployment至少配置一个PDB,副本数小于等于2时设minAvailable为1
- CronJob和Job不需要PDB——它们的生命周期由自身控制器管理
- DaemonSet不需要PDB——每个节点一个Pod,驱逐后由DaemonSet控制器重新调度
- 使用Kyverno或OPA Gatekeeper实现PDB的强制策略——自动为带特定标签的Deployment创建PDB
监控PDB状态应该纳入集群巡检项。通过Prometheus的kube-state-metrics采集PDB指标:kube_poddisruptionbudget_status_pod_disruptions_allowed表示允许驱逐数,持续为0的PDB需要排查原因。PDB是SRE稳定性工程中成本低、收益高的防护手段,正确配置后能在节点维护和自动伸缩时有效防止服务中断。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetespoddisruptionbudget-pei-zhi-zhi-nan-ru-he-fang/