深色模式
健康检查三大探针 Liveness/Readiness/Startup
摘要:本文面向生产 SRE,厘清 Liveness、Readiness、Startup 三种探针的设计意图与边界,给出参数调优、失败模式与排障清单。覆盖 Kubernetes v1.28+(gRPC 探针 v1.27 稳定)。
适用版本与前提
- Kubernetes:v1.28+(gRPC 探针自 v1.27 稳定;exec 探针超时受
ExecProbeTimeout影响) - 工具:
kubectl - 前提:已理解 Pod 生命周期(见《Pod 生命周期与重启策略》)
背景与问题
一个“进程在跑”的容器,不等于“服务可用”。Kubernetes 用三种探针把存活(能否继续服务)、就绪(能否接收流量)、启动(是否完成冷启动) 三个维度解耦。把它们配错(最常见的是用 Liveness 当 Readiness 用)会直接导致雪崩式故障:应用临时卡顿触发 Liveness 杀容器,杀容器又引发请求失败,进而引发更多重启。
三种探针的语义
| 探针 | 回答的问题 | 失败后果 | 典型用途 |
|---|---|---|---|
livenessProbe | 容器还活着吗? | kubelet 重启该容器 | 检测死锁、挂死 |
readinessProbe | 容器准备好接流量了吗? | 从 Service 端点摘除,不重启 | 依赖未就绪、过载降级 |
startupProbe | 应用启动完成了吗? | 启动期内失败则重启;启动完成后移交 Liveness | 保护慢启动应用 |
关键区别:Readiness 失败不重启容器,只从负载均衡中摘除;Liveness 失败一定重启。
注意
不要用 Liveness 检测“依赖是否就绪”。若数据库短暂不可用就让 Liveness 失败,kubelet 会反复杀掉本可自愈的容器。依赖就绪应只放在 Readiness 中。这是生产中最常见的探针误配。
探针机制
三种探针都支持四种检测机制:
exec:在容器内执行命令,返回 0 成功,非 0 失败。httpGet:对容器 IP:port 发 HTTP GET,[200,400)视为成功。tcpSocket:尝试建立 TCP 连接,能连上即成功(不验证应用层)。grpc:gRPC Health Checking Protocol(v1.27 稳定)。
版本相关
gRPC 探针自 v1.27 稳定。HTTP 探针在 v1.13+ 不受本地 HTTP 代理环境变量影响。h2c / gRPC over TLS 探针为 Alpha(v1.37 起,需特性门控),生产非默认开启。
通用参数
yaml
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10 # 容器启动后首次探测延迟
periodSeconds: 10 # 探测周期
timeoutSeconds: 1 # 单次探测超时
successThreshold: 1 # 连续成功几次算健康(默认1,Liveness/Startup必须为1)
failureThreshold: 3 # 连续失败几次判定失败1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
参数语义与取舍:
initialDelaySeconds过短会在应用未就绪时误杀;过长则故障发现慢。引入startupProbe后可把它设小。failureThreshold × periodSeconds决定从异常到动作的总延迟。Liveness 太敏感(如 1×1s)会放大抖动;太迟钝(如 10×30s)则故障发现慢。- Readiness 建议用较短
periodSeconds(如 5–10s)以便快速摘除/恢复。
完整示例:三者配合
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 8080
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30
periodSeconds: 5 # 最多允许 150s 冷启动
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 2
periodSeconds: 5
timeoutSeconds: 1
failureThreshold: 31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Startup 探针的价值
慢启动应用(JVM、大模型加载、大缓存预热)在启动期间 Liveness 会频繁失败。传统做法是把 initialDelaySeconds 设得很大,但这拖慢了真正死锁的发现。Startup 探针在启动阶段“屏蔽”Liveness/Readiness,启动成功后才交由 Liveness 接管,是官方推荐模式。
生产实践
- Readiness 必配:无 Readiness 的 Deployment,Pod 一旦
Running就被打入 Service,滚动更新期间可能把未就绪实例暴露给流量。 - Readiness 反映真实依赖:数据库连接池耗尽、下游超时,应反映在 Readiness,让流量自动避开,而非靠 Liveness 杀进程。
- Liveness 只检测“不可自愈”状态:如死锁、端口彻底不响应。检测逻辑要轻量,避免成为瓶颈。
- gRPC 服务用 gRPC 探针:比 tcpSocket 更能反映应用层健康。
- 探针端点独立且轻量:避免探针触发重计算或全局锁。
生产危险
failureThreshold 过小 + Liveness 检测重 IO,会在 GC 停顿或瞬时高负载时误杀容器,引发连锁重启。对延迟敏感服务,务必给探针留出 timeoutSeconds 与合理的 failureThreshold。
故障排查
| 现象 | 原因 | 排查 |
|---|---|---|
Pod Running 但 0/1 Ready | Readiness 失败 | kubectl describe pod 看 Unhealthy 事件;检查 /ready 逻辑 |
频繁 CrashLoopBackOff | Liveness 失败重启 | kubectl logs + 事件;检查 /healthz 是否随依赖失败 |
| 滚动更新卡住 | 新副本 Readiness 一直不通过 | 检查就绪端点、资源、依赖 |
| 启动即被重启 | Startup 阈值不足 | 增大 failureThreshold × periodSeconds |
常见坑
- Liveness 与 Readiness 指向同一端点且都检测依赖:依赖抖动会同时杀容器并摘流量,放大故障。
exec探针命令依赖容器内有该二进制:精简镜像(distroless)可能缺少cat、sh,导致探针永远失败。- 探针超时默认 1s 在跨网络/慢存储下过短:需显式调大
timeoutSeconds。
替代方案与权衡
- 对于更精细的流量治理(如按错误率熔断),可结合 Service Mesh(Istio/Linkerd)的熔断能力,探针仍负责“进程级”健康。
- 外部黑盒探测(如 Blackbox Exporter)可补充“从集群外看服务”的视角,但无法替代 kubelet 的内部探针。
FAQ
Q:Readiness 失败会重启 Pod 吗? A:不会。Readiness 只控制是否进入 Service 端点。只有 Liveness 失败才会触发容器重启。
Q:Startup 探针和 Readiness 能同时配吗? A:可以且推荐。Startup 通过前,Liveness/Readiness 不会生效;通过后三者并行工作。
参考资料
- Configure Liveness, Readiness and Startup Probes - Kubernetes 官方文档,访问日期:2026-10-08。
- Container Probes 概念 - Kubernetes 官方文档,访问日期:2026-10-08。
- Sidecar Containers(含探针说明)- Kubernetes 官方文档,访问日期:2026-10-08。