如何配置K8s滚动更新以等待60秒再终止旧Pod?
这个问题我之前帮不少开发者踩过坑,核心就是得让Kubernetes准确摸清楚新Pod什么时候才真正就绪,同时调整滚动更新的规则,别让旧Pod在新Pod还没准备好的时候就被干掉。下面给你一步步的实现方案:
解决方案步骤
1. 配置就绪探针(Readiness Probe)
这是解决问题的关键——K8s默认只会检查容器进程是否启动,但你的应用启动后需要20-30秒才能真正处理请求,必须配置就绪探针让K8s知道Pod的实际就绪状态。
如果你的应用有健康检查接口(比如/health),可以这么配置:
spec: containers: - name: your-app-container image: your-docker-image readinessProbe: httpGet: path: /health port: 8080 # 替换成你的应用端口 initialDelaySeconds: 20 # 匹配你的应用启动耗时,20秒后开始第一次探测 periodSeconds: 5 # 每5秒探测一次 failureThreshold: 3 # 连续3次失败才标记Pod未就绪
这样K8s会等20秒后开始检查,直到你的健康接口返回200,才会把新Pod加入服务负载池,同时滚动更新时也会等新Pod就绪后再处理旧Pod。
2. 调整Deployment的滚动更新策略
接下来修改Deployment的滚动更新规则,确保旧Pod不会被提前终止:
spec: strategy: rollingUpdate: maxSurge: 1 # 允许同时启动1个额外的新Pod(可根据集群资源调整) maxUnavailable: 0 # 更新过程中不允许任何旧Pod不可用 type: RollingUpdate
把maxUnavailable设为0是核心——这意味着K8s必须等新Pod完全就绪后,才会终止对应的旧Pod,彻底避免服务中断的情况。
3. 可选:添加预停止钩子延长缓冲时间
如果你的场景需要在终止旧Pod前额外等待60秒(比如处理剩余请求),可以给容器加上preStop钩子,同时调整优雅终止时长:
spec: containers: - name: your-app-container image: your-docker-image terminationGracePeriodSeconds: 90 # 要大于preStop的等待时间,避免强制杀死 lifecycle: preStop: exec: command: ["sleep", "60"]
这个步骤是可选的,如果你已经通过就绪探针和滚动策略解决了问题,可能不需要这一步。但如果应用需要缓冲时间收尾,这个配置会很有用。
验证配置
把修改后的配置应用到集群:
kubectl apply -f your-deployment.yaml
然后观察滚动更新状态:
kubectl rollout status deployment/your-deployment-name
你会看到K8s先启动新Pod,等待就绪探针确认可用后,才会逐步终止旧Pod,完全符合你的需求。
内容的提问来源于stack exchange,提问作者nirebam368




