执行kubectl apply更新同一份Deployment未删除旧Pod反而新建Pod
异常原因
- 滚动更新策略默认参数限制:Deployment默认采用
RollingUpdate更新策略,两个核心参数默认值如下:maxSurge:更新过程中最多允许超出预期副本数的Pod数量,默认25%,副本数为1时向上取整为1,允许最多同时存在2个PodmaxUnavailable:更新过程中最多允许处于不可用状态的Pod数量,默认25%,副本数为1时向下取整为0,不允许任何Pod不可用
旧Pod原本处于crash loop不可用状态,为了不违反maxUnavailable=0的规则,Deployment会先创建新Pod,等新Pod完全就绪后才会删除旧Pod。如果新Pod长时间未通过就绪探针、未进入Ready状态,Deployment就会一直保留两个Pod。
minReadySeconds配置过长:如果Deployment设置了minReadySeconds字段,新Pod进入Ready状态后需要等待指定时长才会被认定为可用,等待期间旧Pod不会被删除,会出现两个Pod临时共存的情况。- Pod标签匹配失效:如果修改配置时意外改动了Pod模板的
metadata.labels字段,导致旧Pod的标签不再匹配Deployment的selector.matchLabels规则,旧Pod会脱离当前Deployment的管理,Deployment新创建的Pod和旧Pod同时存在。 - 旧Pod删除卡住:旧Pod如果配置了自定义finalizer、或所在节点失联,收到删除指令后会一直停留在
Terminating状态,看起来像是持续运行,和新Pod同时存在。
解决方法
- 先确认Pod状态:执行
kubectl get pods -l app=app-pressbrief查看两个Pod的状态、创建时长、READY字段,确认是两个Running状态的Pod还是有一个处于Terminating状态,同时确认新Pod是否已经进入READY状态。- 如果新Pod未进入READY状态:排查新Pod的配置问题(比如镜像拉取失败、启动命令错误、就绪探针配置错误),修复后重新执行
kubectl apply,新Pod就绪后旧Pod会自动被删除。
- 如果新Pod未进入READY状态:排查新Pod的配置问题(比如镜像拉取失败、启动命令错误、就绪探针配置错误),修复后重新执行
- 如果是标签不匹配导致旧Pod脱离管理:手动删除旧Pod即可,执行命令
kubectl delete pod <旧Pod名称>。 - 如果是滚动更新策略参数不符合需求:可以根据业务场景调整更新策略:
对于副本数为1的服务,可改为Recreate策略,更新时会先删除所有旧Pod再创建新Pod,避免同时存在多个Pod,配置示例:
也可以调整RollingUpdate的参数,将spec: strategy: type: RecreatemaxSurge设为0、maxUnavailable设为1,允许更新过程中有1个不可用Pod,避免为了保障可用性先启动新Pod:spec: strategy: rollingUpdate: maxSurge: 0 maxUnavailable: 1 type: RollingUpdate - 如果旧Pod卡在Terminating状态:执行强制删除命令即可:
kubectl delete pod <旧Pod名称> --force --grace-period=0
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

