Kubernetes Pod 健康检查问题排查与最佳实践

277 阅读3分钟

Kubernetes Pod 健康检查问题排查与最佳实践

在最近一次部署 Spring Cloud 应用到 Kubernetes 的过程中,我遇到了一个 Pod 启动后不断重启 的问题。通过排查和调整健康检查配置,最终解决了问题。本文记录整个过程,帮助大家在类似场景下快速定位和处理。


一、问题现象

部署的 Pod 一直处于 Running/CrashLoopBackOff 状态:

kubectl describe pod cloud-mgmt-xxxx -n my-cloud

可以看到:

  • 事件 (Events) 里反复出现:

    • Readiness probe failed: connection refused
    • Liveness probe failed: connection refused
  • Pod 日志显示服务需要一段时间才能完全启动(Spring Boot + Nacos 注册等)。


二、问题排查思路

  1. 查看容器状态 kubectl describe pod 显示容器被反复重启,Exit Code = 143,说明是 被 K8s 杀掉的(而不是应用自己退出)。

  2. 关注探针配置 Pod 的探针配置如下:

    livenessProbe:
      httpGet:
        path: /actuator/health
        port: 9205
      initialDelaySeconds: 60
      periodSeconds: 10
      timeoutSeconds: 3
    
    readinessProbe:
      httpGet:
        path: /actuator/health
        port: 9205
      initialDelaySeconds: 60
      periodSeconds: 5
      timeoutSeconds: 3
    

    问题在于:应用大约需要 100 秒左右 才能完全启动,但探针 60 秒 就开始检查,结果是应用还没起来,就被判定为 不健康 并重启。


三、解决办法

Readiness Probe 的 initialDelaySeconds 调整为 120 秒

readinessProbe:
  httpGet:
    path: /actuator/health
    port: 9205
  initialDelaySeconds: 120   # 延迟检查,确保应用先完全启动
  periodSeconds: 5
  timeoutSeconds: 3

修改后,Kubernetes 会在 应用真正启动完成后 才开始探测,Pod 不再频繁重启。


四、关键参数解析

  • initialDelaySeconds 启动容器后,等待多久才开始第一次探测。 👉 解决方案关键点:应用启动慢时需要调大。

  • periodSeconds 探针的执行间隔,默认 10 秒。 👉 检查频率,太短会增加负载,太长会延迟故障发现。

  • timeoutSeconds 每次探针请求的超时时间。 👉 建议略高于服务的平均响应时间。

  • failureThreshold 连续失败多少次才判定为不健康。 👉 避免临时抖动导致误判。


五、Liveness 与 Readiness 的区别

探针类型作用典型场景
Liveness Probe判断容器是否存活,失败会触发 容器重启应用假死、死循环、内存溢出等
Readiness Probe判断容器是否准备好接收流量,失败时 不会分流量应用初始化、依赖服务未就绪等

简化理解

  • Liveness = 活着没
  • Readiness = 能不能干活

最佳实践是 两个都要配置

  • Liveness 保证服务不会挂死。
  • Readiness 保证服务只在真正可用时才接流量。

六、时序图对比

sequenceDiagram
    participant Kubelet
    participant Container

    Note over Container: 容器启动中 (需要较长时间)
    
    Kubelet->>Container: Liveness (after 60s)
    Container-->>Kubelet: 失败 (服务未就绪)
    Kubelet->>Container: 判定异常,可能重启
    
    Note over Container: 服务大约 100s 才真正 ready
    
    Kubelet->>Container: Readiness (after 120s)
    Container-->>Kubelet: 成功 (返回 200)
    Note over Kubelet: 开始接收流量

七、最佳实践总结

  1. 根据应用启动耗时调整 initialDelaySeconds,避免探针过早触发。

  2. 区分 Liveness 和 Readiness,不要混用:

    • Liveness = 假死自动重启
    • Readiness = 控制流量接入
  3. 合理设置 period 和 timeout,平衡检测精度与性能消耗。

  4. 结合应用特性选择探针方式:HTTP、TCP 或 Command。

  5. 观察 Pod 事件和日志,这是排查健康检查问题的关键。


通过这次排查,我进一步体会到 Kubernetes 探针配置的重要性。配置不合理,可能让一个本来能正常启动的应用陷入无限重启。调整好参数后,应用运行稳定,服务发现和流量调度也都恢复正常。