K8S配置存活、就绪和启动探针

这篇文章讲解了如何为容器配置 存活(Liveness)探针、就绪(Readiness)探针 和 启动(Startup)探针,让 Kubernetes 能够更智能地管理应用的运行状态。

三种探针的作用

  1. 存活探针(Liveness Probe)
    作用:判断容器是否仍然存活,如果探针失败,Kubernetes 就会自动重启该容器。
    适用场景:比如应用发生 死锁(程序卡住但进程仍在运行),存活探针可以及时检测并触发重启,提高应用的可用性。
    常见做法:通常使用 HTTP 请求 或 命令 来检测,并设置较高的 failureThreshold(失败阈值),避免误判导致频繁重启。
  2. 就绪探针(Readiness Probe)
    作用:判断容器是否已经准备好接受流量。如果探针失败,该 Pod 不会被加入负载均衡,避免未准备好的实例接收请求。
    适用场景:应用启动后可能需要进行初始化,如加载配置或建立数据库连接,等这些操作完成后才能正常工作。
    影响:如果 Pod 处于未就绪状态,它将从 Service 负载均衡器 中移除,避免影响业务。
  3. 启动探针(Startup Probe)
    作用:专门用于检测应用是否完成启动。如果应用启动时间较长,可以用 启动探针 来防止 Kubernetes 过早启动存活和就绪探针,避免容器在启动阶段就被误判为失败。
    适用场景:适合 启动慢 的应用,比如需要执行大量初始化操作的服务。

使用建议

  • 存活探针 适用于检测应用发生无法恢复的故障(如死锁)。
  • 就绪探针 适用于控制 Pod 是否能加入流量分发,确保只有状态正常的实例才会对外提供服务。
  • 启动探针 适用于启动时间较长的应用,避免因存活探针误判导致应用在启动过程中被杀掉。

注意事项

⚠ 存活探针的误配置可能会导致级联故障,比如:

  • 在高负载下频繁重启容器,影响业务稳定性。
  • 由于错误的存活探针配置,导致应用无法扩展或请求失败。
  • 某些 Pod 失败后,剩余 Pod 承担更大负载,进一步加剧问题。

因此,在使用存活探针时,一定要确保它真正标识的是不可恢复的故障,而不是暂时性的短暂问题。

探针的使用示例

  1. 存活探针(Liveness Probe)HTTP探活示例

场景:某个 Web 服务在运行过程中可能会进入死锁状态,进程仍然存活,但不再响应请求。我们可以使用 HTTP 探针检测服务是否仍然可用,如果失败,就让 Kubernetes 重启容器。

1
2
3
4
5
6
7
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5 # 容器启动后 5 秒开始探测
periodSeconds: 10 # 每 10 秒探测一次
failureThreshold: 3 # 连续 3 次失败才会触发重启

完整示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 2 # 部署 2 个副本
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: my-app:latest # 替换成你的镜像
ports:
- containerPort: 8080 # 容器暴露的端口

# 存活探针 Liveness Probe
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5 # 容器启动 5 秒后开始检测
periodSeconds: 10 # 每 10 秒检测一次
failureThreshold: 3 # 连续 3 次失败才会重启容器

解释:

  • httpGet:访问 /health 端点检查存活状态。
  • initialDelaySeconds:等待 5 秒再开始探测,防止应用未启动完成时被误判。
  • periodSeconds:每 10 秒检测一次。
  • failureThreshold:如果探测 3 次都失败,则重启容器。
  1. 就绪探针(Readiness Probe)命令探活示例

场景:某个数据库服务在启动后需要 30 秒 才能准备好处理请求,我们使用就绪探针避免它在未准备好的情况下接收流量。

1
2
3
4
5
6
readinessProbe:
exec:
command: ["pg_isready", "-U", "postgres"]
initialDelaySeconds: 5 # 容器启动 5 秒后开始探测
periodSeconds: 10 # 每 10 秒探测一次
failureThreshold: 2 # 允许 2 次失败

解释:

  • exec:执行 pg_isready 检查 PostgreSQL 数据库是否就绪。
  • 只有探针成功,Pod 才会加入负载均衡,否则 Kubernetes 不会将流量分配给它。
  1. 启动探针(Startup Probe)TCP探活示例

场景:某个 Java 应用需要 2 分钟 才能完成初始化,但存活探针在 30 秒内就开始检测,可能会导致容器被误杀。使用 启动探针 让 Kubernetes 等待应用真正启动后,再启用存活和就绪探针。

1
2
3
4
5
6
startupProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 10 # 10 秒后开始检测
periodSeconds: 5 # 每 5 秒探测一次
failureThreshold: 24 # 失败 24 次才会判定启动失败 (24 x 5s = 120s)

解释:

  • tcpSocket:检查端口 8080 是否开启,代表应用已经启动。
  • failureThreshold: 24 配合 periodSeconds: 5,意味着 Kubernetes 会等待 2 分钟(24 × 5 秒) 才会放弃启动。

实际应用场景总结

探针类型 作用 适用场景 可能问题
存活探针 确保容器未死锁 API 服务器、长期运行的服务 误配置可能导致应用高负载时频繁重启
就绪探针 确保容器可接受流量 Web 服务器、数据库、缓存服务 误配置可能导致健康的 Pod 不能接收流量
启动探针 确保应用启动完成 启动时间长的应用(Java、数据库) 误配置可能导致容器被 Kubernetes 误判为启动失败

这些探针可以搭配使用,比如:

  • 启动探针 确保应用完成启动。
  • 存活探针 确保应用在运行过程中不会陷入死锁。
  • 就绪探针 确保应用可以正确处理流量。

这样可以最大程度提高应用的稳定性和可靠性! 🚀

Kubernetes 提供了三种探活方式(httpGet、tcpSocket、exec),每种方式的成功和失败标准如下:

探活方式 成功条件 失败条件
httpGet HTTP 响应码 200-399 HTTP 响应码 400+ 或连接失败(超时、目标端口未监听)
tcpSocket 能成功建立 TCP 连接 目标端口未监听或被防火墙拦截
exec 命令 返回 0(执行成功) 命令 返回非 0 或超时
  1. HTTP 探针(httpGet)

📌 方式:向指定的 HTTP 端点发送请求,根据 HTTP 响应码判断成功或失败。

✅ 成功条件:

  • HTTP 状态码 200-399 代表探针成功。

❌ 失败条件:

  • HTTP 状态码 400 及以上 代表探针失败(例如 404 Not Found、500 Internal Server Error)。
  • 目标端口未监听,或者 Pod 内部进程未正常运行,导致请求超时或连接失败。
  1. TCP 探针(tcpSocket)

📌 方式:尝试与指定端口建立 TCP 连接。

✅ 成功条件:

  • 能成功建立 TCP 连接(即端口处于监听状态)。

❌ 失败条件:

  • 目标端口未监听,导致连接失败(例如应用未启动或崩溃)。
  • 端口被防火墙拦截,导致无法访问。
  1. 命令探针(exec)

📌 方式:在容器内执行指定命令,根据命令的退出状态码判断成功或失败。

✅ 成功条件:

  • 退出码 0(代表命令执行成功)。

❌ 失败条件:

  • 退出码非 0(例如 1、127,代表执行失败)。
  • 命令不存在或执行超时。