Kubernetes (k8s) 中的 探针 (Probes) 是用于检测容器健康状况和可用性的核心机制。它们让 kubelet 能够决定何时重启容器(存活探针)、何时将流量路由到容器(就绪探针)以及何时认为容器已成功启动(启动探针)。主要目的是提高应用的自愈能力和可靠性,防止将流量发送到无法正常处理请求的容器。
一.常用探针类型
1.存活探针(Liveness Probe)
- 目的:检测容器是否仍在正常运行。如果探测失败,kubelet 会认为容器已经死锁或进入不可恢复状态,杀死并重启该容器。
- 何时使用:当你的应用在遇到内部错误(如死锁、资源耗尽)时可能会停止响应,但进程本身还在运行。重启容器通常是恢复服务的最佳方式。
- 关键点: 失败 → 容器重启。
2.就绪探针(Readiness Probe)
- 目的:检测容器是否已准备好接收流量。如果探测失败,kubelet 会将该容器从关联的 Service 的 Endpoints 列表中移除。这意味着该容器将不会接收到任何新的客户端请求(来自 Service 的流量)。
- 何时使用:容器启动后需要加载大量数据或配置文件才能提供服务;容器暂时过载,无法处理更多请求;容器依赖的外部服务(如数据库、缓存)暂时不可用。
- 关键点:失败 → 容器从 Service 负载均衡池中摘除 → 不会重启容器。
3.启动探针(Startup Probe)
- 目的:检测容器内的应用是否已成功启动。在启动探针成功之前,所有其他探针(存活、就绪)都会被禁用。如果启动探针失败,kubelet 会杀死容器并根据其重启策略进行处理(通常是重启)。启动探针的主要目的是保护启动慢的应用不被kill,而不是替代就绪检查。
- 何时使用:主要用于处理那些启动时间特别长的应用(例如,需要几分钟初始化的大型 Java 应用)。它允许你为慢启动的应用配置一个较长的初始检查期限,而不用担心存活探针在应用完成启动前就将其杀死。
- 关键点:失败 → 容器重启(按重启策略)。成功之前禁用其他探针。
二、探测方式
每种探针都需要定义一种方法来执行检查(probe handler),Kubernetes 支持三种类型的检查机制。
1. exec(执行命令)
在容器内执行指定的命令,根据返回值判断执行结果。返回值为0或非0,退出状态码为 0,则认为探测成功;否则认为失败。有点类似于"echo $?"。
# 存活探针,周期性检查服务是否存活,检查结果失败,将重启容器。
livenessProbe:
# 使用exec的方式去做健康检查
exec:
# 自定义检查的命令
command:
- cat
- /tmp/healthy
# 检测服务失败次数的累加值,默认值是3次,最小值是1。当检测服务成功后,该值会被重置!
failureThreshold: 3
# 指定多久之后进行健康状态检查,即此时间段内检测服务失败并不会对failureThreshold进行计数。
initialDelaySeconds: 15
# 指定探针检测的频率,默认是10s,最小值为1.
periodSeconds: 1
# 检测服务成功次数的累加值,默认值为1次,最小值1.
successThreshold: 1
# 一次检测周期超时的秒数,默认值是1秒,最小值为1.
timeoutSeconds: 1
2. httpGet(http get请求)
向容器 IP 地址的指定端口和路径发送 HTTP GET 请求,根据返回的状态码来判断服务是否正常。如果响应的状态码在 200 到 399 之间,则认为探测成功;否则认为失败。
200: 返回状态码成功
301: 永久跳转
302: 临时跳转
401: 验证失败
403: 权限被拒绝
404: 文件找不到
413: 文件上传过大
500: 服务器内部错误
502: 无效的请求
504: 后端应用网关响应超时
...
# 就绪探针,周期性检查服务是否可用,从而判断容器是否就绪.
readinessProbe:
# 使用httpGet的方式去做健康检查
httpGet:
# 指定访问的端口号
port: 80
# 检测指定的访问路径
path: /index.html
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 1
3. tcpSocket(tcp套接字检查)
尝试在容器 IP 地址的指定端口上建立 TCP 连接,如果端口能够成功打开(建立连接),则认为探测成功;否则认为失败。类似于telnet,nc等测试工具。
# 存活探针,周期性检查服务是否存活,检查结果失败,将重启容器。
livenessProbe:
# 使用tcpSocket的方式去做健康检查
tcpSocket:
port: 80
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
三、探针参数详解
- initialDelaySeconds:容器启动后等待多少秒才开始进行第一次探测(非常重要! 避免应用还没启动完就被判失败)。
- periodSeconds:执行探测的间隔时间(秒),默认为 10 秒。
- timeoutSeconds:探测的超时时间(秒),超过此时间无响应则判为失败,默认为 1 秒。
- successThreshold:探测失败后,连续成功多少次才被判定为成功(主要用于恢复判断)。对于存活探针和启动探针必须是 1。
- failureThreshold:探测失败多少次后,才最终判定为失败(达到此次数后,kubelet 才会执行重启或摘除操作)。默认是3次
四、案例详解
1.nginx服务
[root@master-1 yaml]# cat nginx.yaml
apiVersion: apps/v1
kind: Deployment #容器控制器
metadata:
name: nginx
spec:
replicas: 1 #副本数1
selector:
matchLabels:
app: nginx #控制器选择 app=nginx (label)
template:
metadata:
labels:
app: nginx #模板的label: app=nginx
spec:
containers:
- name: nginx #容器名称
image: nginx:latest #镜像名称
imagePullPolicy: IfNotPresent
# --属于容器的部分
ports:
- containerPort: 80 #容器端口
readinessProbe: #容器就绪检测
tcpSocket:
port: 80 #检测端口
initialDelaySeconds: 5 #容器启动之后5秒检测
periodSeconds: 10 #容器初始化之后每隔10秒检测
livenessProbe: #容器存活检测
tcpSocket:
port: 80 #检测端口
initialDelaySeconds: 5 #容器启动之后5秒检测
periodSeconds: 10 #容器初始化之后每隔10秒检测
startupProbe: #容器启动检测
tcpSocket:
port: 80 #检测端口
initialDelaySeconds: 20 #容器启动之后5秒检测
periodSeconds: 10 #容器初始化之后每隔10秒检测
[root@master-1 yaml]# kubectl apply -f nginx.yaml
[root@master-1 yaml]# kubectl get pods
[root@master-1 yaml]# kubectl describe pod nginx-5b6c899d4c-7gqcs
如下图所示:服务在20s左右处于ready状态
2.Java服务示例
[root@master-1 yaml]# cat my-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:v1
ports:
- containerPort: 8080
# 启动探针 - 给慢启动应用足够时间
startupProbe:
httpGet:
path: /startup
port: 8080
initialDelaySeconds: 20 # 第一次检查前的等待
failureThreshold: 30 # 最多尝试 30 次
periodSeconds: 10 #总共允许最大启动时间(30 * 10s+20 = 320s)
# 存活探针 - 检查核心功能是否崩溃
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15 # 等启动探针成功后至少15秒才开始
periodSeconds: 10
timeoutSeconds: 3
# 就绪探针 - 检查是否可以接收流量
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5 # 容器启动后5秒开始检查
periodSeconds: 5
timeoutSeconds: 2
五、注意事项
1.initialDelaySeconds必须设置
这是最常见的错误来源。确保它足够长,让你的应用在首次探测前完成初始化。
2.区分存活与就绪
存活探针: 检查核心功能是否完全崩溃(需要重启)。
就绪探针: 检查是否暂时无法服务(需要从负载均衡移除)。就绪探针的检查条件通常比存活探针宽松。
3.慢应用使用启动探针
为慢启动应用使用启动探针: 避免存活探针在漫长的启动过程中杀死容器。
4.合理配置超时和阈值
根据应用的实际响应时间和网络环境调整 timeoutSeconds, failureThreshold, successThreshold。网络抖动时,适当增加 failureThreshold 可以避免误判。
六、总结
Kubernetes 探针是保障应用在集群中健康、稳定运行的关键机制。正确配置存活、就绪和启动探针,可以显著提高应用的韧性和用户体验,确保流量只被发送到真正准备好处理它的容器,并在容器内部故障时自动恢复。理解它们的区别、配置方式和最佳实践对于有效使用 Kubernetes 至关重要。