K8s 三大探针(livenessProbe/readinessProbe/startupProbe)详解:参数、案例、最佳实践与监控

325 阅读13分钟

核心结论:K8s 的三个探针本质是「服务健康状态的三层校验机制」——livenessProbe(存活探针)保障实例 “活着”,readinessProbe(就绪探针)保障实例 “能用”,startupProbe(启动探针)解决 “慢启动误杀”,三者配合可实现服务从启动到运行的全生命周期健康管控,是生产环境高可用的核心配置。

一、三大探针的核心定位与区别

探针类型核心作用触发结果适用场景核心目标
livenessProbe检测容器是否 “存活”(如进程崩溃、死锁)探测失败→触发容器重启(按 restartPolicy 策略)所有长期运行的服务(如微服务、数据库)避免 “僵尸实例” 占用资源
readinessProbe检测容器是否 “就绪”(如依赖就绪、服务启动完成)探测失败→实例移出 Service 端点(不接收流量)有启动依赖(如 DB / 缓存)、启动后需初始化的服务避免流量转发到 “未准备好” 的实例
startupProbe检测容器是否 “启动完成”(解决慢启动问题)探测成功前,liveness/readiness 不生效;探测失败→重启慢启动服务(如 Java 应用、大数据组件)防止启动过程中被 liveness 误杀

关键区别:livenessProbe 管 “生死”,readinessProbe 管 “流量”,startupProbe 管 “启动阶段保护”,三者独立配置、可组合使用,且探测失败的后果完全不同(重启 vs 移出端点 vs 重启)。

二、三大探针的详细配置:探测方式、参数、生产级案例

每个探针支持 3 种探测方式(exec/httpGet/tcpSocket),核心参数完全一致,先明确参数含义,再分探针讲解具体使用。

1. 通用核心参数(所有探针共用)

参数名作用说明生产推荐值注意事项
initialDelaySeconds容器启动后,延迟多久开始第一次探测(单位:秒)按服务启动时间定(如 Java:30s,Nginx:5s)太短会导致 “启动中误判失败”,太长会延长故障发现时间
periodSeconds探测的时间间隔(单位:秒)10-15s太短浪费 CPU 资源(如 1s 一次),太长会延迟故障响应
timeoutSeconds单次探测的超时时间(单位:秒)1-3s超时视为探测失败,需小于 periodSeconds
successThreshold探测失败后,连续多少次探测成功才算 “恢复正常”1(默认)无需修改,除非需要严格校验恢复状态
failureThreshold探测成功后,连续多少次探测失败才算 “确认故障”3(默认)太高会延迟故障处理,太低易因网络抖动误判
terminationGracePeriodSeconds探测失败后,容器终止前的优雅关闭时间(单位:秒)30-60s给服务预留连接关闭、数据保存时间(如数据库事务提交)

2. 三种探测方式对比(选择逻辑)

探测方式适用场景优点缺点示例命令 / 配置
exec需执行命令校验(如检查文件、进程、配置)灵活,支持复杂逻辑(如脚本校验)依赖容器内命令存在(如curl需提前安装)exec: { command: ["cat", "/tmp/healthy"] }
httpGetWeb 服务(HTTP/HTTPS)、API 接口无需额外依赖,直接校验业务端口可用性仅支持 HTTP/HTTPS 协议httpGet: { path: "/actuator/health", port: 8080, scheme: "HTTP" }
tcpSocket非 HTTP 服务(如数据库、Redis、TCP 端口服务)校验端口连通性,轻量高效仅能判断端口存活,无法校验服务内部状态tcpSocket: { port: 3306 }(MySQL)

选择原则:优先按服务类型匹配探测方式——Web 服务用 httpGet,端口监听类服务用 tcpSocket,需要复杂校验(如依赖检查、文件存在性)用 exec。

3. livenessProbe(存活探针):保障实例 “活着”

作用:

当容器进程崩溃、死锁、无响应时,触发重启,避免 “僵尸实例” 占用资源(如 Java 应用 OOM 后进程未退出,但无法提供服务)。

生产级案例(按服务类型分类)

案例 1:Java Spring Boot 应用(httpGet 探测,校验健康接口)
apiVersion: v1
kind: Pod
metadata:
 name: springboot-app
spec:
 containers:
 - name: springboot
   image: my-springboot-app:v1
   ports:
   - containerPort: 8080
   livenessProbe:
     httpGet:
       path: /actuator/health/liveness  # Spring Boot Actuator的存活端点(需引入actuator依赖)
       port: 8080
       scheme: HTTP
       httpHeaders:  # 若健康接口需认证,添加请求头
       - name: Authorization
         value: Bearer {token}
     initialDelaySeconds: 60  # Java应用启动慢,延迟60秒开始探测
     periodSeconds: 10        # 每10秒探测一次
     timeoutSeconds: 3        # 探测超时时间3秒(超过视为失败)
     failureThreshold: 3      # 连续3次失败触发重启
   restartPolicy: Always  # 探测失败后重启容器(默认策略)
案例 2:MySQL 数据库(tcpSocket 探测,校验端口连通性)
apiVersion: v1
kind: Pod
metadata:
 name: mysql
spec:
 containers:
 - name: mysql
   image: mysql:8.0
   ports:
   - containerPort: 3306
   env:
   - name: MYSQL_ROOT_PASSWORD
     value: "123456"
   livenessProbe:
     tcpSocket:
       port: 3306
     initialDelaySeconds: 40  # MySQL启动需初始化数据,延迟40秒
     periodSeconds: 15
     timeoutSeconds: 5
     failureThreshold: 3
   # 可选:用exec探测MySQL服务是否可用(更精准)
   # livenessProbe:
   #   exec:
   #     command: ["mysqladmin", "ping", "-uroot", "-p123456"]
   #   initialDelaySeconds: 40
   #   periodSeconds: 15
案例 3:Nginx 服务(exec 探测,检查进程是否存在)
apiVersion: v1
kind: Pod
metadata:
 name: nginx
spec:
 containers:
 - name: nginx
   image: nginx:1.25
   ports:
   - containerPort: 80
   livenessProbe:
     exec:
       command: ["pgrep", "nginx"]  # 检查nginx进程是否存在
     initialDelaySeconds: 5  # Nginx启动快,延迟5秒
     periodSeconds: 10
     timeoutSeconds: 2
     failureThreshold: 3

4. readinessProbe(就绪探针):保障实例 “能用”

作用:

实例启动后,需等待依赖(如 DB、缓存)就绪或初始化完成(如加载配置、预热缓存),此时虽进程存活,但无法处理流量,readinessProbe 会将其移出 Service 端点,直到探测成功才接收流量。

生产级案例(按服务场景分类)

案例 1:依赖 Redis 的 Web 服务(httpGet + 依赖校验)
apiVersion: v1
kind: Pod
metadata:
 name: web-with-redis
spec:
 containers:
 - name: web
   image: my-web-app:v1
   ports:
   - containerPort: 80
   readinessProbe:
     httpGet:
       path: /actuator/health/readiness  # 业务就绪端点(内部校验Redis连接)
       port: 80
     initialDelaySeconds: 20  # 启动后20秒开始探测(先等待依赖连接)
     periodSeconds: 5         # 就绪状态需频繁校验,间隔5秒
     timeoutSeconds: 3
     successThreshold: 1      # 1次成功即视为就绪
     failureThreshold: 2      # 2次失败移出端点(避免网络抖动误判)
   env:
   - name: REDIS_HOST
     value: "redis-service"
案例 2:需要初始化数据的微服务(exec 探测,检查数据是否加载完成)
apiVersion: v1
kind: Pod
metadata:
 name: data-service
spec:
 containers:
 - name: data-service
   image: my-data-app:v1
   ports:
   - containerPort: 8080
   readinessProbe:
     exec:
       command: ["sh", "-c", "ls /data/init_complete.txt"]  # 数据初始化完成会生成该文件
     initialDelaySeconds: 30
     periodSeconds: 8
     timeoutSeconds: 2
   volumeMounts:
   - name: data-volume
     mountPath: /data
 volumes:
 - name: data-volume
   emptyDir: {}
案例 3:TCP 服务(如 Socket 服务,tcpSocket 探测)
apiVersion: v1
kind: Pod
metadata:
 name: socket-service
spec:
 containers:
 - name: socket
   image: my-socket-app:v1
   ports:
   - containerPort: 9000
   readinessProbe:
     tcpSocket:
       port: 9000
     initialDelaySeconds: 15
     periodSeconds: 6
     timeoutSeconds: 4

5. startupProbe(启动探针):解决 “慢启动误杀”

作用:

针对慢启动服务(如 Java 应用、大数据组件、需要加载大量依赖的服务),避免 livenessProbe 因 “启动中未响应” 误判为失败而重启。启动探针成功前,liveness 和 readiness 探针不会执行;启动探针失败则直接重启容器。

核心场景:

  • Java 应用(JVM 加载类、初始化 Spring 上下文需 30-120 秒)

  • 大数据组件(如 Elasticsearch、Kafka,启动需初始化集群)

  • 依赖多服务的应用(如同时依赖 DB、缓存、消息队列,启动校验耗时久)

生产级案例(Java 慢启动应用)

apiVersion: v1
kind: Pod
metadata:
 name: slow-start-java-app
spec:
 containers:
 - name: java-app
   image: my-java-app:v1
   ports:
   - containerPort: 8080
   # 启动探针:允许最长5分钟启动时间(300秒)
   startupProbe:
     httpGet:
       path: /actuator/health/startup
       port: 8080
     failureThreshold: 30  # 每次探测间隔10秒,30次×10秒=300秒(5分钟)
     periodSeconds: 10
     timeoutSeconds: 5
   # 存活探针:启动成功后才执行,避免启动中误杀
   livenessProbe:
     httpGet:
       path: /actuator/health/liveness
       port: 8080
     periodSeconds: 15
     timeoutSeconds: 3
     failureThreshold: 3
   # 就绪探针:启动成功后校验是否可用
   readinessProbe:
     httpGet:
       path: /actuator/health/readiness
       port: 8080
     periodSeconds: 5
     timeoutSeconds: 3

关键逻辑:

若 Java 应用在 300 秒内启动成功(startupProbe 探测成功),则 liveness 和 readiness 探针开始工作;若 300 秒内多次探测失败(累计 30 次),则判定启动失败,重启容器。

三、探针组合使用:不同服务场景的配置模板

生产环境中,极少单独使用某一个探针,而是根据服务类型组合配置,以下是典型场景的最优配置:

1. 微服务(Spring Boot):startup + liveness + readiness

containers:
- name: springboot-ms
 image: ms-app:v1
 ports:
 - containerPort: 8080
 startupProbe:  # 解决慢启动
   httpGet:
     path: /actuator/health/startup
     port: 8080
   failureThreshold: 24  # 24×10秒=240秒(4分钟)启动超时
   periodSeconds: 10
 livenessProbe:  # 保障运行中存活
   httpGet:
     path: /actuator/health/liveness
     port: 8080
   initialDelaySeconds: 60  # 启动探针成功后,再延迟60秒启动存活探测
   periodSeconds: 15
   failureThreshold: 3
 readinessProbe:  # 保障可用(校验DB/缓存依赖)
   httpGet:
     path: /actuator/health/readiness
     port: 8080
   periodSeconds: 5
   successThreshold: 1

2. 数据库(MySQL):liveness + readiness

containers:
- name: mysql
 image: mysql:8.0
 ports:
 - containerPort: 3306
 env:
 - name: MYSQL_ROOT_PASSWORD
   value: "123456"
 livenessProbe:  # 检查数据库进程存活
   tcpSocket:
     port: 3306
   initialDelaySeconds: 40
   periodSeconds: 15
   failureThreshold: 3
 readinessProbe:  # 检查数据库服务可用(而非仅端口)
   exec:
     command: ["mysqladmin", "ping", "-uroot", "-p123456"]
   initialDelaySeconds: 50  # 比liveness延迟更久,确保初始化完成
   periodSeconds: 10
   timeoutSeconds: 5

3. 轻量 Web 服务(Nginx):liveness + readiness

containers:
- name: nginx
 image: nginx:1.25
 ports:
 - containerPort: 80
 livenessProbe:
   exec:
     command: ["pgrep", "nginx"]
   initialDelaySeconds: 5
   periodSeconds: 10
 readinessProbe:
   httpGet:
     path: /  # 校验Nginx能正常返回页面
     port: 80
   initialDelaySeconds: 8
   periodSeconds: 5

4. 有依赖的服务(如依赖 RabbitMQ 的订单服务):readiness + liveness

containers:
- name: order-service
 image: order-app:v1
 ports:
 - containerPort: 8080
 livenessProbe:
   httpGet:
     path: /actuator/health/liveness
     port: 8080
   initialDelaySeconds: 30
   periodSeconds: 12
 readinessProbe:
   exec:
     command: ["curl", "-s", "http://localhost:8080/actuator/health/readiness"]  # 内部校验RabbitMQ连接
   initialDelaySeconds: 20
   periodSeconds: 6
   failureThreshold: 2

四、生产环境最佳实践(避坑指南)

1. 探针选择与探测方式的优先级

  • 「Web 服务」:httpGet > exec > tcpSocket(httpGet 可直接校验业务端点,更精准)

  • 「数据库 / 中间件」:tcpSocket + exec(tcpSocket 校验端口,exec 校验服务可用性)

  • 「无 HTTP 接口的服务」:exec > tcpSocket(exec 可执行自定义校验逻辑)

  • 「慢启动服务」:必须加 startupProbe,且failureThreshold × periodSeconds需覆盖最大启动时间

2. 参数配置的 “黄金法则”

  • initialDelaySeconds:liveness/readiness 的延迟时间需略短于服务实际启动时间(如 Java 实际启动 40 秒,设为 30-35 秒),避免 “启动中误判”

  • periodSeconds:liveness 设 10-15 秒(避免频繁探测消耗资源),readiness 设 5-8 秒(需快速感知就绪状态)

  • timeoutSeconds:控制在 1-3 秒(httpGet/tcpSocket)、2-5 秒(exec),避免探测超时导致 “假失败”

  • failureThreshold:liveness 设 3-5 次(防止网络抖动误重启),readiness 设 2-3 次(快速移出异常实例)

  • startupProbe:failureThreshold × periodSeconds需覆盖 99% 的启动场景(如 Java 设 24×10=240 秒),避免 “启动超时误杀”

3. 绝对不能踩的 5 个坑

  • ❌ 用 livenessProbe 代替 readinessProbe:会导致 “启动中实例接收流量”,引发大量 5xx 错误

  • ❌ 给慢启动服务不配置 startupProbe:livenessProbe 会因 “启动中未响应” 频繁重启实例

  • ❌ 探测方式选择不当:如用 tcpSocket 校验 Web 服务(仅端口存活,无法判断业务是否可用)

  • ❌ 参数配置过严:如periodSeconds=2秒(探测太频繁,占用容器 CPU / 网络资源)

  • ❌ 就绪探针依赖外部不稳定服务:如 readinessProbe 校验跨集群 DB,会因网络波动导致实例频繁移出端点

4. 探针与业务代码的配合

  • 暴露专门的健康检查端点(如 Spring Boot Actuator 的/actuator/health系列端点),避免复用业务接口

  • 健康端点需 “轻量无副作用”:不执行复杂查询、不修改数据,确保探测耗时 < 1 秒

  • 就绪探针需包含依赖校验:如检查 DB、缓存、消息队列的连接状态,确保服务 “真能用”

  • 启动探针端点需仅校验 “启动完成”:如 Spring Boot 的/actuator/health/startup,仅判断上下文是否初始化完成

5. 特殊场景的额外配置

  • 「滚动更新时」:readinessProbe 的successThreshold设为 1,确保新实例快速就绪;livenessProbe 的initialDelaySeconds设为滚动更新间隔的 2 倍,避免更新过程中误重启

  • 「StatefulSet 服务(如 MySQL 集群)」:livenessProbe 用 exec 探测集群状态(如mysql -e "show status like 'wsrep_cluster_status'"),避免单节点故障影响集群

  • 「敏感服务(如支付服务)」:livenessProbe 和 readinessProbe 用不同探测方式(如 liveness 用 httpGet,readiness 用 exec),双重校验降低误判风险

五、探针监控与告警方案(生产级)

探针的状态是服务健康的核心指标,需通过 “指标采集→可视化→告警” 实现全链路监控,避免探针失败未发现导致故障扩散。

1. 核心监控指标(基于 kube-state-metrics)

kube-state-metrics 会暴露探针相关的 Prometheus 指标,核心指标如下:

指标名称含义告警阈值参考
kube_pod_probe_success{probe="liveness"}livenessProbe 探测成功次数5 分钟内成功率 < 90%
kube_pod_probe_success{probe="readiness"}readinessProbe 探测成功次数5 分钟内成功率 < 80%
kube_pod_probe_success{probe="startup"}startupProbe 探测成功次数启动后 3 分钟内未成功
kube_pod_container_status_waiting_reason容器等待原因(如 ProbeFailed)出现 “ProbeFailed” 且持续 5 分钟以上
kube_pod_status_readyPod 就绪状态(1 = 就绪,0 = 未就绪)0 状态持续 10 分钟以上

2. 可视化(Grafana Dashboard)

  • 导入官方 Dashboard:Kubernetes Pod Health(ID:13105),可直观展示探针成功率、失败次数、Pod 就绪状态

  • 自定义面板:添加 “探针失败 Top5 Pod”“就绪实例占比”“重启次数统计”,聚焦核心风险点

3. 告警规则(Alertmanager)

groups:
- name: k8s-probe-alerts
 rules:
 # livenessProbe频繁失败告警
 - alert: LivenessProbeFailure
   expr: sum(rate(kube_pod_probe_success{probe="liveness"}[5m]) == 0) by (pod, namespace) > 0
   for: 5m
   labels:
     severity: critical
   annotations:
     summary: "Pod {{ $labels.pod }} livenessProbe探测失败"
     description: "命名空间{{ $labels.namespace }}的Pod {{ $labels.pod }}的livenessProbe已连续5分钟探测失败,可能导致容器重启,请检查服务状态"
 # readinessProbe失败导致实例未就绪
 - alert: ReadinessProbeFailure
   expr: kube_pod_status_ready{condition="true"} == 0
   for: 10m
   labels:
     severity: warning
   annotations:
     summary: "Pod {{ $labels.pod }}未就绪"
     description: "命名空间{{ $labels.namespace }}的Pod {{ $labels.pod }}已连续10分钟未就绪,可能是readinessProbe探测失败,请检查服务依赖或初始化状态"
 # startupProbe启动失败
 - alert: StartupProbeFailure
   expr: sum(rate(kube_pod_probe_success{probe="startup"}[3m]) == 0) by (pod, namespace) > 0
   for: 5m
   labels:
     severity: critical
   annotations:
     summary: "Pod {{ $labels.pod }}启动失败"
     description: "命名空间{{ $labels.namespace }}的Pod {{ $labels.pod }}的startupProbe探测失败,服务启动超时,请检查启动日志或延长启动超时时间"

4. 故障排查流程

  1. 收到告警后,先执行kubectl describe pod <pod-name> -n <namespace>,查看 “Events” 字段,确认探针失败原因(如 “Liveness probe failed: HTTP request failed with status code: 503”)

  2. 查看容器日志:kubectl logs <pod-name> -n <namespace> --tail=100,排查服务崩溃、依赖连接失败等问题

  3. 手动执行探测命令:如 httpGet 探测可执行kubectl exec <pod-name> -n <namespace> -- curl -v ``http://localhost:8080/actuator/health,验证业务端点状态

  4. 调整参数:若为参数配置不当(如 initialDelaySeconds 太短),临时修改参数并重启 Pod,观察探针状态

六、总结

K8s 的三大探针是服务高可用的 “基石”——livenessProbe 保障实例 “活着不僵尸”,readinessProbe 保障流量 “只到可用实例”,startupProbe 解决慢启动 “不被误杀”。生产环境中,需根据服务类型(Web / 数据库 / 微服务)、启动特性(快 / 慢启动)、依赖关系(有无外部依赖)组合配置,配合合理的参数与监控告警,才能最大化减少故障影响。

核心原则:探针的核心是 “精准校验”,而非 “越多越好”,需在 “探测准确性” 和 “资源消耗” 之间平衡,避免过度探测或校验不足。