K8s 探针机制
Kubernetes 三大探针(Startup / Liveness / Readiness)的原理、配置与生产实践。
K8s 探针分为 存活探针(LivenessProbe)、就绪探针(ReadinessProbe)、启动探针(StartupProbe),三者都是kubelet 主动在节点本地执行,不经过 apiserver/控制器,用于检测容器状态、实现自愈与流量控制。
📖 通用基础认知
1. 核心执行主体
由节点上的 kubelet 定期发起探测,每个容器独立配置探针(Pod 内多容器互不影响)。
2. 三种探测方式(所有探针通用)
三种方式本质都是校验容器是否正常响应,优先级/使用场景不同:
- Exec 命令探测
- 原理:在容器内执行一条命令,判断退出码
- 规则:退出码
0→ 成功;非0 → 失败 - 适用:自定义脚本、检查进程、文件、端口等灵活场景
- TCP Socket 探测
- 原理:kubelet 尝试和容器指定端口建立 TCP 连接
- 规则:连接能建立 → 成功;连不上/超时 → 失败
- 适用:TCP 服务(MySQL、Redis、后端服务)
- 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. 工作原理
- 容器启动 → 先只运行 StartupProbe
- 启动探针连续成功后 → 探针生命周期结束,才开始执行 Liveness + Readiness
- 启动探针持续失败,达到
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
- 连续失败达到
failureThreshold→ kubelet 杀死并重启当前容器 - 重启后重置所有探针状态
3. 典型故障场景(探针触发重启)
- Java 应用死锁、GC 死循环,进程还在但接口无响应
- Nginx/中间件进程僵死,端口监听正常但不处理请求
- 容器内部资源耗尽,对外完全无响应
4. 示例配置(TCP 探测,检查端口)
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
三、就绪探针 ReadinessProbe
1. 核心作用
检测容器是否“准备好接收业务流量”,控制流量转发,不重启容器。
是流量网关,决定 Service/Ingress 是否将请求转发到当前 Pod。
2. 工作原理
- 探测成功 → Pod 状态变为
Ready,Endpoint 列表加入该 Pod,接收流量 - 探测失败 → Pod 变为
NotReady,从 Endpoint 中剔除,不再转发新流量 - 旧连接默认不会断开,仅拦截新请求;不会重启容器
3. 核心使用场景
- 容器启动完成,但应用还在加载数据、初始化缓存、连接数据库,暂时不能接流量
- 应用运行中临时过载、依赖服务宕机,主动摘除流量,避免请求失败
- 滚动更新时,保证新 Pod 就绪后再切流量,实现零停机发布
4. 示例配置(Exec 命令探测)
readinessProbe:
exec:
command:
- sh
- -c
- pgrep java # 检查Java进程是否正常运行
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
🔧 三大探针执行顺序 & 整体生命周期(重点)
完整流程:
- 容器启动
- 等待
initialDelaySeconds→ 只执行 StartupProbe
- 启动探针成功 → 进入下一步
- 启动探针多次失败 → 重启容器
- 启动探针完成 → 同时并行执行 LivenessProbe + ReadinessProbe
- 长期运行阶段:
- Readiness 失败 → 摘流量,Pod NotReady,不重启
- Liveness 失败 → 直接重启容器,重置所有状态
一句话区分执行逻辑:
启动探针:等容器跑完初始化
就绪探针:管流量进不进
存活探针:管容器死不死、要不要重启
⚙️ 三大探针核心区别对照表
| 探针类型 | 核心目标 | 探测失败动作 | 影响范围 | 适用场景 |
| StartupProbe 启动探针 | 等待容器缓慢启动 | 重启容器 | 整个Pod生命周期前置阶段 | Java、ES、Kafka、数据库等慢启动应用 |
| LivenessProbe 存活探针 | 检测容器是否僵死 | 重启容器 | 自愈、恢复异常容器 | 进程卡死、死锁、服务无响应 |
| ReadinessProbe 就绪探针 | 检测容器能否接流量 | 摘除流量,不重启 | Service/Ingress 流量转发 | 初始化未完成、服务过载、依赖异常 |
🚀 生产最佳实践 & 避坑指南
1. 配置原则
- 慢启动应用(Java 为主):必须配 StartupProbe不要单纯靠调大 liveness 的
initialDelaySeconds,启动探针是专门解决方案。 - HTTP 服务优先使用 httpGet,标准健康接口
/health//actuator/health - TCP 服务(MySQL/Redis)优先使用 tcpSocket,简单高效
- 自定义复杂检查(脚本、多条件)使用
exec
2. 常见坑
坑1:探针超时/间隔设置过小,导致误杀
- 现象:业务正常,频繁重启 Pod
- 原因:探测超时太短、并发高时健康接口响应慢 → 存活探针误判
- 解决:调大
timeoutSeconds、合理拉长periodSeconds
坑2:只配存活探针,不配就绪探针
- 现象:Pod 启动后立刻进流量,应用还没初始化完成,大量请求报错
- 解决:线上业务 Pod 建议双探针必配
坑3:启动探针参数太小,慢应用反复重启
- 现象:容器一直在重启循环,始终起不来
- 解决:加大
failureThreshold、periodSeconds,给足启动时间
坑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
💾 面试高频简答(精简背诵版)
- 三个探针分别作用?
- 启动探针:等待慢应用完成初始化,避免启动阶段误重启;
- 存活探针:检测容器僵死,异常则重启容器自愈;
- 就绪探针:判断容器是否可接收流量,失败则从负载均衡中摘除,不重启容器。
- 探针由谁执行?
节点上的 kubelet 本地执行,不经过 Master 组件。 - 就绪探针失败会重启 Pod 吗?
不会,只会剥离流量,Pod 继续运行。 - 为什么 Java 应用建议配置启动探针?
JVM 启动、类加载、框架初始化耗时较长,直接使用存活探针容易探测失败,导致反复重启。
关联文档
- K8s 滚动更新与发布策略 — 滚动更新中的探针配合
- K8s StatefulSet 详解 — StatefulSet 探针配置
- 面试题/K8s 进阶面试题 — 探针相关面试题
关联文档