健康检查

目录

理解健康检查

请参考官方 Kubernetes 文档:

在 Kubernetes 中,健康检查(也称为探针)是确保应用高可用性和弹性的关键机制。Kubernetes 使用这些探针来判断 Pod 的健康状态和就绪状态,从而使系统能够采取适当的措施,例如重启容器或路由流量。没有适当的健康检查,Kubernetes 无法可靠地管理应用的生命周期,可能导致服务性能下降或中断。

Kubernetes 提供三种类型的探针:

  • livenessProbe:检测容器是否仍在运行。如果存活探针失败,Kubernetes 会根据重启策略终止并重启 Pod。
  • readinessProbe:检测容器是否准备好提供服务。如果就绪探针失败,Endpoint Controller 会将该 Pod 从 Service 的 Endpoint 列表中移除,直到探针成功。
  • startupProbe:专门检查应用是否已成功启动。存活和就绪探针在启动探针成功之前不会执行。对于启动时间较长的应用非常有用。

正确配置这些探针对于构建健壮且自愈的 Kubernetes 应用至关重要。

探针类型

Kubernetes 支持三种实现探针的机制:

HTTP GET 操作

对 Pod 的 IP 地址的指定端口和路径执行 HTTP GET 请求。如果响应码在 200 到 399 之间,则探针视为成功。

  • 使用场景:Web 服务器、REST API 或任何暴露 HTTP 端点的应用。

  • 示例

    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20

exec 操作

在容器内执行指定命令。如果命令以状态码 0 退出,则探针成功。

  • 使用场景:无 HTTP 端点的应用,检查内部应用状态,或执行需要特定工具的复杂健康检查。

  • 示例

    readinessProbe:
      exec:
        command:
          - cat
          - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

TCP Socket 操作

尝试在容器的 IP 地址和指定端口打开 TCP 套接字。如果能建立 TCP 连接,则探针成功。

  • 使用场景:数据库、消息队列或任何通过 TCP 端口通信但可能没有 HTTP 端点的应用。

  • 示例

    startupProbe:
      tcpSocket:
        port: 3306
      initialDelaySeconds: 5
      periodSeconds: 10
      failureThreshold: 30

最佳实践

  • 存活探针 vs. 就绪探针
    • 存活探针:如果应用无响应,最好重启它。失败时,Kubernetes 会重启容器。
    • 就绪探针:如果应用暂时无法提供服务(例如连接数据库),但可能无需重启即可恢复,使用就绪探针。这可防止流量被路由到不健康的实例。
  • 慢启动应用使用启动探针:对于启动时间较长的应用,使用启动探针。这样可以避免因存活探针失败导致的过早重启,或因就绪探针失败导致的流量路由问题。
  • 轻量级探针:确保探针端点轻量且响应迅速。探针不应涉及重计算或外部依赖(如数据库调用),以免探针本身不可靠。
  • 有意义的检查:探针检查应真实反映应用的健康和就绪状态,而不仅仅是进程是否运行。例如,对于 Web 服务器,应检查是否能提供基本页面,而不仅是端口是否开放。
  • 调整 initialDelaySeconds:合理设置 initialDelaySeconds,给予应用足够时间启动后再进行首次探测。
  • 调整 periodSeconds 和 failureThreshold:在快速检测故障和避免误报之间取得平衡。探测过于频繁或 failureThreshold 过低可能导致不必要的重启或不就绪状态。
  • 日志调试:确保应用日志清晰记录健康检查端点调用和内部状态,有助于调试探针失败。
  • 组合使用探针:通常同时使用三种探针(存活、就绪、启动)以有效管理应用生命周期。

YAML 文件示例

spec:
  template:
    spec:
      containers:
        - name: nginx
          image: nginx:1.14.2 # 容器镜像
          ports:
            - containerPort: 80 # 容器暴露端口
          startupProbe:
            httpGet:
              path: /startup-check
              port: 8080
            initialDelaySeconds: 0 # 启动探针通常为 0 或很小
            periodSeconds: 5
            failureThreshold: 60 # 允许 60 * 5 = 300 秒(5 分钟)启动时间
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5 # Pod 启动后延迟 5 秒开始检测
            periodSeconds: 10 # 每 10 秒检测一次
            timeoutSeconds: 5 # 超时 5 秒
            failureThreshold: 3 # 连续失败 3 次视为不健康
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
            timeoutSeconds: 5
            failureThreshold: 3

通过 Web 控制台配置健康检查参数

通用参数

参数描述
Initial DelayinitialDelaySeconds:探针开始前的宽限时间(秒)。默认值:300
PeriodperiodSeconds:探针间隔(1-120秒)。默认值:60
TimeouttimeoutSeconds:探针超时时长(1-300秒)。默认值:30
Success ThresholdsuccessThreshold:标记健康所需的最小连续成功次数。默认值:0
Failure ThresholdfailureThreshold:触发动作的最大连续失败次数:
- 0:禁用基于失败的动作
- 默认:5 次失败 → 容器重启。

协议特定参数

参数适用协议描述
ProtocolHTTP/HTTPS健康检查协议
PortHTTP/HTTPS/TCP探测目标容器端口
PathHTTP/HTTPS端点路径(例如 /healthz
HTTP HeadersHTTP/HTTPS自定义头部(添加键值对)
CommandEXEC容器内执行的检查命令(例如 sh -c "curl -I localhost:8080 | grep OK")。
注意:转义特殊字符并测试命令有效性。

探针失败故障排查

当 Pod 状态显示与探针相关的问题时,可按以下步骤排查:

查看 Pod 事件

kubectl describe pod <pod-name>

查找与 LivenessProbe failed、ReadinessProbe failed 或 StartupProbe failed 相关的事件。这些事件通常包含具体错误信息(如连接拒绝、HTTP 500 错误、命令退出码等)。

查看容器日志

kubectl logs <pod-name> -c <container-name>

检查应用日志,查看探针失败时是否有错误或警告。应用可能记录了健康检查端点未正确响应的原因。

手动测试探针端点

  • HTTP:如果可能,使用 kubectl exec -it <pod-name> -- curl <probe-path>:<probe-port> 或容器内的 wget 查看实际响应。
  • Exec:手动执行探针命令:kubectl exec -it <pod-name> -- <command-from-probe>,检查退出码和输出。
  • TCP:从同一网络内的另一个 Pod 或允许的主机使用 nc(netcat)或 telnet 测试 TCP 连接:kubectl exec -it <another-pod> -- nc -vz <pod-ip> <probe-port>

检查探针配置

  • 仔细核对 Deployment/Pod YAML 中的探针参数(路径、端口、命令、延迟、阈值)。常见错误是端口或路径配置错误。

检查应用代码

  • 确保应用的健康检查端点正确实现,真实反映应用的就绪和存活状态。有时端点可能返回成功,但应用本身已损坏。

资源限制

  • CPU 或内存资源不足可能导致应用无响应,进而导致探针失败。检查 Pod 资源使用情况(kubectl top pod <pod-name>),并考虑调整 resources 限制/请求。

网络问题

  • 极少数情况下,网络策略或 CNI 问题可能阻止探针访问容器。验证集群内的网络连通性。