在 Kubernetes 中,探针(Probe) 是 K8s 用来 "诊断容器状态" 的工具,就像给容器装了 "体检设备"。它通过定期检查容器的健康状况,让 K8s 能自动处理异常(比如重启故障容器、暂停流量转发),确保应用稳定运行。
1 为什么需要探针?
想象一个场景:
- 应用容器进程还在运行(
kubectl get pod
显示Running
),但内部发生死锁,无法处理请求("假活"); - 应用刚启动,还在加载配置,此时接收请求会报错("未就绪");
- 大型 Java 应用启动需要 5 分钟,启动过程中被误判为 "故障" 而重启("启动慢")。
没有探针时,K8s 无法识别这些状态,会导致服务异常。而探针能精准检测这些情况,触发对应处理逻辑。
2 3 种探针的核心区别
K8s 提供 3 种探针,分工明确,解决不同场景的问题:
探针类型 | 核心目标 | 失败后的行为 | 一句话总结 |
---|---|---|---|
存活探针(livenessProbe) | 检测容器 "是否还活着"(能否正常运行) | 触发容器重启(按restartPolicy 规则) |
"死了就重启,保证容器活着" |
就绪探针(readinessProbe) | 检测容器 "是否能接收请求"(是否准备好) | 从 Service 中移除,不接收新流量 | "没准备好就隔离,不影响服务" |
启动探针(startupProbe) | 检测容器 "是否启动完成"(针对慢启动应用) | 启动失败则重启容器 | "给慢启动应用足够时间,不被误杀" |
3 探针的 3 种检查方式
每种探针都可以通过以下 3 种方式检查容器状态,根据应用特性选择:
3.1 HTTP GET 检查(最常用)
向容器的某个 HTTP 接口发送请求(比如/health
),如果返回200~399之间的状态码,视为 "健康"。
适用场景:Web 应用(如 Spring Boot、Nginx、Node.js),通常会暴露健康检查接口。
示例(存活探针检查 Nginx 的/
路径):
yaml
livenessProbe:
httpGet:
path: / # 检查的URL路径
port: 80 # 容器内的端口(必须是容器暴露的端口)
scheme: HTTP # 可选,默认HTTP,HTTPS需指定
initialDelaySeconds: 5 # 容器启动后,延迟5秒再开始第一次检查
periodSeconds: 10 # 每10秒检查一次
timeoutSeconds: 2 # 检查超时时间(超过2秒没响应视为失败)
3.2 TCP Socket 检查
尝试与容器的某个端口建立 TCP 连接,如果连接成功(三次握手完成),视为 "健康"。
适用场景:非 HTTP 服务(如 MySQL、Redis、MongoDB、SSH 等基于 TCP 的服务)。
示例(就绪探针检查 MySQL 的 3306 端口):
yaml
readinessProbe:
tcpSocket:
port: 3306 # 检查3306端口是否能连接
initialDelaySeconds: 15 # MySQL启动慢,延迟15秒开始检查
periodSeconds: 20 # 每20秒检查一次
failureThreshold: 3 # 连续3次失败才视为"未就绪"
3.3 Exec 命令检查
在容器内执行一条 Linux 命令,如果命令的退出状态码为 0(成功),视为 "健康"。
适用场景:需要自定义逻辑检查的场景(如检查文件是否存在、配置是否正确、进程是否运行)。
示例(存活探针检查/tmp/healthy
文件是否存在):
yaml
livenessProbe:
exec:
command: ["test", "-f", "/tmp/healthy"] # 执行`test -f`命令检查文件
initialDelaySeconds: 5
periodSeconds: 5
4 探针的关键参数(所有探针通用)
这些参数控制探针的执行逻辑,必须根据应用特性调整(否则可能误判):
参数 | 含义(默认值) | 调优建议 |
---|---|---|
initialDelaySeconds |
容器启动后,延迟多久开始第一次检查(0 秒) | 启动慢的应用(如 Java)设大些(30~60 秒);启动快的(如 Nginx)设小些(5 秒)。 |
periodSeconds |
检查的间隔时间(10 秒) | 高频服务(如 API)可设短些(5 秒);资源紧张场景设长些(20 秒)。 |
timeoutSeconds |
每次检查的超时时间(1 秒) | 网络请求或命令执行慢的场景,适当调大(如 3 秒)。 |
successThreshold |
连续几次成功视为 "健康"(1 次) | 不稳定的检查(如偶发网络波动),可设为 2 次。 |
failureThreshold |
连续几次失败视为 "不健康"(3 次) | 不希望频繁触发重启 / 隔离的场景,可设为 5 次。 |
5 3 种探针的实战场景与配置
5.1 存活探针(livenessProbe):解决 "假活" 问题
场景:应用进程未崩溃,但内部故障(如死锁、内存泄漏导致无法响应)。
目标:发现后重启容器,恢复服务。
示例(Java 应用的存活检查):
yaml
apiVersion: v1
kind: Pod
metadata:
name: java-app
spec:
containers:
- name: app
image: my-java-app:v1
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /actuator/health # Spring Boot的健康检查接口
port: 8080
initialDelaySeconds: 60 # Java启动慢,给60秒初始化
periodSeconds: 15 # 每15秒检查一次
failureThreshold: 3 # 连续3次失败则重启
5.2 就绪探针(readinessProbe):解决 "未就绪接收流量" 问题
场景:容器已启动,但依赖的服务(如数据库)未就绪,或正在加载缓存(此时接收请求会报错)。
目标:未就绪时不接收流量,就绪后自动加入服务。
示例(依赖数据库的 Web 应用):
yaml
apiVersion: v1
kind: Pod
metadata:
name: web-with-db
spec:
containers:
- name: web
image: my-web-app:v1
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /ready # 应用自定义的"就绪接口"(依赖数据库连接成功才返回200)
port: 80
initialDelaySeconds: 5 # 启动后5秒开始检查
periodSeconds: 3 # 频繁检查,一旦就绪立即接收流量
5.3 启动探针(startupProbe):解决 "慢启动被误杀" 问题
场景:应用启动耗时很长(如大型数据分析服务、初始化数据量巨大的数据库),启动过程中存活探针会误判为 "故障" 而重启。
目标:启动探针成功前,暂停存活 / 就绪探针,确保启动完成。
示例(启动需 5 分钟的服务):
yaml
apiVersion: v1
kind: Pod
metadata:
name: slow-start-app
spec:
containers:
- name: app
image: slow-app:v1
ports:
- containerPort: 9000
# 启动探针:最多等5分钟(300秒)
startupProbe:
httpGet:
path: /started # 应用启动完成后才返回200的接口
port: 9000
failureThreshold: 30 # 30 * 10秒 = 300秒超时
periodSeconds: 10
# 启动完成后,才开始存活检查
livenessProbe:
httpGet:
path: /health
port: 9000
periodSeconds: 10
6 探针调试:如何排查失败问题?
如果探针失败(比如容器被频繁重启、无法接收流量),可通过以下方式排查:
-
查看 Pod 事件(最直接):
bashkubectl describe pod <pod名称>
事件中会显示探针失败原因,例如:
Liveness probe failed: HTTP probe failed with statuscode: 500
(存活探针 HTTP 返回 500)Readiness probe failed: dial tcp 10.244.1.5:3306: connect: connection refused
(就绪探针 TCP 连接失败)
-
查看容器日志(检查应用内部错误):
bashkubectl logs <pod名称> -c <容器名称>
比如应用日志中可能有 "数据库连接失败",导致就绪探针失败。
-
手动模拟探针检查(在 Node 上执行):
如果是 HTTP 检查,可在容器所在 Node 上用
curl
测试:bash# 进入Node后执行(需知道Pod的IP和端口) curl -I <pod-ip>:<port>/<path> # 查看返回状态码
7 总结
探针是 K8s 保障应用可用性的 "核心诊断工具",记住 3 个核心点:
- 存活探针:保证容器 "活着且能工作",失败则重启;
- 就绪探针:保证流量只发给 "能处理请求" 的容器,失败则隔离;
- 启动探针:给慢启动应用 "缓冲时间",避免启动中被误判。