核心结论: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"] } |
| httpGet | Web 服务(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_ready | Pod 就绪状态(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. 故障排查流程
-
收到告警后,先执行
kubectl describe pod <pod-name> -n <namespace>,查看 “Events” 字段,确认探针失败原因(如 “Liveness probe failed: HTTP request failed with status code: 503”) -
查看容器日志:
kubectl logs <pod-name> -n <namespace> --tail=100,排查服务崩溃、依赖连接失败等问题 -
手动执行探测命令:如 httpGet 探测可执行
kubectl exec <pod-name> -n <namespace> -- curl -v ``http://localhost:8080/actuator/health,验证业务端点状态 -
调整参数:若为参数配置不当(如 initialDelaySeconds 太短),临时修改参数并重启 Pod,观察探针状态
六、总结
K8s 的三大探针是服务高可用的 “基石”——livenessProbe 保障实例 “活着不僵尸”,readinessProbe 保障流量 “只到可用实例”,startupProbe 解决慢启动 “不被误杀”。生产环境中,需根据服务类型(Web / 数据库 / 微服务)、启动特性(快 / 慢启动)、依赖关系(有无外部依赖)组合配置,配合合理的参数与监控告警,才能最大化减少故障影响。
核心原则:探针的核心是 “精准校验”,而非 “越多越好”,需在 “探测准确性” 和 “资源消耗” 之间平衡,避免过度探测或校验不足。