核心在于让readinessProbe真实反映应用就绪状态,配置initialDelaySeconds≥30s、periodSeconds≤10s,并配合minReadySeconds:60和maxUnavailable:0,确保新Pod完全启动且稳定运行后才摘除旧Pod,实现流量无损切换。

滚动更新时请求丢失,核心在于新旧 Pod 切换与负载均衡器协同脱节。不是单纯改个参数就能解决,而是要让健康检查、就绪机制、流量切换三者严格对齐。
确保 readinessProbe 真正反映服务可服务状态
很多请求丢失,是因为 Pod 虽已 Running,但 Spring Boot 应用还没完成初始化(比如数据库连接池未建满、缓存未预热、Actuator 健康端点返回 false)。Kubernetes 却已将其加入 Service 的 Endpoint 列表,流量开始涌入。
- readinessProbe 必须调用应用层真实健康接口,例如
/actuator/health,且配置initialDelaySeconds和periodSeconds留足启动缓冲(建议 initialDelaySeconds ≥ 30s,periodSeconds ≤ 10s) - 避免使用仅检测端口是否监听的探针(如 tcpSocket),它无法识别“端口通但业务不可用”的假就绪状态
- 在 Spring Boot 中,可自定义 HealthIndicator 返回更细粒度的状态,确保 /actuator/health 返回 UP 后再接受流量
设置 minReadySeconds 防止过早摘除旧 Pod
即使 readinessProbe 已通过,新 Pod 也可能因 JVM 预热、连接池填充等原因,在最初几秒内响应缓慢或超时。此时若旧 Pod 被立即终止,就会造成请求丢失。
- 在 Deployment 的
strategy.rollingUpdate下配置minReadySeconds: 60(建议值,根据应用冷启动实测调整) - 该参数要求新 Pod 就绪后,必须持续稳定运行指定秒数,才允许 Kubernetes 开始删除旧 Pod
- 配合
maxUnavailable: 0,可确保整个更新过程中始终有足够副本在线提供服务
合理配置 Service 与 Ingress 的会话保持策略
对于 WebSocket、长轮询、或依赖本地内存 Session 的场景,单纯轮询会导致连接中断或状态错乱,表现为“请求成功但用户掉线”。
- 若使用 ClusterIP Service,启用
sessionAffinity: ClientIP,适合短期会话粘性需求 - 若走 Ingress(如 Nginx Ingress Controller),配置基于 Cookie 的 sticky session:
nginx.ingress.kubernetes.io/affinity: "cookie"并指定nginx.ingress.kubernetes.io/session-cookie-name - 注意:ClientIP 粘性在 NAT 环境下可能失效;Cookie 粘性需客户端支持且不适用于非 HTTP 场景(如 gRPC)
验证流量切换是否平滑的关键检查项
上线前务必执行这几步验证,比事后排查高效得多:
- 用
kubectl get endpoints <service-name>观察更新过程中 endpoints 是否逐步替换,而非瞬间清空再重建 - 用
kubectl describe pod <new-pod>查看 Events,确认Started container后是否出现Readiness probe succeeded,且间隔合理 - 在更新期间,持续 curl 服务入口(Service ClusterIP 或 Ingress 域名),观察是否有 502/503 或连接拒绝,记录失败时间点并与 Pod 状态日志比对
- 若使用云厂商 LoadBalancer(如阿里云 SLB/NLB),确认其后端服务器组中 Pod 的健康状态变更是否与 Kubernetes Endpoint 同步,避免 LB 缓存导致旧 Pod 仍被转发


















