在K8S中,pod中readness 和 liveness 的区别和各自应用场景是什么?
在 Kubernetes 中,livenessProbe
(存活探针)和 readinessProbe
(就绪探针)是两种关键的健康检查机制,用于监控 Pod 中容器的状态,但它们的目的、触发动作和应用场景截然不同:
核心区别
特性 | Liveness Probe (存活探针) | Readiness Probe (就绪探针) |
---|---|---|
目的 | 检查容器是否“活着” (Is the process running?) | 检查容器是否“准备好”接收流量 (Is the app ready to serve?) |
失败后果 | 重启容器 (Kill the container and restart it) | 将 Pod 标记为 NotReady ,并从 Service 的 Endpoints 中移除 (Stop sending traffic) |
核心关注点 | 进程存活/无响应 (Crashed, deadlocked, unresponsive) | 应用初始化完成/临时过载/依赖可用 (Startup complete, dependencies ready, temporary backpressure) |
类比 | 心脏起搏器 (心跳停了就电击重启) | 交通信号灯 (红灯时禁止车辆通行) |
Liveness Probe (存活探针) - 保活卫士
- 作用: 检测容器内的主进程是否处于预期的工作状态。如果探测失败,Kubernetes 认为容器已经“死亡”或“僵死”(例如:进程崩溃、死锁、内部错误导致完全无响应)。
- 失败动作: 重启容器(根据 Pod 的
restartPolicy
执行重启操作)。 - 应用场景:
- 进程崩溃: 应用程序本身因未捕获异常而退出。
- 死锁/卡死: 应用程序陷入死循环或死锁状态,不再处理任何请求(即使进程仍在运行)。
- 内部严重错误: 应用程序因内部状态错误(如关键线程崩溃)而无法继续工作。
- 长时间无响应: 应用程序进程仍在,但因严重问题(如资源耗尽)无法响应任何请求。
- 配置要点:
- 探测命令/端点: 需要设计一个轻量级、低开销的检查,能明确反映应用核心功能是否彻底崩溃。例如:
- 对
/healthz
或类似端点的 HTTP GET 请求(返回 5xx 表示失败)。 - 执行一个简单的命令(如
cat /tmp/healthy
,文件存在表示健康)。 - TCP Socket 连接是否成功建立。
- 对
- 初始延迟 (
initialDelaySeconds
): 非常重要! 必须设置足够长的时间,让应用程序完成其启动过程(如初始化框架、连接数据库、加载数据)。避免在启动阶段就被误杀重启。 - 探测频率 (
periodSeconds
) 和 失败阈值 (failureThreshold
): 平衡响应速度和避免误判(如网络瞬时抖动)。通常比 Readiness Probe 宽松一些。
- 探测命令/端点: 需要设计一个轻量级、低开销的检查,能明确反映应用核心功能是否彻底崩溃。例如:
- 目标: 自动恢复故障容器,尝试让 Pod 重新变得可用。
Readiness Probe (就绪探针) - 流量守门员
- 作用: 检测容器是否已初始化完毕并准备好接受外部流量(例如来自 Service 的请求)。如果探测失败,Kubernetes 认为容器暂时不可用。
- 失败动作: 将 Pod 的
Ready
状态置为False
。控制平面(如 Endpoint Controller)会将该 Pod 从其所属的所有 Service 的 Endpoints 列表中移除。流量不再被路由到该 Pod。 - 应用场景:
- 应用启动初始化: 容器进程已启动,但应用还在加载配置、连接数据库、预热缓存、注册服务等。此时不应接收流量。
- 依赖服务不可用: 应用依赖的后端服务(数据库、缓存、其他微服务)暂时不可达,导致自身无法正常工作。此时不应接收流量。
- 临时过载/背压: 应用因瞬时高负载暂时无法处理更多请求(如线程池满、队列过长)。此时应暂停接收新流量,让应用喘息。
- 维护模式/优雅下线准备: 在应用即将停止前(如滚动更新开始),标记为未就绪,确保现有请求处理完且不再接收新请求。
- 配置要点:
- 探测命令/端点: 需要设计一个能准确反映应用是否具备服务能力的检查。通常比 Liveness Probe 的检查更全面(但也要避免过重)。例如:
- 对
/ready
或/health?type=ready
端点的 HTTP GET 请求(检查核心依赖项状态)。 - 执行一个检查内部状态的命令。
- 检查应用内部健康状态(如线程池使用率、队列深度)。
- 对
- 初始延迟 (
initialDelaySeconds
): 同样重要,确保在启动完成前不接收流量。 - 探测频率 (
periodSeconds
) 和 失败阈值 (failureThreshold
): 可以设置得比 Liveness Probe 更敏感一些,以便更快地将临时不可用的 Pod 移出负载均衡池。
- 探测命令/端点: 需要设计一个能准确反映应用是否具备服务能力的检查。通常比 Liveness Probe 的检查更全面(但也要避免过重)。例如:
- 目标: 控制流量流向,确保只将请求发送给真正能处理的 Pod,提升用户体验和系统整体稳定性。避免将请求发送给无法处理的 Pod(导致 5xx 错误、超时)。
关键区别与协同工作图示
Service --> Endpoints (Ready Pods) --> Pod (Containers)
--> Pod (Containers) -- [Readiness Probe Fails] --> Removed from Endpoints
--> Pod (Containers) -- [Liveness Probe Fails] --> Container Restarted
- Readiness Probe 失败: Pod 被移出 Service 的 Endpoints,流量被屏蔽。容器不被重启,K8s 等待它恢复(可能自行恢复或需要人工介入)。
- Liveness Probe 失败: K8s 杀死问题容器并启动一个新容器(遵循
restartPolicy
)。新容器启动后,需要先通过 Readiness Probe 才能重新加入 Endpoints 接收流量。
最佳实践与总结
- 通常两者都需要配置: 大多数生产应用应同时配置 Liveness 和 Readiness 探针。
- 职责分离:
- Liveness 要保守: 只在确定容器彻底挂掉时才失败触发重启。避免过于敏感导致频繁重启风暴(尤其是在应用启动慢或负载高时)。检查点应聚焦于进程存活和基本响应能力。
- Readiness 可激进: 在容器暂时无法提供服务时就应失败,快速屏蔽流量。检查点应反映完整的服务能力(包括依赖项)。
- Readiness 检查应包含 Liveness 检查: 如果应用彻底挂了,Readiness Probe 也应该失败(这样流量就不会再尝试发往一个死容器)。反之不成立,Liveness 不应包含所有 Readiness 检查(否则临时依赖不可用也会导致不必要的重启)。
- 仔细设置
initialDelaySeconds
: 对两者都至关重要,避免启动过程中的误判。 - 合理设置
periodSeconds
,timeoutSeconds
,successThreshold
,failureThreshold
: 根据应用特性和网络环境调整,平衡响应速度、准确性和开销。 - 使用不同的端点: 为
/healthz
(Liveness) 和/ready
(Readiness) 设计不同的端点,实现逻辑分离。Liveness 检查应非常轻量且无依赖。 - 优雅处理终止: 在 Pod 被终止时,Readiness Probe 通常会先失败(移出流量池),然后才发送 SIGTERM。确保应用能正确处理 SIGTERM 完成优雅关闭。
- 避免仅依赖进程状态: 仅检查进程是否运行(如通过
ps
)通常不够,因为进程可能还在但应用逻辑已卡死。推荐使用 HTTP/TCP/Exec 进行更深入的检查。
简单记忆:
- Liveness Probe (存活): “不行了?重启!” -> 解决进程级故障。
- Readiness Probe (就绪): “还没好?别发流量给我!” -> 解决服务可用性和流量控制问题。
正确配置这两个探针是保障 Kubernetes 应用高可用性、自愈能力和用户体验的关键环节。理解它们的区别并针对应用场景进行精细配置至关重要。