就绪探针管流量,存活探针管容器生命周期,就绪探针失败时,Pod会从Service的Endpoints中摘除;存活探针失败时,kubelet会杀掉容器并按策略重启。
在Kubernetes生产环境里,这两个探针是最常用的健康检查组合,很多初次接触的人会把它们混为一谈,因为它们都在做“告诉kubelet当前Pod健康状况”这件事,一旦分工理解错位,滚动发布时要么流量提前打到未就绪的Pod上,要么容器被反复重启却没人知道根因,把这两个探针看成两种角色,一个管门禁,一个管急救,思路就顺了。
就绪探针和存活探针的区别到底是什么
两者的探针类型完全一样,都可以用HTTP请求、TCP连接或执行命令来检测,差异体现在检测通过或失败之后,“接下来发生什么”完全不同。
检查目标与失败动作的差异
就绪探针回答的是“这个Pod现在能不能接收请求”,它关注业务层面的可用性,存活探针回答的是“这个进程还活没活着”,它关注容器底层的存活性。
| 对比维度 | 就绪探针(readinessProbe) | 存活探针(livenessProbe) |
|---|---|---|
| 检查目标 | 业务是否准备好处理流量 | 进程是否处于存活状态 |
| 失败动作 | 将Pod从Service的Endpoints中摘除 | kubelet杀掉容器并重建 |
| 影响范围 | Service流量路由、滚动更新节奏 | Pod生命周期、容器重启次数 |
| Pod状态表现 | 保持Running,但Ready状态变为False | 容器可能反复重启,RESTARTS计数持续增长 |
就绪探针失败,Pod还在跑,只是“没人给它派活”,存活探针失败,Pod会被直接处理掉,重新拉起来一个。
与启动探针的分工
除了这两个探针,Kubernetes还有第三个探针叫startupProbe,专门处理容器启动慢的场景,行业共识认为,三者的分工是:startupProbe管启动过程,livenessProbe管运行存活,readinessProbe管流量就绪,启动很慢的应用如果让存活探针过早介入,容器刚启动几秒就被误杀,因此startupProbe的探测周期和失败阈值要覆盖整个启动窗口,启动探针通过后,存活探针才开始接管,这个顺序在配置时要注意。

存活探针的工作机制与触发逻辑
存活探针的逻辑非常直接:探测失败达到阈值,就杀掉容器,这层保护是兜底的,防止进程死锁、死循环或内部状态异常时还继续占用资源。
一个典型的存活探针配置
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
successThreshold: 1
参数含义:
- initialDelaySeconds:容器启动后等多久才开始第一次探测,给业务留出初始化时间。
- periodSeconds:两次探测之间的间隔,单位秒。
- timeoutSeconds:单次探测的超时时间,超过即算本次失败。
- failureThreshold:连续失败多少次才触发重启动作。
- successThreshold:连续成功多少次才把探针标记为健康,默认1。
上面的配置表示:容器启动10秒后开始探测,每10秒请求一次/healthz,连续3次失败就重启容器。
三种探测方式的判定标准
- HTTP探针:向指定路径发起GET请求,返回状态码在200到399之间算通过,返回4xx或5xx都算失败。
- TCP探针:尝试与指定端口建立TCP连接,能连上算成功,连接失败算失败。
- exec探针:在容器内执行一条命令,退出码为0算成功,其他退出码都算失败。
容器重启的判定路径
当存活探针连续失败达到阈值,kubelet会杀掉容器,然后根据Pod的restartPolicy重建容器,如果restartPolicy是Always或OnFailure,容器就会被重新拉起,反复失败就会出现CrashLoopBackOff状态,执行kubectl get pods查看RESTARTS列,数字持续上涨,通常就是存活探针在起作用。
k8s就绪探针配置示例与流量摘除逻辑
就绪探针的配置结构和存活探针几乎一样,区别在于它的失败动作不涉及容器生命周期,只影响流量调度。
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 3
successThreshold: 1
这套配置的含义是:容器启动3秒后,每5秒请求一次/ready接口,连续3次失败就把该Pod从Service的后端列表中摘除,注意,Pod本身不会重启,只是暂时不接收新流量。

验证就绪探针摘除流量
想要直观看到摘除过程,可以按下面的步骤操作:
- 执行
kubectl get endpoints <service-name>,记录当前Endpoints中列出的Pod地址。 - 让/ready接口返回500状态码,模拟业务不可用。
- 等待periodSeconds乘以failureThreshold的时间后,再次执行
kubectl get endpoints <service-name>。 - 该Pod的地址从列表中消失,但
kubectl get pods显示Pod状态仍是Running,RESTARTS列没有明显增长。
这说明就绪探针只切流量,不动容器,在新版Kubernetes中,Endpoints背后由EndpointSlice承载,但查询方式与判定逻辑保持一致。
滚动更新时的就绪保护
滚动更新场景里,就绪探针的价值更明显,新版本Pod启动后,ready接口一直不通过,Deployment会暂停滚动,旧版本Pod继续负责流量,直到新Pod的就绪探针通过,才会被纳入Endpoints,随后继续推进更新节奏,没有就绪探针的服务,新Pod一启动就会被分配流量,业务还没监听端口,请求就会连接失败。
就绪探针失败会重启容器吗
不会,这是最容易混淆的点,就绪探针失败只会影响Service的流量调度,kubelet不会重启容器,Pod的Phase状态也不会改变,多数情况下,Pod继续Running,只是Ready状态变成False,只有配置了相同路径的存活探针,容器才会被重启,这两个探针的失败动作完全不同,排查问题时先区分是流量断了还是容器在反复重启,能快速定位到底哪一层出了问题。
探针参数调优与常见故障排查
探针参数没有万能模板,需要根据业务接口的实际响应速度来设定,常见做法是观察业务启动时间和接口P99耗时,再决定initialDelaySeconds和timeoutSeconds的数值。
参数设计的建议
- 就绪探针的periodSeconds可以比存活探针设得更短,比如5秒一次,加快流量接入速度。
- timeoutSeconds要留出余量,接口偶发耗时较长时,给2到3秒的缓冲,避免误判。
- startupProbe的failureThreshold乘以periodSeconds要大于业务真实启动时间,至少留出20%的余量。
- 存活探针的failureThreshold别设太激进,连续1次失败就重启容器,容易在GC暂停或网络抖动时误杀实例。

常见的探针配置故障
- 探针接口里检了数据库连接,数据库一抖动,探针全部失败,流量和容器双双被处理,故障被放大成雪崩。
- 就绪探针和存活探针指向同一个接口,接口响应变慢时,存活探针先触发,容器被直接杀掉,就绪探针还没来得及摘流量。
- 探针端口写错或业务监听地址是127.0.0.1,导致探针永远连不上,容器反复重启或一直不Ready。
业内专家指出,探针接口应该保持轻量,只检查进程状态和核心依赖,避免在健康检查路径里加入重计算或外部服务调用,否则探针自身就会成为故障放大器,即使是国内云厂商提供的托管集群,探针的判定也完全在kubelet侧完成,控制面只记录事件,不做额外干预,排查时多利用kubectl describe pod查看Liveness和Readiness字段下的探测参数,再结合kubectl get events看具体的失败原因,比瞎猜更快。
就绪探针与存活探针的分工问题解答
就绪探针失败会重启容器吗
不会,就绪探针失败后,容器保持运行状态,只是从Service的Endpoints中移除,如果看到容器RESTARTS在涨,那是存活探针或其他原因导致的,跟就绪探针没有直接关系。
存活探针和就绪探针可以配置同一个接口吗
可以,但不推荐使用完全相同的参数,同一个接口变慢时,存活探针可能比就绪探针先达到failureThreshold,容器还没被摘流量就被杀掉了,保守做法是让就绪探针的探测频率更高、threshold更敏感,存活探针的阈值放宽一些,给摘流量留出时间。
为什么配置了就绪探针,集群内部访问还是不通
如果请求是直接访问Pod IP,就绪探针的摘除逻辑不生效,它只控制Service的Endpoints登记状态,只有通过Service或Ingress进入的流量才会经过后端过滤,确认访问路径是经过Service的,再看kubectl get endpoints里有没有可用的Pod地址,就能定位是路由问题还是就绪状态问题。
把就绪探针、存活探针和启动探针放在一起,就是一套完整的云原生健康检查方案。就绪探针决定流量能不能进,存活探针决定容器能不能留,两者各管一摊,配合使用才能让发布和故障处理都干净利落。