Kubernetes 中 Docker 容器微服务无损下线需打通“流量摘除—请求处理—进程终止”三步链路:通过 readiness probe 实时控制 Endpoint、preStop 主动下线、terminationGracePeriodSeconds 与 SIGTERM 协同实现优雅终止。

在 Kubernetes 中让 Docker 容器实现微服务无损下线,核心不是只改容器镜像或加 sleep,而是打通“流量摘除—请求处理—进程终止”三步链路。关键在于 Kubernetes 原生机制与应用层配合,而非单靠某一方。
确保 readiness probe 实时反映服务状态
Service 的 Endpoint 是否包含该 Pod,完全取决于 readiness probe 的结果。缩容时若 probe 仍返回成功,流量就会继续打进来,导致 502/503。
- probe 配置中必须设 failureThreshold: 1,避免重试延迟摘除
- 应用需在收到 SIGTERM 后立即关闭 /readyz 接口响应(如返回 503),而不是等 shutdown 完成才关
- 不要复用 livenessProbe 的路径做 readiness;健康检查和就绪检查语义不同,应分离
用 preStop Hook 主动触发服务下线动作
preStop 是 Pod 被标记为 Terminating 后、发 SIGTERM 前的唯一可控窗口,适合调用注册中心下线接口或关闭长连接入口。
- 推荐使用 exec 类型执行轻量命令,例如:
curl -X POST http://localhost:22222/offline(Dubbo QoS)或curl -X POST http://127.0.0.1:8080/actuator/health/ready?status=DOWN(Spring Boot Actuator) - 避免在 preStop 中执行耗时操作;如需等待,可用
sleep 5,但总时长受 terminationGracePeriodSeconds 约束 - 若调用失败(如网络不通),不能阻塞整个流程,建议设置超时(
curl --max-time 3)并忽略失败
合理配置 terminationGracePeriodSeconds 并处理 SIGTERM
这个字段决定了从发 SIGTERM 到强制 kill 的最大缓冲时间,它要覆盖:probe 失败传播 + preStop 执行 + 请求处理完成。
- 默认 30 秒往往不够,建议根据业务平均请求耗时 × 2 来设,例如 60 秒
- 应用代码必须监听 SIGTERM,并启动 graceful shutdown:关闭 HTTP server、拒绝新连接、等待活跃请求结束(Go 用
server.Shutdown(),Java 用 Spring 的 SmartLifecycle 或 actuator shutdown endpoint) - Dockerfile 中无需额外设 STOPSIGNAL(Kubernetes 默认用 SIGTERM),除非你明确需要换信号
验证是否真正无损的关键检查点
上线后别只看 Pod Ready,要确认整个闭环生效:
- 手动缩容一个 Pod,立刻查
kubectl get endpoints <svc-name>—— 对应 IP 应在几秒内消失 - 同时抓包或看日志,确认 /readyz 在 SIGTERM 后首次 probe 就失败,且不再有新请求进该 Pod
- 观察应用日志,确认 shutdown 流程启动时间与 SIGTERM 时间差 ≤ 1 秒,且所有活跃连接在 grace period 内自然结束


















