Kubernetes

K8s 探针机制

·13 分钟阅读·4834 字

StartupProbe、LivenessProbe、ReadinessProbe——原理、配置、区别、实战问题排查

📋 目录

K8s 探针机制

Kubernetes 三大探针(Startup / Liveness / Readiness)的原理、配置与生产实践。


K8s 探针分为 存活探针(LivenessProbe)就绪探针(ReadinessProbe)启动探针(StartupProbe),三者都是kubelet 主动在节点本地执行,不经过 apiserver/控制器,用于检测容器状态、实现自愈与流量控制。


📖 通用基础认知

1. 核心执行主体

节点上的 kubelet 定期发起探测,每个容器独立配置探针(Pod 内多容器互不影响)。

2. 三种探测方式(所有探针通用)

三种方式本质都是校验容器是否正常响应,优先级/使用场景不同:

  1. Exec 命令探测
  • 原理:在容器内执行一条命令,判断退出码
  • 规则:退出码 0 → 成功;非0 → 失败
  • 适用:自定义脚本、检查进程、文件、端口等灵活场景
  1. TCP Socket 探测
  • 原理:kubelet 尝试和容器指定端口建立 TCP 连接
  • 规则:连接能建立 → 成功;连不上/超时 → 失败
  • 适用:TCP 服务(MySQL、Redis、后端服务)
  1. HTTP/HTTPS 探测
  • 原理:kubelet 向容器内指定 URL 发送 GET 请求
  • 规则:响应码 200~399 → 成功;4xx/5xx/超时 → 失败
  • 适用:Web 服务、微服务(SpringBoot/Nginx 等,主流用法)

3. 通用配置参数(所有探针共用)

## 所有探针都支持以下字段
initialDelaySeconds: 5   # 容器启动后,延迟多久开始第一次探测(秒)
periodSeconds: 10        # 探测间隔,每多久执行一次(默认10s)
timeoutSeconds: 3        # 单次探测超时时间(默认1s)
failureThreshold: 3      # 连续失败多少次,判定为异常(默认3次)
successThreshold: 1      # 连续成功多少次,判定为正常(默认1次)

⚡ 三大探针详解(作用+原理+触发行为+典型配置)

一、启动探针 StartupProbe

1. 核心作用

专门解决容器启动慢的问题
部分应用(如 Java、中间件、大数据组件)启动耗时久,还没完成初始化,存活/就绪探针就开始探测,直接误杀容器。
启动探针会阻塞另外两个探针,直到自身探测成功。

2. 工作原理

  1. 容器启动 → 先只运行 StartupProbe
  2. 启动探针连续成功后 → 探针生命周期结束,才开始执行 Liveness + Readiness
  3. 启动探针持续失败,达到 failureThreshold → kubelet 重启容器

3. 关键特性

  • 启动探针没有 successThreshold 实际意义,成功一次即完成使命
  • 专为慢启动应用设计(JVM 应用、ES、Kafka、数据库等)
  • 高配置建议:拉长超时、间隔、失败次数,给足启动时间

4. 示例配置(HTTP 方式)

startupProbe:
  httpGet:
    path: /actuator/health
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 15
  timeoutSeconds: 10
  failureThreshold: 20  # 最多允许20次失败,总启动时长:10 + 15*20 = 310s

二、存活探针 LivenessProbe

1. 核心作用

检测容器是否“活着”(进程卡死、僵死、不可用),实现容器自愈重启
容器进程存在,但内部逻辑卡死、死锁、服务挂死、无响应 → 探针失败,直接重启容器

2. 工作原理

  1. 容器启动 + 启动探针完成后,按周期持续探测
  2. 单次探测超时/结果失败 → 计数+1
  3. 连续失败达到 failureThreshold → kubelet 杀死并重启当前容器
  4. 重启后重置所有探针状态

3. 典型故障场景(探针触发重启)

  • Java 应用死锁、GC 死循环,进程还在但接口无响应
  • Nginx/中间件进程僵死,端口监听正常但不处理请求
  • 容器内部资源耗尽,对外完全无响应

4. 示例配置(TCP 探测,检查端口)

livenessProbe:
  tcpSocket:
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10
  timeoutSeconds: 3
  failureThreshold: 3

三、就绪探针 ReadinessProbe

1. 核心作用

检测容器是否“准备好接收业务流量”,控制流量转发,不重启容器
是流量网关,决定 Service/Ingress 是否将请求转发到当前 Pod

2. 工作原理

  1. 探测成功 → Pod 状态变为 Ready,Endpoint 列表加入该 Pod,接收流量
  2. 探测失败 → Pod 变为 NotReady,从 Endpoint 中剔除,不再转发新流量
  3. 旧连接默认不会断开,仅拦截新请求;不会重启容器

3. 核心使用场景

  1. 容器启动完成,但应用还在加载数据、初始化缓存、连接数据库,暂时不能接流量
  2. 应用运行中临时过载、依赖服务宕机,主动摘除流量,避免请求失败
  3. 滚动更新时,保证新 Pod 就绪后再切流量,实现零停机发布

4. 示例配置(Exec 命令探测)

readinessProbe:
  exec:
    command:
    - sh
    - -c
    - pgrep java  # 检查Java进程是否正常运行
  initialDelaySeconds: 5
  periodSeconds: 10
  timeoutSeconds: 3
  failureThreshold: 3

🔧 三大探针执行顺序 & 整体生命周期(重点)

完整流程:

  1. 容器启动
  2. 等待 initialDelaySeconds → 只执行 StartupProbe
  • 启动探针成功 → 进入下一步
  • 启动探针多次失败 → 重启容器
  1. 启动探针完成 → 同时并行执行 LivenessProbe + ReadinessProbe
  2. 长期运行阶段:
  • Readiness 失败 → 摘流量,Pod NotReady,不重启
  • Liveness 失败 → 直接重启容器,重置所有状态

一句话区分执行逻辑:
启动探针:等容器跑完初始化
就绪探针:管流量进不进
存活探针:管容器死不死、要不要重启


⚙️ 三大探针核心区别对照表

探针类型核心目标探测失败动作影响范围适用场景
StartupProbe
启动探针
等待容器缓慢启动重启容器整个Pod生命周期前置阶段Java、ES、Kafka、数据库等慢启动应用
LivenessProbe
存活探针
检测容器是否僵死重启容器自愈、恢复异常容器进程卡死、死锁、服务无响应
ReadinessProbe
就绪探针
检测容器能否接流量摘除流量,不重启Service/Ingress 流量转发初始化未完成、服务过载、依赖异常

🚀 生产最佳实践 & 避坑指南

1. 配置原则

  1. 慢启动应用(Java 为主):必须配 StartupProbe不要单纯靠调大 liveness 的 initialDelaySeconds,启动探针是专门解决方案。
  2. HTTP 服务优先使用 httpGet,标准健康接口 /health / /actuator/health
  3. TCP 服务(MySQL/Redis)优先使用 tcpSocket,简单高效
  4. 自定义复杂检查(脚本、多条件)使用 exec

2. 常见坑

坑1:探针超时/间隔设置过小,导致误杀

  • 现象:业务正常,频繁重启 Pod
  • 原因:探测超时太短、并发高时健康接口响应慢 → 存活探针误判
  • 解决:调大 timeoutSeconds、合理拉长 periodSeconds

坑2:只配存活探针,不配就绪探针

  • 现象:Pod 启动后立刻进流量,应用还没初始化完成,大量请求报错
  • 解决:线上业务 Pod 建议双探针必配

坑3:启动探针参数太小,慢应用反复重启

  • 现象:容器一直在重启循环,始终起不来
  • 解决:加大 failureThresholdperiodSeconds,给足启动时间

坑4:就绪探针失败,以为容器挂了

  • 现象:Pod 状态 NotReady,但容器正常运行、日志无报错
  • 原因:就绪探针失败,仅摘流量,不会重启容器
  • 排查:查看就绪探针日志、健康接口返回值

3. 排查命令(线上排障)

## 📖 查看 Pod 事件,探针失败原因
kubectl describe pod <pod-name>

## ⚡ 查看 Pod 状态、Ready 状态
kubectl get pod <pod-name> -o wide

## 🔧 手动进入容器,验证探测命令/接口是否正常
kubectl exec -it <pod-name> -- /bin/sh

🌐 完整 YAML 示例(三合一探针,生产模板)

apiVersion: v1
kind: Pod
metadata:
  name: demo-app
spec:
  containers:
  - name: app
    image: my-java-app:v1
    ports:
    - containerPort: 8080

    # 启动探针:应对Java慢启动
    startupProbe:
      httpGet:
        path: /actuator/health
        port: 8080
      initialDelaySeconds: 10
      periodSeconds: 15
      timeoutSeconds: 10
      failureThreshold: 20

    # 存活探针:卡死就重启
    livenessProbe:
      httpGet:
        path: /actuator/health
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
      timeoutSeconds: 3
      failureThreshold: 3

    # 就绪探针:控制流量
    readinessProbe:
      httpGet:
        path: /actuator/health
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
      timeoutSeconds: 3
      failureThreshold: 3

💾 面试高频简答(精简背诵版)

  1. 三个探针分别作用?
  • 启动探针:等待慢应用完成初始化,避免启动阶段误重启;
  • 存活探针:检测容器僵死,异常则重启容器自愈;
  • 就绪探针:判断容器是否可接收流量,失败则从负载均衡中摘除,不重启容器。
  1. 探针由谁执行?
    节点上的 kubelet 本地执行,不经过 Master 组件。
  2. 就绪探针失败会重启 Pod 吗?
    不会,只会剥离流量,Pod 继续运行。
  3. 为什么 Java 应用建议配置启动探针?
    JVM 启动、类加载、框架初始化耗时较长,直接使用存活探针容易探测失败,导致反复重启。

关联文档

关联文档