4、存活探针(Liveness Probe)原理:探针类型、探测机制、失败后果
大家好,我是你们的老朋友。今天我们来聊聊存活探针。
说白了,存活探针就是K8s用来判断容器是否「活着」的手段。如果容器挂了,K8s就把它重启。嗯,就这么简单。但实际用起来,坑可不少。
4.1 探针的三种类型
K8s提供了三种探测方式。我一个个说。
4.1.1 HTTP探针
最常用的一种。K8s向容器内的某个HTTP端点发请求,如果返回200-399状态码,就算成功。
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 5
我个人习惯用/healthz这个路径。为什么?因为很多框架默认支持,而且语义清晰。我在项目中遇到过一个问题:有个同事把健康检查路径写成了/,结果首页稍微慢一点,探针就超时了,容器被反复重启。嗯,这里要注意:健康检查端点一定要轻量,别查数据库,别查外部依赖。
4.1.2 TCP探针
如果容器没有HTTP服务,比如只暴露了gRPC端口,那就用TCP探针。K8s尝试建立TCP连接,能连上就算活着。
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
你想想看,TCP探针只能检查端口是否在监听。但端口开着不代表服务正常。我曾经遇到一个情况:gRPC服务死锁了,端口还开着,但已经不处理请求了。TCP探针完全没发现,直到用户报障。所以,能用HTTP尽量用HTTP。
4.1.3 Exec探针
最灵活的一种。K8s在容器内执行一条命令,返回码为0就算成功。
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
Exec探针适合那些没有HTTP接口的旧应用。但要注意:命令执行本身有开销。我见过有人用curl命令做健康检查,每次启动一个进程,对高并发容器来说压力不小。建议用内置的脚本或者二进制工具。
4.2 探测机制详解
K8s的探测机制其实就三个参数:
| 参数 | 含义 | 默认值 |
|---|---|---|
| initialDelaySeconds | 容器启动后多久开始探测 | 0 |
| periodSeconds | 每次探测的间隔 | 10 |
| timeoutSeconds | 单次探测超时时间 | 1 |
| successThreshold | 连续成功几次才算健康 | 1 |
| failureThreshold | 连续失败几次才算不健康 | 3 |
这里有个容易踩的坑:timeoutSeconds默认只有1秒。如果你的健康检查端点需要2秒才能返回,那每次都会超时。我曾经调试过一个vLLM服务,加载模型时响应慢,探针一直超时,容器被反复重启。后来我把timeoutSeconds调到了5秒,问题解决。
核心逻辑流程图
4.3 失败后果
探针失败后,K8s会怎么做?
- 单次失败:只是记录一下,不影响。K8s会继续探测。
- 连续失败达到failureThreshold:K8s认为容器不健康,执行重启策略。
- 重启策略:默认是
Always,也就是总是重启。如果Pod设置了restartPolicy: Never,那Pod会进入CrashLoopBackOff状态。
⚠️ 重要警告
我曾经见过一个生产事故:某团队把存活探针的failureThreshold设成了1,结果网络抖动了一下,所有Pod同时被重启,服务完全不可用。建议failureThreshold至少设为3,给网络波动留点缓冲。
4.4 实战避坑指南
最后分享几个我踩过的坑:
- 探针不要依赖外部服务:如果健康检查里调了数据库,数据库挂了,你的容器也会被重启。这其实是级联故障。
- initialDelaySeconds要合理:vLLM加载模型可能需要几十秒,如果设得太短,容器还没启动就被重启了。
- 不要用存活探针做就绪判断:存活探针只管「死没死」,就绪探针才管「能不能干活」。别混用。
💡 我的个人习惯
对于vLLM这类推理服务,我一般这样配:
- 存活探针:HTTP GET /health,超时5秒,间隔10秒,失败阈值3
- 就绪探针:HTTP GET /ready,超时5秒,间隔5秒,失败阈值1
这样既保证了快速发现死锁,又避免了网络抖动导致的误杀。
好了,存活探针就聊到这里。记住一句话:探针是K8s的「眼睛」,但别让它变成「瞎指挥」。