【Kubernetes】 的三个Probe

1.三种Probe

  • startupProbe应用启动了吗?
  • readinessProbe应用现在能接收流量吗?
  • livenessProbe应用是不是还活着?

Startup 管启动,Readiness 管流量,Liveness 管存活。

2. 三种 Probe 的区别

Probe 作用 失败后的主要行为
startupProbe 判断应用是否完成启动 连续失败达到阈值 → 重启容器
readinessProbe 判断应用是否可以接收流量 失败 → Pod NotReady,从正常流量 Endpoint 中摘除
livenessProbe 判断应用是否已经异常/卡死 连续失败达到阈值 → 重启容器

2.1 Startup Probe

作用

用于判断:

应用是否已经成功启动。

主要用于启动比较慢的应用,例如:

  • Spring Boot
  • Java 应用
  • 需要加载大量数据的应用
  • 启动时需要初始化数据库、缓存等的应用

例如:

yaml 复制代码
startupProbe:
  httpGet:
    path: /actuator/health
    port: 8080
  periodSeconds: 10
  failureThreshold: 30

表示:

  • 每 10 秒检查一次
  • 连续失败 30 次后认为启动失败
  • 大致给应用最多 5 分钟的启动时间
text 复制代码
10s × 30 = 300s = 5分钟

如果超过这个时间仍然没有成功:

text 复制代码
Startup Probe
      ↓
连续失败达到 failureThreshold
      ↓
认为容器启动失败
      ↓
kubelet 重启容器

Startup Probe 成功之前

如果配置了 Startup Probe:

text 复制代码
Container 启动
      ↓
Startup Probe
      ↓
   ❌ ❌ ❌
      ↓
继续等待

在 Startup Probe 成功之前:

  • Liveness Probe 不会执行
  • Readiness Probe 不会执行

当 Startup Probe 成功:

text 复制代码
Startup Probe ✅
      ↓
开始执行 Liveness Probe
开始执行 Readiness Probe

因此 Startup Probe 可以理解为:

给慢启动应用提供一个启动保护期。

2.2 Readiness Probe

作用

Readiness Probe 判断:

这个 Pod 现在能不能接收流量?

例如:

yaml 复制代码
readinessProbe:
  httpGet:
    path: /actuator/health/readiness
    port: 8080
  periodSeconds: 10
  failureThreshold: 3

假设检查失败:

text 复制代码
Readiness Probe ❌
       ↓
Pod NotReady
       ↓
不作为 Service 的正常 Ready Endpoint
       ↓
Service 不给它转发正常流量

非常重要

Readiness Probe 失败不会重启容器。

例如:

text 复制代码
应用进程       ✅
容器           Running
Liveness       ✅
Readiness      ❌

结果:

text 复制代码
Pod:
Running + NotReady

2.2.1 Readiness 一直失败会怎么样?

这是很容易产生疑问的地方。

假设:

yaml 复制代码
periodSeconds: 10
failureThreshold: 3

连续失败:

text 复制代码
0s      ❌
10s     ❌
20s     ❌
        ↓
     NotReady

但是 NotReady 之后并不会停止检测

它仍然会:

text 复制代码
30s     ❌
40s     ❌
50s     ❌
60s     ❌
...

如果一直失败:

Pod 就一直保持 NotReady

但如果应用恢复:

text 复制代码
100s    ❌
110s    ❌
120s    ✅
        ↓
      Ready
        ↓
重新加入正常流量 Endpoint

所以 Readiness Probe 实际上是一个动态流量开关

text 复制代码
Readiness
    │
    ├── ✅ Ready
    │      ↓
    │    接收流量
    │
    └── ❌ NotReady
           ↓
        不接收流量

2.3 Liveness Probe

作用

Liveness Probe 判断:

应用是不是已经死了、卡死了或者处于无法正常工作的状态。

例如:

yaml 复制代码
livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
  periodSeconds: 10
  failureThreshold: 3

如果连续失败:

text 复制代码
Liveness ❌
     ↓
连续失败达到 failureThreshold
     ↓
kubelet 判断容器异常
     ↓
重启 Container

所以:

Liveness 失败主要用于触发容器重启。

例如应用发生死锁:

text 复制代码
Container:Running
进程:存在
但是应用已经无法正常响应
       ↓
Liveness Probe ❌
       ↓
重启 Container

3. 三种 Probe 的关系

可以用下面这个流程理解:

text 复制代码
                 Container 启动
                       │
                       ▼
                Startup Probe
                       │
                 是否启动完成?
                  │          │
                 ❌          ✅
                  │          │
                  │          ▼
                  │    ┌───────────────┐
                  │    │               │
                  │    ▼               ▼
                  │ Readiness       Liveness
                  │    │               │
                  │    ▼               ▼
                  │ 能接流量吗?      还活着吗?
                  │    │               │
                  │    │               │
                  │ ❌ → NotReady   ❌ → 重启
                  │
                  ▼
              启动失败 → 重启

4. Probe 的探测方式

Probe 需要解决一个问题:

Kubernetes 到底通过什么方式检查我的应用?

Kubernetes 常见有四种探测方式:

  1. httpGet
  2. tcpSocket
  3. exec
  4. grpc

4.1 httpGet

最常见的方式。

Kubernetes 向容器发送 HTTP 请求。

例如:

yaml 复制代码
readinessProbe:
  httpGet:
    path: /ready
    port: 8080

实际上就是检查:

text 复制代码
http://PodIP:8080/ready

如果返回正常的 HTTP 状态码,就认为检查成功。

一般来说:

text 复制代码
200 ~ 399 → 成功
其他      → 失败

适合场景

非常适合:

  • Spring Boot
  • Gin
  • Node.js
  • Web API
  • HTTP 服务

例如 Spring Boot:

yaml 复制代码
livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080

readinessProbe:
  httpGet:
    path: /actuator/health/readiness
    port: 8080

4.2 tcpSocket

检查 TCP 端口是否能够建立连接。

例如:

yaml 复制代码
readinessProbe:
  tcpSocket:
    port: 8080

Kubernetes 会尝试连接:

text 复制代码
PodIP:8080

如果 TCP 连接成功:

text 复制代码
TCP Connect
     ↓
    成功

Probe 就成功。

如果:

text 复制代码
Connection refused
Timeout

则失败。

适合场景

例如:

text 复制代码
MySQL       3306
Redis       6379
PostgreSQL  5432

或者一些没有 HTTP Health API 的 TCP 服务。


4.3 exec

在容器内部执行命令。

例如:

yaml 复制代码
livenessProbe:
  exec:
    command:
      - cat
      - /tmp/healthy

Kubernetes 相当于进入容器执行:

bash 复制代码
cat /tmp/healthy

如果:

text 复制代码
exit code = 0

表示成功。

如果:

text 复制代码
exit code != 0

表示失败。

适合场景

一些特殊的、自定义的健康检查。

不过如果应用本身已经提供 HTTP/gRPC Health Check,通常优先考虑 HTTP/gRPC,而不是复杂的 exec


4.4 grpc

针对 gRPC 服务。

例如:

yaml 复制代码
livenessProbe:
  grpc:
    port: 50051

Kubernetes 会使用 gRPC Health Checking Protocol 检查服务。

适合:

text 复制代码
gRPC Server
     ↓
实现标准 Health Checking
     ↓
grpc Probe

5. 四种探测方式总结

探测方式 检查内容 常见场景
httpGet HTTP 请求 Web/API
tcpSocket TCP 端口 TCP 服务、数据库等
exec 容器内执行命令 自定义检查
grpc gRPC Health Check gRPC 服务

一个 Probe 只能选择一种探测方式

yaml 复制代码
readinessProbe:
  httpGet:
    ...

不能同时:

yaml 复制代码
readinessProbe:
  httpGet:
    ...
  tcpSocket:
    ...

6. Probe 的常见配置参数

yaml 复制代码
readinessProbe:
  httpGet:
    path: /ready
    port: 8080

  initialDelaySeconds: 10
  periodSeconds: 10
  timeoutSeconds: 2
  failureThreshold: 3
  successThreshold: 1

重点:

参数 含义
initialDelaySeconds 第一次探测前等待多久
periodSeconds 多久探测一次
timeoutSeconds 一次探测最多等待多久
failureThreshold 连续失败多少次才判定失败
successThreshold 连续成功多少次才判定恢复

7. initialDelaySeconds

表示:

容器启动后,等待多久才开始第一次探测。

例如:

yaml 复制代码
initialDelaySeconds: 30

表示:

text 复制代码
Container 启动
     ↓
等待 30 秒
     ↓
第一次 Probe

不过如果配置了 startupProbe,通常应该让 Startup Probe 来负责慢启动保护,而不是大量依赖 initialDelaySeconds


8. periodSeconds

表示:

Probe 多久执行一次。

例如:

yaml 复制代码
periodSeconds: 10

表示大致:

text 复制代码
Probe
 ↓
10秒
 ↓
Probe
 ↓
10秒
 ↓
Probe
 ↓
10秒
 ↓
...

默认值:

text 复制代码
10 秒

9. timeoutSeconds

表示:

一次 Probe 最多允许执行多长时间。

例如:

yaml 复制代码
timeoutSeconds: 2

如果 HTTP 请求:

text 复制代码
0s ───────── 2s
             ↓
         还没有响应
             ↓
           失败

就会认为这次探测失败。

默认值:

text 复制代码
1 秒

10. failureThreshold

表示:

连续失败多少次,才判定 Probe 失败。

默认:

text 复制代码
3

例如:

yaml 复制代码
periodSeconds: 10
failureThreshold: 3

如果连续:

text 复制代码
第一次 ❌
第二次 ❌
第三次 ❌
       ↓
   判定失败

但是要注意:

它不是"失败 3 次以后就停止检查"。

尤其对于 Readiness:

text 复制代码
NotReady
   ↓
继续检查
   ↓
❌
   ↓
继续检查
   ↓
❌
   ↓
...
   ↓
✅
   ↓
Ready

11. successThreshold

表示:

连续成功多少次,才判定 Probe 恢复成功。

默认:

text 复制代码
1

例如:

yaml 复制代码
successThreshold: 3

Readiness 当前是 NotReady

text 复制代码
第一次 ✅
第二次 ✅
第三次 ✅
       ↓
      Ready

特别注意

successThreshold

  • readinessProbe:可以设置大于 1
  • livenessProbe:必须是 1
  • startupProbe:必须是 1

因此实际使用中,successThreshold 最常用于控制 Readiness 的恢复条件。


12. 默认值

参数 默认值
initialDelaySeconds 0
periodSeconds 10
timeoutSeconds 1
failureThreshold 3
successThreshold 1

所以:

yaml 复制代码
readinessProbe:
  httpGet:
    path: /ready
    port: 8080

如果不写这些参数,就会使用 Kubernetes 的默认值。


13. 一个完整例子

以 Spring Boot 为例:

yaml 复制代码
startupProbe:
  httpGet:
    path: /actuator/health
    port: 8080
  periodSeconds: 10
  failureThreshold: 30

readinessProbe:
  httpGet:
    path: /actuator/health/readiness
    port: 8080
  periodSeconds: 5
  failureThreshold: 3
  successThreshold: 1

livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
  periodSeconds: 10
  failureThreshold: 3

它的工作流程可以理解为:

text 复制代码
                Container 启动
                      │
                      ▼
                Startup Probe
                      │
              ┌───────┴───────┐
              │               │
             ❌              ✅
              │               │
        失败达到30次          │
              │               ▼
              ▼         Readiness Probe
           重启容器              │
                              │
                       ┌──────┴──────┐
                       │             │
                      ❌            ✅
                       │             │
                       ▼             ▼
                   NotReady        Ready
                       │             │
                       │             ▼
                       │        接收流量
                       │
                       └──继续检测───┐
                                    │
                                    ▼
                              恢复后重新Ready


                 Liveness Probe
                       │
                  连续失败3次
                       │
                       ▼
                    重启容器

14. 最终记忆版

如果只想记住最核心的东西,可以记下面这张表:

概念 记忆
startupProbe 启动了吗?
readinessProbe 能接流量吗?
livenessProbe 还活着吗?
httpGet 发 HTTP 请求
tcpSocket 检查 TCP 端口
exec 执行容器内命令
grpc gRPC Health Check
periodSeconds 多久检查一次
timeoutSeconds 一次最多等多久
failureThreshold 连续失败几次才算失败
successThreshold 连续成功几次才算恢复
initialDelaySeconds 第一次检查前等多久

Startup 失败 → 重启容器。
Liveness 失败 → 重启容器。
Readiness 失败 → 摘掉流量,但不重启容器。

相关推荐
猫吃了源码6 小时前
k9s简介和安装
linux·docker·kubernetes
云原生指北7 小时前
Docker Sandboxes 上手:从安装到第一次跑 Agent
运维·docker·容器
heimeiyingwang9 小时前
【架构实战】Kubernetes故障排查全景图:从Pod异常到集群雪崩的诊断手册
容器·架构·kubernetes
骇客野人10 小时前
Docker Compose 部署多个独立 Jar 服务完整实操步骤
docker·容器·jar
AAA@峥10 小时前
K8s 资源管控:ResourceQuota 与 LimitRange 机制详解与实战
云原生·容器·kubernetes
daoihfoaf10 小时前
太原助听器品质甄选
容器
秦渝兴11 小时前
Ansible 自动化部署 K8s 三节点集群(完整教程)
kubernetes·自动化·ansible
云川之下12 小时前
【k8s】Docker inspect 命令
docker·容器·kubernetes
猫吃了源码13 小时前
CentOS7使用Kubeadm安装部署K8s(Kubernetes)最新稳定版本1.26.x
云原生·容器·kubernetes