Kubernetes readiness 与 liveness 探针配置:避免滚动发布误摘流量

Kubernetes 探针配置封面

这篇指南帮助你区分 Kubernetes readiness 与 liveness 探针的作用,理解探针参数如何影响滚动发布流量切换,并掌握避免误摘除的配置方法。探针配置不当最常见的后果是:滚动发布时新实例还没准备好就被导入流量,或者已经正常的实例被错误重启,两类问题都和探针参数直接相关。

如果你已经在用容器化部署,探针配置和 容器安全加固一样属于上线基线。Hostease 这类面向中文用户的 [VPS](https://cn.hostease.com/vps/) 或[独立服务器](https://cn.hostease.com/dedicated-server/)环境上运行 Kubernetes(一种容器编排系统)时,探针决定了滚动发布和故障恢复的稳定性。本文不讲 Kubernetes 基础概念,只聚焦探针参数怎么配、怎么排错。

一、readiness 与 liveness 的本质区别

readiness probe(就绪探针)回答的问题是”这个实例能不能接收流量”。探针失败时,Kubernetes 把实例从 Service 的 Endpoints 中移除,不再转发新请求,但不会重启容器。liveness probe(存活探针)回答的问题是”这个实例是否需要重启”。探针失败时,Kubernetes 会杀掉并重启容器。

最常见的错误是把 liveness 当 readiness 用:用 liveness 检查应用是否就绪。后果是应用启动慢时被 liveness 判定失败并反复重启,永远无法完成初始化。正确做法是用 readiness 控制流量导入,用 liveness 只检测真正的死锁或卡死。

二、探针的四个核心参数

  • initialDelaySeconds:容器启动后等待多久才开始第一次探测。设太短会在应用未启动时就判定失败。
  • periodSeconds:探测间隔。默认 10 秒,太短会增加负载,太长会延迟发现问题。
  • timeoutSeconds:单次探测超时时间。设太短会让稍慢的检查端点被误判失败。
  • failureThreshold:连续失败多少次后才判定失败。设为 1 会让一次抖动就触发摘除或重启。

探针参数与流量切换流程

三、滚动发布时的流量切换逻辑

Kubernetes 滚动发布时,新 Pod 启动后必须通过 readiness probe 才会被加入 Endpoints 接收流量。如果 readiness 配置不当,有两种典型故障:第一种是 initialDelaySeconds 太短,应用还在启动就被判定就绪,流量导入后返回 502 或超时;第二种是 failureThreshold 设为 1,应用启动期间一次探测失败就被移出,即使后续恢复也要等下一轮探测重新加入。

更隐蔽的问题是 liveness 探针在滚动发布期间误杀新 Pod。如果 liveness 的 initialDelaySeconds 小于应用实际启动时间,新 Pod 会在启动阶段被 liveness 判定失败并重启,形成”启动 → 被杀 → 重启 → 被杀”的循环,滚动发布永远无法完成。

四、推荐配置实践

以下是一个 readiness 和 liveness 分离的配置示例,适用于需要预热的 Web 应用:

readinessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 3
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10
  timeoutSeconds: 3
  failureThreshold: 3

关键区别:readiness 的 initialDelaySeconds 设为 5 秒,允许快速开始检查;liveness 的 initialDelaySeconds 设为 30 秒,给应用足够的启动时间。两者 failureThreshold 都设为 3,避免一次抖动就触发动作。

检查端点的选择也很重要。HTTP 检查应指向一个轻量级路径,如 /healthz 或 /ready,这个端点只返回 200 确认进程存活,不执行复杂逻辑。如果检查端点需要确认依赖可用性,可以分两层:readiness 检查依赖是否就绪(如数据库连接、缓存可用),liveness 只检查进程是否卡死。不要让 liveness 检查依赖状态,否则依赖短暂不可用时所有实例都会被重启,造成级联故障。如果你在做 微服务拆分,每个服务的探针参数应该根据各自的启动时间和依赖预热时长单独设置,而不是全项目统一复制。

对于 TCP 检查,可以只检查端口是否监听,开销最低但无法确认应用逻辑是否正常。对于需要确认应用状态的服务,优先用 HTTP 检查。exec 检查可以执行容器内命令,适合检查文件状态或进程是否存在,但开销最高,不适合高频探测。

五、误摘除的排查方法

当实例被频繁移出 Endpoints 或反复重启时,先用以下命令确认是哪种探针触发的。

kubectl describe pod  | grep -A 5 "Last State"
kubectl get events --field-selector involvedObject.name= --sort-by='.lastTimestamp'

如果事件中看到 Liveness probe failed,说明 liveness 触发了重启,需要检查 initialDelaySeconds 是否足够、检查端点是否响应慢。如果看到 Readiness probe failed,说明 readiness 把实例移出了 Endpoints,需要检查应用启动期间检查端点是否返回非 200 状态码。

还有一种常见情况是探针检查端点本身设计不合理。比如把健康检查端点指向首页,首页需要查询数据库、渲染模板、加载插件,任何一步变慢都会让探针超时。正确的做法是把健康检查端点设计成轻量级接口,只返回 200 确认进程存活和依赖可用,不执行复杂业务逻辑。检查端点应该避免访问外部 API、复杂报表或大范围数据库扫描。

如果检查端点涉及数据库查询,还要确认查询本身是否够快,可以参考 MySQL 慢查询分析排查是否有慢 SQL 导致检查端点超时。配合 多层缓存架构排查时要注意:缓存预热未完成时检查端点可能返回 503,这是正常行为,readiness 应该允许这种状态,而不是在预热期间就把实例摘除。如果你做过 容器安全加固,其中限制容器权限不会影响探针运行,但要确认探针访问的端口没有被网络策略阻断。

六、startup probe 处理慢启动应用

Kubernetes 1.16+ 引入了 startup probe(启动探针)。它专门解决慢启动应用的 liveness 困境:startup probe 通过之前 liveness 不生效,通过后 liveness 才开始检查。这样可以把 liveness 的 initialDelaySeconds 设得很小,同时不担心慢启动被误杀。

探针分离与 startup probe 对比

探针类型 失败后果 适用场景
readiness 移出 Endpoints,不重启 控制流量导入
liveness 重启容器 检测死锁、卡死
startup 重启容器 慢启动应用保护

总结

探针配置的核心原则是分离职责:readiness 控制流量,liveness 控制重启,startup 保护慢启动。滚动发布误摘除的最常见原因是 liveness 的 initialDelaySeconds 不足或 readiness 的 failureThreshold 设为 1。建议 readiness 用短间隔快速检查就绪状态,liveness 用足够长的 initialDelaySeconds 和 failureThreshold 容忍启动和抖动。对于 Hostease 环境上的 Kubernetes 部署,正确的探针配置是保证滚动发布和故障恢复不中断业务的基础。

发表评论