健康检查

目录

理解健康检查

请参考官方 Kubernetes 文档:

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

Kubernetes 提供三种类型的探针:

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

正确配置这些探针对于在 Kubernetes 上构建强大且自愈的应用程序至关重要。

探针类型

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

HTTPGET 操作

对 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

TCPSocket 操作

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

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

示例

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

最佳实践

  • 存活性就绪性
    • 存活性:如果您的应用程序无响应,最好重启它。如果失败,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 控制台配置健康检查参数

常见参数

参数描述
初始延迟initialDelaySeconds:开始探针之前的宽限期(秒)。默认值:300
周期periodSeconds:探针间隔(1-120 秒)。默认值:60
超时timeoutSeconds:探针超时持续时间(1-300 秒)。默认值:30
成功阈值successThreshold:标记健康所需的最小连续成功次数。默认值:0
失败阈值failureThreshold:触发操作的最大连续失败次数:
- 0:禁用基于失败的操作
- 默认值:5 次失败 → 容器重启。

协议特定参数

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

排查探针失败

当 Pod 的状态指示与探针相关的问题时,以下是排查方法:

检查 Pod 事件

kubectl describe pod <pod-name>

查找与存活性探针失败、就绪性探针失败或启动探针失败相关的事件。这些事件通常提供具体的错误消息(例如,连接被拒绝、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:使用 nc(netcat)或 telnet 从同一网络中的另一个 Pod 或主机(如果允许)测试 TCP 连接:kubectl exec -it <another-pod> -- nc -vz <pod-ip> <probe-port>

检查探针配置

  • 仔细检查您的 Deployment/Pod YAML 中的探针参数(路径、端口、命令、延迟、阈值)。常见错误是端口或路径不正确。

检查应用程序代码

  • 确保您的应用程序的健康检查端点正确实现,并真实反映应用程序的就绪性/存活性。有时,端点可能在应用程序本身出现故障时仍返回成功。

资源限制

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

网络问题

  • 在少数情况下,网络策略或 CNI 问题可能会阻止探针到达容器。验证集群内的网络连接。