Skip to content
Kubernetes 核心对象与资源治理 · 第 4 篇 / 共 4 篇
领域运维与部署
专题Kubernetes 专题
当前序列Kubernetes 核心对象与资源治理
阅读位置第 4 篇 / 共 4 篇当前专题第 1 个序列 / 共 3 个序列

Readiness、Liveness、Startup Probe 怎么分工

很多 Kubernetes 服务“不稳定”,问题并不在镜像,也不在调度,而是在探针设计上。

最常见的现象包括:

  • Pod 明明起来了,但一接流量就报错
  • 应用启动慢,被反复重启,永远起不来
  • 短暂依赖抖动导致实例被频繁杀掉
  • 服务发布时明明副本够,线上还是出现请求尖峰失败

这些问题大多和这三个探针分工不清有关:

  • Readiness Probe
  • Liveness Probe
  • Startup Probe

先说结论

  • Readiness 负责回答“现在能不能接流量”
  • Liveness 负责回答“这个进程是不是已经卡死,需要被重启”
  • Startup 负责回答“应用是不是还在正常启动阶段,先别急着按存活探针处理”

最容易犯的错误不是不会配置,而是让一个探针同时承担多个职责。这样一来,流量切换、故障自愈和启动保护就会互相打架。

一、为什么探针不是“配上就行”

探针的本质不是做健康检查展示页,而是参与平台决策:

  • 是否把流量转进来
  • 是否把实例从 Service 里摘掉
  • 是否要重启这个容器
  • 是否认为启动已经超时

也就是说,你返回的每一个成功或失败,都会直接影响线上调度行为。

所以探针设计错了,后果往往不是“监控页不准”,而是:

  • 正常实例被踢出流量
  • 未就绪实例提前接流量
  • 慢启动服务被误杀
  • 短暂故障被放大成频繁重启

二、Readiness:只回答“能不能接流量”

Readiness 和可用性直接相关,但它不应该承担“判死刑”的职责。

一个实例 readiness 失败时,更合理的效果是:

  • 暂时从 Service 后端摘掉
  • 不再接收新流量
  • 但容器本身先别急着重启

它更适合检查:

  • 应用核心依赖是否基本可用
  • 关键初始化是否完成
  • 必要配置、线程池、连接池是否准备就绪
  • 是否处于发布中的预热阶段

但要注意,readiness 不应该耦合过多外围依赖。比如某个低优先级外部接口偶发超时,不应该导致整个服务立刻从流量里摘除,否则会造成可用性被过度放大。

三、Liveness:只处理“进程活着但已经不工作”的情况

Liveness 最容易被误用。

很多团队把 /health 接口同时给 readiness 和 liveness 用,结果只要数据库连不上、Redis 短暂抖一下,Kubernetes 就开始重启容器。问题不仅没好,反而把连接风暴、缓存击穿、线程池抖动进一步放大。

Liveness 更适合判断的是:

  • 进程是否死锁
  • 主线程是否卡死
  • 内部事件循环是否停止
  • 应用是否进入无法自行恢复的坏状态

换句话说,只有在“重启比等待更有价值”的场景下,liveness 才应该失败。

四、Startup:保护慢启动服务别被误杀

很多 Java 服务、Spring Boot 服务、带大量缓存预热或数据加载的服务,启动时间本来就不短。

如果这时候直接上 liveness,容器还没来得及启动完成,就会被认为“不健康”,然后触发重启。最终出现一种很典型的现象:

  • Pod 一直在启动
  • 日志每次都差不多
  • 但永远过不了健康检查

Startup Probe 的意义,就是告诉 Kubernetes:

  • 这个应用现在还处在冷启动阶段
  • 在 startup 成功前,先不要按 liveness 的标准来判断它

这对 Java、搜索、分析、消息类组件尤其重要,因为它们经常存在:

  • 类加载慢
  • 配置初始化多
  • 本地缓存预热
  • 集群元数据同步

五、三个探针更实用的分工方式

如果用一句最容易记住的话来区分:

  • Readiness 看“能不能对外服务”
  • Liveness 看“是不是已经需要强制拉起”
  • Startup 看“是不是还在合理启动期”

一个更常见的实战组合是:

  1. 启动阶段由 Startup Probe 兜住慢启动窗口。
  2. 启动完成后由 Readiness Probe 控制流量接入和摘除。
  3. 只有在应用明显卡死或进入不可恢复状态时,才让 Liveness Probe 失败并触发重启。

六、线上最容易踩的几个坑

1. 一个接口同时给三个探针用

这样最省事,但职责混乱最严重。探针触发动作不同,判断条件也不该完全一样。

2. 把所有依赖都挂进 readiness

一旦某个非核心依赖偶发抖动,整个服务都会被摘流量,反而造成可用实例数快速下降。

3. 用 liveness 处理外部依赖故障

数据库短时不可用、MQ 短时超时,并不一定意味着应用进程坏了。此时频繁重启只会加剧雪崩。

4. 没给慢启动服务配置 startup

Java 项目、老系统、初始化较重的服务特别容易因此反复重启。

5. 探针阈值照抄模板

不同服务的启动时间、依赖复杂度、请求耗时差异很大,统一模板往往在测试环境正常,一上生产就暴露问题。

七、发布和排障时怎么用探针更稳

如果目标是让服务发布更平滑、排障更清晰,更建议这样设计:

  1. 把应用就绪判断和进程存活判断拆开。
  2. 对慢启动应用单独评估 cold start 时间,配置 startup 窗口。
  3. 把 readiness 和预热流程结合起来,例如缓存未热完先不接流量。
  4. 对 liveness 保守一些,只在真正卡死或内部核心循环异常时才失败。
  5. 上线前专门演练三种场景:慢启动、依赖抖动、线程卡死。

八、排查探针问题时的顺序

如果线上出现“实例反复摘流量”或“不断重启”,可以先按这个顺序看:

  1. 是 readiness 失败还是 liveness 失败,先分清触发源。
  2. 失败发生在启动期还是运行期。
  3. 探针检查的是应用自身状态,还是某个外部依赖。
  4. 探针阈值是否明显不符合当前启动耗时和运行耗时。
  5. 发布期间是否因为预热不足导致 readiness 过早成功。

很多时候问题不是 Kubernetes 有 bug,而是探针承载了本不属于它的职责。

一句话总结

探针的关键不在于配了几个字段,而在于职责边界是否清楚。Readiness 管流量,Liveness 管自愈,Startup 管慢启动保护。

把三者分工拆清后,服务发布会更平滑,异常定位会更直接,Kubernetes 也不再是“动不动就乱重启”的背锅对象。

延伸阅读相关文章优先当前专题,再补跨专题关联。
同一序列 · 回看前文会更完整Request、Limit、HPA 怎么配合容量治理适合把 Deployment、Service、ConfigMap、资源限制和探针放在一起看。Kubernetes 专题 · Kubernetes 核心对象与资源治理同一序列 · 回看前文会更完整ConfigMap、Secret、Volume 和环境变量怎么选适合把 Deployment、Service、ConfigMap、资源限制和探针放在一起看。Kubernetes 专题 · Kubernetes 核心对象与资源治理同专题其他序列 · 共享标签:部署交付节点污点、亲和性和拓扑 spread 怎么组合适合把命名空间、回滚、PDB、HPA、Mesh 和调度约束放在一条 Kubernetes 治理主线上整理。Kubernetes 专题 · Kubernetes 编排约束与交付治理同专题其他序列 · 共享标签:部署交付Deployment 回滚到底依赖了什么信息适合把命名空间、回滚、PDB、HPA、Mesh 和调度约束放在一条 Kubernetes 治理主线上整理。Kubernetes 专题 · Kubernetes 编排约束与交付治理跨专题关联 · 同场景:部署交付标签基数为什么会拖垮 Prometheus适合把 Prometheus、Grafana、标签治理和告警分级放在一起看。可观测性专题 · 指标与告警体系设计跨专题关联 · 同场景:部署交付多环境发布怎么设计:开发、测试、预发、生产不只是名字不同适合沿着流水线设计、自动部署、发布策略、数据库变更和多环境治理这条线往下读。CI/CD 与发布治理专题 · CI/CD 与发布治理
继续阅读Kubernetes 核心对象与资源治理当前序列第 4 篇 / 共 4 篇当前专题第 1 个序列 / 共 3 个序列
往前看
上一篇Request、Limit、HPA 怎么配合容量治理回到当前序列上一章上一序列Linux 网络与权限安全细节从第 1 篇开始:ss、netstat、lsof 怎么配合排查端口问题
往后看
下一序列Kubernetes 发布与排障主线从第 1 篇开始:Ingress、Service 和集群网络链路怎么串起来看

把零散经验整理成可查、可复用、可持续更新的企业级知识门户