就绪探针(Readiness Probe)负责判断容器是否已经准备好接收外部流量,存活探针(Liveness Probe)负责判断容器是否还活着、要不要重启,二者的分工可以概括为:一个管“能不能接客”,一个管“该不该留命”。
就绪探针和存活探针的区别是什么:一个管接客,一个管续命
在Kubernetes里,Pod从启动到能正常处理请求往往有一段“暖机时间”,应用进程可能已经跑起来了,但数据库连接池还没建好、缓存还没加载完毕、或者配置文件还在解析,这个时候把流量打进去,用户看到的就是满屏报错。
就绪探针专门解决这个问题,它每隔一段时间去问容器:“你现在能干活了吗?”如果回答是“不能”,Kubernetes就会把这个Pod从Service的后端列表里摘掉,不让新流量进来,等它连续几次回答“能”,再把它加回流量池。
存活探针问的则是另一个问题:“你还活着吗?”一个容器进程可能并没有退出,但内部已经死锁、内存溢出、或者进入不可恢复的坏状态,存活探针一旦连续失败,kubelet会直接杀掉容器并重启,尝试让应用自愈。
用餐厅来打比方:就绪探针像领班在门口检查服务员是否换好工装、记住今日菜单,没准备好就暂时不让他上桌服务;存活探针像每日健康检查,发现员工突然晕倒失去工作能力,就得赶紧送医抢救,而不是让他继续站在餐桌旁。
两者虽然都叫探针,但失败后的动作完全不同,这也是最容易混淆的地方。
| 对比维度 | 就绪探针 | 存活探针 |
|---|---|---|
| 核心关注 | 容器是否准备好接收流量 | 容器进程是否健康存活 |
| 失败后果 | 从Service后端摘除,不重启 | 容器被重启 |
| 典型场景 | 启动预热、依赖未就绪、临时过载 | 死锁、内存泄漏、不可恢复故障 |
| 影响范围 | 只影响流量分发 | 影响容器生命周期 |
| 成功阈值 | 通常1次成功即恢复 | 通常1次失败即触发重启 |
行业共识认为,把两者混用或者只配置存活探针不配置就绪探针,是造成滚动更新期间大量502错误的常见原因。
Kubernetes就绪探针怎么配置才不会被误判
配置就绪探针并不复杂,但参数调优需要结合应用真实启动行为,Kubernetes支持三种检查方式:httpGet、tcpSocket、exec,前两种最常用。
一个典型的HTTP就绪探针配置如下:
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 2
successThreshold: 1
failureThreshold: 3
各参数含义很直观:
initialDelaySeconds:容器启动后等多久才开始第一次检查,Java应用启动慢,可以设到20-30秒;Go或Node应用通常5-10秒足够。periodSeconds:每隔几秒检查一次,默认10秒,生产环境常用5秒以加快摘除速度。timeoutSeconds:单次检查多久没响应算失败,建议2-3秒,避免探针本身卡住。successThreshold:连续几次成功才认为就绪,默认1次即可。failureThreshold:连续几次失败才判定为不就绪,默认3次,太少会导致网络抖动就摘流量,太多则故障响应变慢。
实操建议:就绪探针的检查端点不要和存活探针共用同一个路径,就绪端点应该返回应用是否完成预热、内部队列是否可接收请求;存活端点应该返回进程内部是否死锁,两个逻辑写在一个接口里,很容易因为外部依赖抖动同时触发摘流量和重启。
据CNCF公开资料,相当一部分生产事故并非探针本身写错,而是initialDelaySeconds设得太短,容器还没起来就被连续判定失败,导致滚动更新时新版本永远无法进入就绪状态。
就绪探针失败会导致什么后果?线上滚动更新踩坑场景
先看一个最常见的滚动更新事故现场。
假设你有一个Deployment,副本数3个,没有配置就绪探针,或者就绪探针参数过于宽松,你执行kubectl apply发布新版本,新Pod启动需要20秒,但旧Pod在更新过程中已经被逐步终止,此时Service后端列表里可能一个就绪副本都没有,接口瞬时全量502。
如果正确配置了就绪探针,新Pod在未通过检查前不会被加入Service,旧Pod也不会被提前全部摘除,流量会平滑过渡。
另一个容易忽略的场景是就绪探针依赖外部服务,比如你把数据库连接检查写进/health/ready
接口,数据库发生短时抖动,所有Pod的就绪探针同时失败,全部从Service摘除,此时外部流量进不来,数据库失去部分请求压力后可能更快恢复,但你的服务已经在用户侧表现为完全不可用。
所以就绪探针的检查逻辑应该只判断进程自身是否具备处理请求的能力,不要引入强外部依赖,如果确实需要检查数据库,可以做成非必需组件,失败时降级处理而不是直接返回不就绪。
- 常见失误:没有就绪探针,流量打到未预热实例。
- 常见失误:就绪探针失败后没有告警,Pod长时间处于未就绪状态。
- 常见失误:
failureThreshold设为1,网络抖动频繁摘除Pod造成流量颠簸。 - 常见失误:就绪探针路径返回200但内部队列已满,实际无法处理请求。
存活探针的职责边界:它为什么不负责导流
很多团队习惯把存活探针当成“万能健康检查”,让它去探测数据库、Redis、下游API,结果数据库一抖,存活探针失败,kubelet开始重启所有Pod,重启期间服务完全中断,反而放大了故障。
业内专家指出,存活探针的唯一职责是回答“这个进程还有没有恢复的可能”,如果应用内部死锁、内存堆爆掉、无法响应用户请求且不可能自行恢复,重启是合理的选择,而外部依赖故障大多数情况下是暂时的,只要依赖恢复,应用进程自己就能恢复服务能力,不需要重启。
存活探针更适合用轻量级检查:
- 检查进程内部一个简单的HTTP端点,返回200即可。
- 使用
exec执行一条内部命令,验证核心线程没有死锁。 - 使用
tcpSocket检查容器主端口是否还在监听。
如果存活探针和就绪探针都检查同一个外部数据库,数据库抖动时会发生什么?存活探针把容器重启了,就绪探针把Pod摘除了,两套机制叠加,恢复时间反而更长。
分工清晰的做法:就绪探针可以短时检查依赖,失败时摘流量但保留容器运行;存活探针只检查进程内部健康,失败时重启容器,两者各管一段,不越界。
国内云服务器部署就绪探针的注意事项与成本说明
国内云服务器上的Kubernetes集群,比如简米云ACK、酷番云TKE、华为云CCE,都已经原生支持就绪探针和存活探针,就绪探针本身
不产生单独价格,不需要额外购买监控服务,费用来自Pod占用的CPU、内存,以及探针请求产生的少量内网流量,在华东地域或华北地域的托管集群中,这部分开销通常可以忽略不计。
国内环境部署时有三个实际注意事项:
- 健康检查端点用内网地址,不要把数据库、Redis之类的检查请求发到公网域名,跨地域走公网延迟高,容易导致就绪探针超时,尤其在华北地域访问华南地域数据库时特别明显。
- tcpSocket比httpGet更省资源,如果只是检查端口是否监听,用
tcpSocket可以减少HTTP握手开销,适合带宽紧张的小规格云服务器。 - 避免与云负载均衡健康检查重复,云厂商的负载均衡器通常自带健康检查,如果Pod内又配置了相同路径的就绪探针,可能出现双重检查逻辑冲突,建议云LB检查TCP端口,Pod内就绪探针检查具体业务就绪状态。
配置示例:
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
这种配置在国内云服务器上运行稳定,不会因为HTTP检查路径写错导致Pod永远不就绪。
Q&A:就绪探针和存活探针的常见疑问
就绪探针和存活探针可以共用同一个检查项吗?
可以但不推荐,共用同一个路径会让摘流量和重启两个动作绑定在一起,检查项失败时,Pod既被移出Service,又可能被重启,重启期间服务完全断开,等恢复后又需要重新预热,就绪探针和存活探针分开配置,逻辑各自独立,故障恢复更快,误判范围更小。
就绪探针失败会自动重启容器吗?
不会,就绪探针失败只做一件事:把Pod从Service的endpoints列表里移除,外部流量不再进入,容器本身继续运行,直到存活探针失败或进程主动退出,这是两者最核心的机制差异,很多人以为就绪探针失败会重启容器,实际是存活探针才触发重启。
国内云服务器部署就绪探针价格贵吗?
就绪探针是Kubernetes原生能力,国内主流云厂商的托管集群不会单独收取探针检查费用,实际成本来自Pod占用的CPU和内存,以及探针请求产生的少量内网流量,在华东、华北地域的容器服务中,这部分开销通常可忽略,不需要单独做预算。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/640559.html





