健康检查探针在容器编排中扮演“守护哨兵”的角色它持续感知容器内部状态,在服务“假死”或启动未就绪时触发自动处置,是保障业务连续性的第一道防线。
健康检查探针有哪些类型
容器编排系统之所以能支撑大规模分布式应用,核心能力之一就是自愈,而自愈的前提,是编排系统能准确判断一个容器到底是“活着”还是“已经不行了”,这个判断动作,就由探针完成。
行业共识认为,探针本质上是kubelet定期执行的命令或请求,通过返回结果判断容器状态,目前主流的探针类型有三种,各自盯防不同阶段的故障。
- 存活探针(Liveness Probe):回答“容器还活着吗”,如果判定失败,kubelet会杀掉容器并重建,适用于检测死锁、内存溢出等无法自行恢复的致命错误。
- 就绪探针(Readiness Probe):回答“容器能接收流量了吗”,判定失败时,不会杀掉容器,而是将Pod从Service的后端列表中摘除,适用于处理依赖外部资源、启动较慢或过载的场景。
- 启动探针(Startup Probe):回答“应用启动过程是否完成”,启动探针成功之前,其他探针不会执行,适用于启动极慢的Java应用或需要加载大量模型的推理服务。
三者的协作逻辑是:启动探针先放行,存活探针保命,就绪探针控流量,缺少任何一环,容器编排的自愈能力都存在盲区。
存活探针和就绪探针区别
很多人初次接触探针时,容易混淆存活和就绪的区别,两者确实都通过HTTP请求、TCP连接或执行命令来判断状态,但失败后的动作完全不同,适用场景也差异明显。
| 对比维度 | 存活探针 | 就绪探针 |
|---|---|---|
| 核心目的 | 判断容器是否需重启 | 判断容器是否可服务 |
| 失败动作 | 杀掉容器,按策略重建 | 摘除流量入口,不杀容器 |
| 适用场景 | 死锁、内存泄漏、进程崩溃 | 启动依赖、瞬时过载、配置加载 |
| 配置建议 | 判定条件要严,避免误杀 | 判定条件要宽,避免流量抖动 |
用一个形象的比喻:存活探针是“急诊医生”,发现救不活就直接宣告死亡,让系统重新生一个;就绪探针是“前台接待”,客人来了先问一句“现在能接待吗”,不能就先请客人去别处。
实操中常见的错误是:只配置了存活探针而漏掉就绪探针,结果应用启动时端口已经监听成功,但内部业务线程还没准备好,流量涌进来直接报错,存活探针以为一切正常,就绪探针缺位,服务在“半死”状态下硬扛,反过来,只配就绪探针不配存活探针,容器内部已经死锁,但TCP端口依然能连上,就绪探针判定正常,流量持续被打进一个无法处理的容器。
就绪探针还有一个容易被忽略的作用配合滚动更新,新版本Pod启动后,只有就绪探针判定成功,才会继续更新后续Pod,如果新版本有启动故障,就绪探针一直不通过,更新会自动暂停,避免全量故障。
启动探针为何成为标配
早期Kubernetes版本只有存活和就绪两种探针,启动探针是后来引入的,它的出现,解决了一个实际痛点:部分应用启动时间超过存活探针的容忍上限。
比如一个Java应用,常规存活探针配置的initialDelaySeconds普遍在30秒到60秒之间,但遇到冷启动或高负载的Pod调度,应用启动可能需要两分钟以上,存活探针频繁触发误杀,Pod陷入“启动-被杀-再启动-再被杀”的死循环,社区里把这个现象叫作“CrashLoopBackOff”,排查起来非常耗时。
启动探针的引入改变了这个局面,它在启动期间独享判定权,启动探针未通过时,存活探针和就绪探针原地待命,你可以把initialDelaySeconds压缩到很小,periodSeconds设为10秒甚至更短,失败阈值调高到60次,这样无论应用启动多慢,只要启动探针还没判定失败,系统就不会轻举妄动。
具体配置示例:
startupProbe:
httpGet:
path: /health/startup
port: 8080
initialDelaySeconds: 0
periodSeconds: 10
failureThreshold: 30
这段配置允许启动探针最多探测30次,每次间隔10秒,总时长上限300秒,相比延长存活探针的初始延迟,启动探针的方式更可控、更精准。

容器健康检查失败怎么办
探针配置不当或应用自身问题,会导致健康检查失败,常见情况包括:应用依赖的数据库暂时不可用、内部线程池耗尽、磁盘空间占满但HTTP接口还能响应,以及探针路径配置错误返回了404。
排查容器健康检查失败问题,推荐按以下路径操作。
- 第一步,查看Pod事件,执行
kubectl describe pod,关注Events部分是否有“Liveness probe failed”或“Readiness probe failed”提示。 - 第二步,查看容器日志,执行
kubectl logs,结合探针失败的周期时间点,定位是逻辑异常还是资源不足。 - 第三步,手工验证探针路径,进入容器后使用
curl或wget请求探针URL,检查HTTP状态码是否与探针配置相符。 - 第四步,确认探针URL的鉴权情况,部分应用的健康检查接口无需鉴权,但开发环境加了拦截器,导致探针拿到的不是200。
从配置侧看,多数探针问题源于参数设置过于激进,例如failureThreshold设为1,只要有一次网络抖动就判定失败,Pod被频繁重启,建议结合实际监控数据调整参数,留出合理的抖动容忍度。
另一个容易踩坑的地方是探针使用的端口,如果应用监听的是8080端口,探针却配置为80端口,健康检查必然失败,在Kubernetes探针配置教程中,端口写错是高频问题,修改后务必观察一段时间再宣告修复完成。
探针配置最佳实践
探针配置不是越多越好,关键在于匹配业务特性,以下几条实践建议来自一线运维经验的总结,适用性较广。
- HTTP探针优先于TCP探针,TCP探针只能确认端口能连上,无法判断业务是否真正可用,HTTP探针可以配合业务自定义的检查逻辑,例如查询数据库连接池状态、检查缓存是否就绪。
- 检查接口设计要轻量,健康检查接口不应承担过重的业务逻辑,如果接口内部做了大量依赖检查,一个下游抖动就会导致全部Pod判定失败,引发流量雪崩。
- 就绪探针配合最小副本数,设置PodDisruptionBudget并保证最小可用副本数,避免滚动更新时流量被打断。
- 根据流量特征设置参数,高并发服务的就绪探针可以适当调大periodSeconds,降低探测频率对应用的性能消耗。
- 引入云原生容器部署实践时,探针与HPA结合使用,当就绪探针频繁失败时,结合HPA指标判断是容量问题还是代码问题,避免盲目扩容后仍然失败。

一个常见的业务场景是:凌晨流量高峰,缓存服务抖动,导致所有Pod的就绪探针同时失败,Service后端列表为空,前端全部超时,这类问题光靠调整探针参数解决不了,更合理的思路是给探针接口增加降级逻辑,例如缓存不可用时返回200但标记降级,让业务层自行熔断。
很多容器编排工具对比测试中,探针的实现方式也是差异化竞争的焦点,Kubernetes级别的探针方案已经标准化,而Docker Compose层面的healthcheck则更简单,两者定位不同,适用场景也不同,选择工具时,需要优先确认是否支持细粒度的探针控制。
健康检查探针的常见问题解答
问题:配置了存活探针后,容器频繁重启,如何定位是探针问题还是应用问题?
先调整探针配置,把failureThreshold临时调大,观察容器是否仍然重启,如果停止重启,基本可以确定是探针误判,再检查探针路径的响应时间,以及响应体是否符合预期,也可以临时移除存活探针,仅保留就绪探针,观察应用在无干预条件下能否稳定运行。
问题:就绪探针判定失败的Pod,流量真的不会打进去吗?
是的,就绪探针判定失败后,该Pod的IP会从Endpoints列表中移除,Service负载均衡不再转发流量到该Pod,但需要留意,如果使用Headless Service或者StatefulSet,服务发现行为有所不同,客户端需要自行处理探活逻辑。
问题:为什么不用TCP探针而是用HTTP探针?
TCP探针只能验证端口处于监听状态,无法感知应用层健康状况,一个叠加了业务逻辑的HTTP探针能反馈的信息量远大于TCP连接,对于核心业务,建议使用HTTP或gRPC探针,并在探针接口中暴露关键依赖的状态;对于边缘Pod或非关键服务,TCP探针已经足够。
