单副本Deployment场景下如何实现Pod的零停机驱逐?
单副本Deployment场景下如何实现Pod的零停机驱逐?
这个问题戳中了单副本Deployment在节点维护或自动缩容场景下的核心痛点——默认的驱逐逻辑确实会直接干掉旧Pod,导致服务断档。不过我们可以通过两个关键配置的组合来实现类似kubectl rollout restart的零停机效果,具体如下:
1. 配置Pod Disruption Budget(PDB)限制服务可用性
PDB的作用是告诉Kubernetes集群:在执行自愿中断操作(比如节点排空、集群自动扩缩容缩容、节点版本升级)时,不能让你的应用可用Pod数低于指定阈值。对于单副本场景,我们需要确保始终有至少1个可用Pod:
apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: my-app-pdb spec: minAvailable: 1 selector: matchLabels: app: my-app # 这里要严格匹配你的Deployment的Pod标签
当集群尝试驱逐旧Pod时,会先检查PDB规则:如果删除旧Pod后可用数会降到0,就会暂停驱逐操作,直到有新的Pod就绪为止。
2. 调整Deployment的滚动更新策略
配合PDB,我们需要明确Deployment的滚动更新规则,允许临时创建额外的1个Pod(单副本场景下暂时最多2个),同时禁止任何Pod处于不可用状态:
apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 1 strategy: rollingUpdate: maxSurge: 1 # 允许超过期望副本数的最大数量,这里设为1,支持临时多一个Pod maxUnavailable: 0 # 允许不可用的Pod数量为0,确保服务始终可用 type: RollingUpdate # 以下是你的Pod模板、标签等原有配置...
实际生效流程
当触发自愿驱逐时,整个流程会变成:
- 集群标记旧Pod为待删除,但由于PDB限制,不会立即执行删除
- Deployment检测到旧Pod即将被删除,按照滚动更新策略创建新Pod,调度到其他可用节点
- 新Pod完成镜像拉取、容器启动,通过
readinessProbe验证就绪后 - 集群才会执行旧Pod的删除操作,全程保持服务可用
注意事项
- 这个方案仅对自愿中断有效,如果是节点突然宕机、网络故障这类非自愿中断,旧Pod会直接消失,Deployment只能事后创建新Pod,这种情况的 downtime无法避免(除非改成多副本架构)
- 一定要确保你的Pod配置了正确的
readinessProbe,否则集群可能误判新Pod就绪状态,导致提前删除旧Pod引发断档 - 如果使用Cluster Autoscaler,默认它会尊重PDB规则,但要确认你的集群版本和Autoscaler配置没有禁用该特性
备注:内容来源于stack exchange,提问作者vbezhenar
相关产品推荐
相关产品推荐

