K8s学习笔记(十六) 探针(Probe)

在 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 探针调试:如何排查失败问题?

如果探针失败(比如容器被频繁重启、无法接收流量),可通过以下方式排查:

  1. 查看 Pod 事件(最直接):

    bash 复制代码
    kubectl 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 连接失败)
  2. 查看容器日志(检查应用内部错误):

    bash 复制代码
    kubectl logs <pod名称> -c <容器名称>

    比如应用日志中可能有 "数据库连接失败",导致就绪探针失败。

  3. 手动模拟探针检查(在 Node 上执行):

    如果是 HTTP 检查,可在容器所在 Node 上用curl测试:

    bash 复制代码
    # 进入Node后执行(需知道Pod的IP和端口)
    curl -I <pod-ip>:<port>/<path>  # 查看返回状态码

7 总结

探针是 K8s 保障应用可用性的 "核心诊断工具",记住 3 个核心点:

  • 存活探针:保证容器 "活着且能工作",失败则重启;
  • 就绪探针:保证流量只发给 "能处理请求" 的容器,失败则隔离;
  • 启动探针:给慢启动应用 "缓冲时间",避免启动中被误判。
相关推荐
初圣魔门首席弟子4 小时前
C++ STL 向量(vector)学习笔记:从基础到实战
c++·笔记·学习
qiangshang9901265 小时前
WPF+MVVM入门学习
学习·wpf
iconball5 小时前
个人用云计算学习笔记 --20 (Nginx 服务器)
linux·运维·笔记·学习·云计算
生物小卡拉5 小时前
R脚本--表达矩阵与特征矩阵相关性分析
笔记·学习·机器学习
liliangcsdn5 小时前
从LLM角度学习和了解MoE架构
人工智能·学习·transformer
能不能别报错6 小时前
K8s学习笔记(十四) DaemonSet
笔记·学习·kubernetes
报错小能手6 小时前
linux学习笔记(19)进程间通讯——消息队列
linux·笔记·学习
进击的圆儿6 小时前
【学习笔记05】C++11新特性学习总结(下)
c++·笔记·学习
低音钢琴7 小时前
【碎片化学习】工具文:计算机通用术语中常见的100个英文单词
学习