Kubernetes 探针全解析:启动探针、存活探针与就绪探针(Startup/Liveness/Readiness Probe)

文章目录
- [Kubernetes 探针全解析:启动探针、存活探针与就绪探针(Startup/Liveness/Readiness Probe)](#Kubernetes 探针全解析:启动探针、存活探针与就绪探针(Startup/Liveness/Readiness Probe))
-
- 一、为什么需要三种探针?
- 二、启动探针:确保应用"成功起跑"
- 三、存活探针:判断应用"是死是活"
- 四、就绪探针:决定应用"能否接客"
- 五、三种探针对比
- 六、探针的检查方式
-
- [1. `httpGet`](#1.
httpGet) - [2. `tcpSocket`](#2.
tcpSocket) - [3. `exec`](#3.
exec)
- [1. `httpGet`](#1.
- 七、关键参数
- 八、配置示例
- 九、最佳实践
-
- [1. 慢启动应用优先使用启动探针](#1. 慢启动应用优先使用启动探针)
- [2. 存活探针与就绪探针保持独立](#2. 存活探针与就绪探针保持独立)
- [3. 存活探针要"迟钝"一些](#3. 存活探针要“迟钝”一些)
- [4. 就绪探针要能反映依赖和负载状态](#4. 就绪探针要能反映依赖和负载状态)
- [5. 谨慎使用 `exec` 探针](#5. 谨慎使用
exec探针) - [6. 不要忽略超时和阈值](#6. 不要忽略超时和阈值)
- 十、总结
在 Kubernetes 中,Pod 里的容器"跑起来"并不等于"能对外服务",更不等于"永远健康"。为了更精细地管理容器生命周期和流量,kubelet 提供了三种探针:
- 启动探针(Startup Probe):保护慢启动应用
- 存活探针(Liveness Probe):判断容器是否还活着
- 就绪探针(Readiness Probe):判断容器能否接收流量
三者看似相似,职责却完全不同。配置得当,可以显著提升应用可用性;配置不当,则可能引发频繁重启、流量抖动甚至级联故障。本文将从作用、失败后果、检查方式、关键参数和最佳实践几个方面,系统梳理 Kubernetes 中的三类探针。

一、为什么需要三种探针?
在实际生产环境中,应用通常会经历几个阶段:
- 启动阶段:加载配置、预热缓存、建立数据库连接,耗时可能很长;
- 运行阶段:进程正常处理请求;
- 异常阶段:进程还在,但已经死锁或无法处理请求;
- 暂时不可用阶段:依赖服务抖动、过载,短时间内不适合接收新流量。
如果只用一种探针,很难同时覆盖这些场景。例如:
- 用存活探针保护慢启动应用,可能导致应用还没启动完就被反复重启;
- 用就绪探针判断是否重启,又无法处理死锁这类"进程活着但不可用"的问题;
- 应用暂时过载时直接重启容器,可能让问题进一步恶化。
因此,Kubernetes 将"是否启动完成""是否还活着""是否能接流量"拆分成三种独立探针,分别处理。
适用边界提示 :本文以对外提供请求的 Web 应用为主要讨论对象。若 Pod 运行的是定时任务、Job 类控制台程序,通常没有 Service 入站流量,"就绪探针是流量开关"的语义并不直接适用;启动探针和存活探针仍可用于进程级健康检查,但它们不能解决"旧 Pod 被销毁时,正在执行的任务被中断"的问题。此类场景还需要在应用层处理
SIGTERM、停止调度新任务,并对当前任务做等待收尾、保存 checkpoint 或幂等重试,K8s 宽限期只应作为兜底,而不是主要依赖。
二、启动探针:确保应用"成功起跑"
启动探针用于检查容器内的应用是否已经完成启动。
核心作用
启动探针主要保护启动缓慢的应用。在启动探针成功之前,Kubernetes 会禁用存活探针和就绪探针,避免它们在应用初始化期间误判,导致容器被错误重启或流量被过早摘除。
运行特点
- 仅在容器启动阶段执行;
- 一旦成功,启动探针不再运行;
- 成功后,存活探针和就绪探针开始正常工作。
失败后果
如果启动探针在配置的容忍次数内仍未成功,kubelet 会杀死该容器,并根据 Pod 的重启策略进行处理。
适用场景
适合启动时间较长或不确定的应用,例如:
- 需要加载大量数据的 Java 应用;
- 需要建立大量外部连接的服务;
- 启动时需要执行复杂初始化的单体应用。
对于这类应用,使用启动探针通常比给存活探针设置超长的 initialDelaySeconds 更清晰、更安全。
三、存活探针:判断应用"是死是活"
存活探针用于判断容器是否仍在正常运行 ,是决定是否重启容器的依据。
核心作用
存活探针主要检测应用是否陷入"假死"状态。例如进程仍然存在,但由于死锁、内部状态异常等原因,已经无法处理请求。此时重启容器往往是恢复可用性的有效手段。
失败后果
如果存活探针连续失败次数超过 failureThreshold,kubelet 会重启该容器。
关键注意点
存活探针不会等待就绪探针成功,它是独立运行的。更重要的是,存活探针必须谨慎配置。
如果存活探针过于敏感,例如把依赖服务短暂抖动、高负载导致的慢响应误判为不可恢复故障,就可能让容器陷入反复重启的恶性循环,甚至引发级联故障。
因此,存活探针应尽量只检查应用自身是否处于不可恢复状态,而不是检查所有外部依赖。
四、就绪探针:决定应用"能否接客"
就绪探针用于判断容器是否已准备好接收流量,是决定是否将 Pod IP 加入 Service 端点的依据。
核心作用
就绪探针实现的是精细化的流量管理。当应用尚未完成初始化,或者暂时无法处理请求时,就绪探针失败会将 Pod 从 Service 的 EndpointSlice 中移除,避免新请求被转发到该 Pod。
常见场景包括:
- 缓存尚未预热完成;
- 数据库连接尚未建立;
- 应用过载,暂时不适合接收新流量;
- 关键依赖服务暂时不可用。
失败后果
就绪探针失败不会重启容器,只会将 Pod 从对应 Service 的端点中移除,使其暂时不再接收新流量。
一旦探针恢复成功,Pod 会被重新加回端点列表,再次开始接收流量。
运行特点
就绪探针在容器整个生命周期内持续运行,是动态调整流量路由的关键。
注意:对于没有 Service 入站流量的 Job/定时任务 Pod,就绪探针不会产生"摘除流量"的效果;若使用外部调度中心,应通过调度中心的下线接口实现类似"停止派发新任务"的能力。
五、三种探针对比
| 特性 | 启动探针 Startup Probe | 存活探针 Liveness Probe | 就绪探针 Readiness Probe |
|---|---|---|---|
| 核心问题 | 应用是否已启动完毕? | 应用是否还活着? | 应用是否准备好接流量? |
| 失败后果 | 杀死并重启容器 | 重启容器 | 从 Service 端点移除,不重启 |
| 运行时机 | 仅在启动阶段,成功后停止 | 容器启动后持续运行 | 容器启动后持续运行 |
| 与其他探针关系 | 成功前禁用存活和就绪探针 | 不等待就绪探针,独立运行 | 受启动探针保护,与存活探针独立 |
| 主要目的 | 保护慢启动应用 | 从不可恢复故障中恢复 | 实现优雅的流量管理 |
一句话总结:
- 启动探针是"起跑保护"
- 存活探针是"故障重启器"
- 就绪探针是"流量开关"
六、探针的检查方式
三种探针都支持多种检查机制,常见的有:
1. httpGet
向容器发送 HTTP GET 请求。返回码在 200--399 之间视为成功,适用于 Web 服务。
2. tcpSocket
尝试与容器指定端口建立 TCP 连接。连接成功即视为健康,适用于数据库、缓存等 TCP 服务。
3. exec
在容器内执行指定命令。命令退出码为 0 视为成功。方式最灵活,但需注意高负载下可能因资源竞争导致探针超时。
七、关键参数
配置探针时,以下参数非常重要:
initialDelaySeconds:容器启动后等待多久开始第一次探测;periodSeconds:探测执行频率,默认 10 秒;timeoutSeconds:单次探测超时时间,默认 1 秒;failureThreshold:连续失败多少次后认定探测失败;successThreshold:连续成功多少次后认定探测恢复成功。
对于启动探针和存活探针,successThreshold 通常必须为 1;就绪探针则可以通过多次成功来避免流量抖动。
八、配置示例
下面是一个包含三种探针的 Deployment 示例:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
spec:
replicas: 3
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: demo-app
image: example/demo-app:1.0.0
ports:
- name: http
containerPort: 8080
startupProbe:
httpGet:
path: /healthz
port: http
periodSeconds: 10
failureThreshold: 30
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /livez
port: http
periodSeconds: 10
failureThreshold: 6
timeoutSeconds: 2
readinessProbe:
httpGet:
path: /readyz
port: http
periodSeconds: 5
failureThreshold: 3
timeoutSeconds: 2
这个示例中:
- 启动探针最多容忍约 300 秒的启动时间;
- 启动成功后,存活探针和就绪探针开始工作;
- 存活探针阈值相对宽松,避免短暂抖动导致重启;
- 就绪探针频率更高,用于快速摘除或恢复流量。
九、最佳实践
1. 慢启动应用优先使用启动探针
对于启动时间不确定或较长的应用,使用启动探针比给存活探针设置超长 initialDelaySeconds 更清晰、更安全。
2. 存活探针与就绪探针保持独立
两者目的不同,应尽量设计不同的检查逻辑或阈值。常见模式是:
- 存活探针检查轻量级、始终存在的端点;
- 就绪探针检查反映真实服务能力的端点。
3. 存活探针要"迟钝"一些
存活探针只应对真正不可恢复的故障做出反应。可以适当提高 failureThreshold,给应用留出自我恢复时间。
4. 就绪探针要能反映依赖和负载状态
就绪探针可以检查关键依赖是否可用、应用是否过载。但要注意避免把短暂依赖抖动误判为长期不可用。
5. 谨慎使用 exec 探针
exec 探针灵活,但在高负载下可能因为资源竞争而超时。优先考虑轻量级的 HTTP 或 TCP 检查。
6. 不要忽略超时和阈值
默认值不一定适合生产环境。应根据应用响应时间和故障恢复策略调整 timeoutSeconds、periodSeconds 和 failureThreshold。
十、总结
Kubernetes 的三类探针并不是互相替代的关系,而是从不同维度保障应用可用性:
- 启动探针负责保护慢启动应用,避免启动期间被误杀;
- 存活探针负责发现不可恢复故障,通过重启恢复容器;
- 就绪探针负责流量管理,确保只有真正准备好的 Pod 才接收请求。
理解它们各自独立的职责,并结合应用的实际启动时间、依赖关系和故障恢复策略进行配置,是构建健壮 Kubernetes 应用的关键。