目录
[五、为什么需要 Startup,Liveness 不能替代](#五、为什么需要 Startup,Liveness 不能替代)
一、引言:为什么需要探针
在 Kubernetes 中,"进程在运行"不等于"服务可用" 。容器可能处于死锁、假死、依赖未就绪等状态,进程看似存活却无法正确处理请求。K8s 通过探针对 Pod 进行健康检查,并根据结果自动采取重启或摘流等动作,从而提升应用可用性 。
K8s 提供三种探针:Startup(启动)、Liveness(存活)、Readiness(就绪)。
二、三种探针的定位
|--------------------|-----------|-------------------------------------|
| 探针 | 回答的问题 | 失败后果 |
| StartupProbe | 应用启动完成了吗 | 杀容器并按重启策略重启 |
| LivenessProbe | 进程是否卡死/假死 | 杀容器并按重启策略重启 |
| ReadinessProbe | 现在能否接收流量 | 从 Service Endpoints 摘除、停止导流,不重启 |
- Liveness:kubelet 用它判断何时重启容器,可捕获死锁等不可恢复故障 。
- Readiness:kubelet 用它判断容器何时准备好接收请求流量;Pod Ready 为 true 时才作为 Service 后端,未就绪则被从负载均衡剔除 。
- Startup:kubelet 用它了解应用何时启动完成,专用于保护慢启动容器,避免其在启动完成前被误杀 。
三、执行顺序与协作关系
三者共存时存在明确的先后关系:Startup 先行,Liveness 与 Readiness 被暂时禁用;Startup 成功一次后,另两者才同时启用并行探测 。
容器启动
└─ StartupProbe 循环探测(期间 Liveness/Readiness 禁用)
├─ 超阈值仍失败 → 杀容器重启
└─ 成功一次 → Startup"退休",停止探测
→ Liveness + Readiness 并行探测直到容器消亡
├─ Liveness 失败 → 重启
└─ Readiness 失败 → 摘流量 / 成功 → 接流量
关键差异:Startup 成功一次即停止探测,而 Readiness/Liveness 在容器整个生命周期内持续运行 。若未配置 Startup,其默认状态为成功 。
四、共同参数与探测方法
三种探针均支持 exec、httpGet、tcpSocket(及 grpc)探测方式,并共用以下参数 :
|-----------------------|----------|---------------------------------|
| 参数 | 默认值 | 说明 |
| initialDelaySeconds | 0 | 容器启动后首次探测的等待秒数 |
| periodSeconds | 10(最小 1) | 探测频率 |
| timeoutSeconds | 1(最小 1) | 探测超时时间 |
| successThreshold | 1 | 失败后需连续成功多少次才算成功(Liveness 必须为 1) |
| failureThreshold | 3(最小 1) | 成功后需连续失败多少次才算失败 |
探测结果有三种:Success(通过)、Failure(未通过)、Unknown(未执行,不采取行动) 。
五、为什么需要 Startup,Liveness 不能替代
这是最常见的疑问。核心在于:Liveness 是稳态,Startup 是启动期,两者服务不同阶段。
对慢启动应用(如 Java 应用,启动耗时数十秒到十几分钟且波动大),若只用 Liveness:
- initialDelay 设小 :启动未完成就开始探测 → 连续失败 → 被杀重启 → 再次慢启动 → 无限重启循环;
- initialDelay 设大:每次重启后都有一段长"盲窗",真实卡死无法被及时发现,且固定值难以适配波动的启动时长。
Startup 用 failureThreshold × periodSeconds 提供自适应启动窗口 :启动快则提前结束探测,启动慢则用满窗口;启动一完成,Liveness 立即以严格参数接管,实现卡死秒级发现 。因此,慢启动应用应使用 StartupProbe 。
六、配置示例
probes:
startupProbe: # 保护慢启动,成功即退休
httpGet: {path: /healthz, port: 8080}
periodSeconds: 10
failureThreshold: 90 # 90×10s = 15 分钟启动窗口
livenessProbe: # 保活底线:失败=重启
httpGet: {path: /healthz, port: 8080}
periodSeconds: 10
failureThreshold: 3
readinessProbe: # 流量门槛:失败=摘流量
httpGet: {path: /ready, port: 8080}
periodSeconds: 5
failureThreshold: 3
七、常见陷阱
- 谨慎配置 Liveness:它应真正标示不可恢复故障(如死锁);错误配置可能引发级联故障------高负载下容器被重启,剩余 Pod 负载加重,进一步失败 。
- Liveness 与 Readiness 勿用完全相同的规范 :可复用同一健康端点,但 Liveness 应设置更高的
failureThreshold(如 Readiness 3 次、Liveness 10 次),确保硬性终止前已观察到一段时间的非就绪 。 - 探针保持轻量高效:探针命令/接口应高效、不依赖外部服务,避免探针本身拖累性能 。
- 谨慎设置失败阈值:防止临时抖动导致频繁重启 。
- 监控探针事件 :通过
kubectl describe pod及时发现探针异常 。 - 注意作用范围:Liveness 影响单个容器;Readiness 影响整个 Pod------多容器 Pod 中任一容器未就绪,整个 Pod 即为未就绪 。
- Liveness 失败不一定重启 :是否重启由
restartPolicy决定 。
八、总结
|-----------|-------|---------|------|
| 探针 | 管什么 | 探测持续期 | 失败代价 |
| Startup | 能否启动 | 成功一次即退休 | 重启 |
| Liveness | 要不要重启 | 探到容器消亡 | 重启 |
| Readiness | 接不接流量 | 探到容器消亡 | 仅摘流量 |
一句话概括:Startup 护航启动、Liveness 监护存活、Readiness 把关流量;三者共存时 Startup 先行、另两者禁用,启动完成后并行接管。