k8s里三种探针的使用场景

一、存活探针

**目的:存活探针决定何时重启容器。**如果存活探针失败,kubelet 会杀死容器,然后根据 Pod 的 restartPolicy 来重启它。

适用场景 :用于检测死锁应用僵死但进程还在的情况。通过重启容器,可以帮助应用从故障状态中恢复。

示例:检测 HTTP 服务死锁

假设你有一个 Web 应用,但在某些情况下(如高负载),它会进入死锁状态,无法响应任何请求,但进程仍在。这时可以使用 HTTP GET 存活探针。

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: liveness-http-pod
spec:
  containers:
  - name: liveness-http-container
    image: my-app:v1.0
    ports:
    - containerPort: 8080
    livenessProbe:
      httpGet:
        # 探针将访问容器的 8080 端口的 /health 路径
        path: /health
        port: 8080
      initialDelaySeconds: 3  # 容器启动后等待 3 秒再开始探测
      periodSeconds: 5        # 每 5 秒执行一次探测
      failureThreshold: 1     # 连续失败 1 次后即判定为失败

工作流程:

  1. 容器启动。
  2. 等待 3 秒 (initialDelaySeconds)。
  3. kubelet 开始每隔 5 秒 (periodSeconds) 向 http://:8080/health 发送 GET 请求。
  4. 如果 /health 路径返回的状态码在 200 到 399 之间,则探测成功。
  5. 如果该路径返回 404 或 500 等错误状态码,或者连接超时,则探测失败。
  6. 一旦失败次数达到 failureThreshold (这里是 1),kubelet 就会杀死并重启容器。

**说明:**存活探针不会等待就绪探针成功。 如果你想在执行存活探针前等待,你可以定义义 initialDelaySeconds,或者使用启动探针。


二、就绪探针

目的判断容器是否已准备好接收流量 。如果就绪探针失败,Endpoint Controller 会从与 Pod 匹配的所有 Service 的端点(Endpoint)中移除该 Pod 的 IP 地址。

适用场景 :这种探针在等待应用执行耗时初始任务 时非常有用; 例如:建立网络连接、加载文件和预热缓存。在容器的生命周期后期, 就绪探针也很有用,例如,从临时故障或过载中恢复时。就绪探针在容器的整个生命期内持续运行。

关键问题:我的应用准备好服务了吗?如果没准备好,就别把流量发给我。

示例:应用启动慢或依赖服务不可用

假设你的应用启动需要 30 秒来加载缓存和连接数据库。在准备好之前,它不应接收任何流量。

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: readiness-tcp-pod
spec:
  containers:
  - name: readiness-tcp-container
    image: my-app:v2.0
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        # 探针只检查 8080 端口是否能打开
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
      # 允许连续失败 3 次,给应用更多启动时间
      failureThreshold: 3
      # 必须连续成功 1 次才算就绪
      successThreshold: 1

工作流程:

  1. 容器启动。
  2. 等待 5 秒后开始探测。
  3. kubelet 尝试与容器的 8080 端口建立 TCP 连接。
  4. 如果连接成功,则探测成功。
  5. 应用可能启动较慢,前几次探测可能会失败。kubelet 会尝试 3 次 (failureThreshold: 3),即 30 秒内如果端口仍未打开,Pod 会一直处于"未就绪"状态。
  6. 一旦有一次探测成功 (successThreshold: 1),Pod 就会被标记为就绪,并被添加到 Service 的负载均衡池中。

三、启动探针

目的保护慢启动容器。在启动探针成功之前,所有其他探针(存活和就绪)都会处于禁用状态。

适用场景 :用于处理启动时间非常长的旧应用。在没有启动探针时,我们只能将livenessProbe 的 initialDelaySeconds 设得很大,但这不够灵活。启动探针允许应用在启动期间无限次地失败,直到成功为止。

关键问题 :我的应用启动完成了吗?在完成之前,先别用存活和就绪探针来打扰我。

示例:处理启动极慢的遗留应用

假设一个 Java 遗留应用,启动可能需要 2 到 5 分钟,时间不固定。

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: startup-exec-pod
spec:
  containers:
  - name: startup-exec-container
    image: legacy-java-app:v3
    ports:
    - containerPort: 8088
    startupProbe:
      exec:
        # 通过检查一个特定文件是否存在来判断应用是否启动完成
        command:
        - cat
        - /tmp/app-initialized
      failureThreshold: 60  # 尝试 60 次
      periodSeconds: 5      # 每 5 秒一次 (总超时时间 = 60 * 5 = 300秒 = 5分钟)
    livenessProbe:
      httpGet:
        path: /health
        port: 8080
      periodSeconds: 10     # 启动成功后,每10秒检查一次存活状态
    readinessProbe:
      httpGet:
        path: /ready
        port: 8080
      periodSeconds: 5      # 启动成功后,每5秒检查一次就绪状态

工作流程

  1. 容器启动。
  2. kubelet 立即开始执行启动探针(没有 initialDelaySeconds),每 5 秒执行一次 cat /tmp/app-initialized 命令。
  3. 在应用完成启动之前,这个文件不存在,命令会失败。kubelet 会一直重试,最多尝试 60 次(总共 5 分钟)。
  4. 一旦应用启动完成,它创建了 /tmp/app-initialized 文件,启动探针成功。
  5. 启动探针成功后,kubelet 才会开始运行存活探针和就绪探针。
  6. 这样,慢启动的应用就不会因为在启动期间存活探针失败而被意外重启。

四、最佳实践

  1. **所有重要 Pod 都应定义就绪探针:**这是实现服务可靠性和滚动更新平滑性的关键。
  2. **谨慎使用存活探针:**只有当应用在失败时确实能通过重启恢复时才使用。配置不当的存活探针可能导致频繁重启,陷入 CrashLoopBackOff。
  3. **优先使用启动探针处理慢启动:**代替设置很长的 initialDelaySeconds,它更灵活、更可靠。
  4. 探针检查逻辑要轻量:探针端点或命令不应消耗过多资源,且执行时间要短(默认为 1 秒超时)。
  5. 探针配置要与应用启动时间匹配:合理设置 initialDelaySeconds、periodSeconds 和 failureThreshold,避免误判。
相关推荐
bxlj_jcj4 小时前
Service :微服务通信、负载、故障难题的解决方案
云原生·容器·kubernetes
Q飞了4 小时前
Kubernetes Pod 的生命周期与故障排查
云原生·容器·kubernetes
止观止5 小时前
容器化安装新趋势:云原生到边缘计算
人工智能·云原生·边缘计算
娶个名字趴5 小时前
Docker(二)
运维·docker·容器
Ribou7 小时前
k8s集群部署nacos集群
kubernetes
失散137 小时前
分布式专题——21 Kafka客户端消息流转流程
java·分布式·云原生·架构·kafka
凉茶社7 小时前
前端容器化配置注入全攻略(docker/k8s) 🐳🚀
运维·docker·容器
June`8 小时前
Docker镜像与容器:轻松理解与实战
运维·docker·容器
荣光波比9 小时前
Docker(二)—— Docker核心功能全解析:网络、资源控制、数据卷与镜像构建实战
运维·网络·docker·容器·云计算