首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >别让探针害了你:一次价值百万的Kubernetes健康检查惨案

别让探针害了你:一次价值百万的Kubernetes健康检查惨案

作者头像
用户5741377
发布2026-06-22 21:33:46
发布2026-06-22 21:33:46
1560
举报

一、事故现场:凌晨的噩梦

凌晨 2 点,某金融公司监控系统报警:支付服务异常中断。几分钟内,多个微服务进入“CrashLoopBackOff”状态,业务全面瘫痪。

短短 37 分钟,交易中断造成直接经济损失超百万元。

事后排查发现——罪魁祸首竟是一个看似无害的配置项:存活探测(Liveness Probe)

在这次事故中,探测路径 /healthz 被配置为判断容器是否“活着”,但该路径在应用完全启动前即能响应 200 状态码。 结果 Kubernetes 误以为容器“活着”,但实际上核心模块尚未加载完成,服务无法响应外部请求。探针持续判定失败 → Pod 被不断重启 → 所有实例陷入“死亡循环”。

一句话总结: 👉 探针没错,错的是我们不理解它。

二、两个探针,两个世界

很多开发者、甚至资深运维都对这两个探针的作用模糊不清。 要真正避免类似事故,必须理解它们的本质区别。

1️⃣ 存活探测(Liveness Probe)

问题:应用程序是不是“死”了?

  • 失败后果:Kubernetes 重启容器
  • 适用场景:检测程序死锁、线程卡死、不可恢复异常
  • 关键原则必须幂等,不能因重启带来副作用

示例配置:

代码语言:javascript
复制
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 30   # 必须大于应用最长启动时间
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 3

2️⃣ 就绪探测(Readiness Probe)

问题:应用程序准备好接收流量了吗?

  • 失败后果:Pod 从 Service 负载列表中移除
  • 适用场景:应用启动缓慢、初始化资源、外部依赖未就绪
  • 关键原则保护应用免受未准备好的流量冲击

示例配置:

代码语言:javascript
复制
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5
  failureThreshold: 2

📘 一句话总结区别:

存活探测负责“活着”,就绪探测负责“能干活”。

三、实战:健康检查的正确打开方式

1. HTTP 检查(最常用)

代码语言:javascript
复制
httpGet:
  path: /health
  port: 8080

适合 Web 服务,返回 200 即视为成功。

2. Exec 检查(执行命令)

代码语言:javascript
复制
exec:
  command: ["cat", "/tmp/healthy"]

3. TCP Socket 检查

代码语言:javascript
复制
tcpSocket:
  port: 3306

适用于数据库、Redis 等非 HTTP 服务,只检查端口连通性。

四、三个真实场景下的最佳实践

场景一:启动依赖多,加载时间长

代码语言:javascript
复制
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 20
  failureThreshold: 10  # 给依赖服务充分启动时间

启动慢不是错,错的是没告诉探针“等等我”。

场景二:存活探测太“勤快”导致雪崩

代码语言:javascript
复制
livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 60
  periodSeconds: 30
  failureThreshold: 2

探测频繁 + 超时太短 = 自己把自己打死

场景三:数据库服务混合探测

代码语言:javascript
复制
livenessProbe:
  tcpSocket:
    port: 3306
  initialDelaySeconds: 300

readinessProbe:
  exec:
    command:
    - mysql
    - -h127.0.0.1
    - -e
    - "SELECT 1"

先探活,再探“能不能用”。

五、常见坑与解决方案

常见问题

典型症状

正确做法

存活探测太敏感

Pod 无限重启

调大 failureThreshold、延长 initialDelaySeconds

就绪探测路径错误

Pod 永远未就绪

确保探测路径返回 200 状态码

探测逻辑太重

应用 CPU 飙升

使用轻量级接口,如内存级变量判断

忽略启动顺序

应用依赖未就绪

结合 Init Container 或延时策略

六、快速排查思路

查看探针事件

代码语言:javascript
复制
kubectl describe pod <pod-name>

重点关注:

代码语言:javascript
复制
Liveness probe failed: container will be restarted
Readiness probe failed: container will be removed from service endpoints

查看Pod日志

代码语言:javascript
复制
kubectl logs <pod-name>

检查Pod就绪状态

代码语言:javascript
复制
kubectl get pods -o wide

READY 一列显示:当前就绪容器数/总容器数。

七、结语:健康检查不是装饰,而是生死线

Liveness ProbeReadiness Probe 是 Kubernetes 自愈与高可用的核心机制。 正确使用它们,可以:

  • 自动恢复故障实例
  • 实现零停机部署
  • 防止流量雪崩
  • 提升系统韧性

反之,一个配置错误,可能让集群在凌晨全线崩溃。

在 Kubernetes 世界里,健康探针不是“锦上添花”,而是“保命符”。

✅ 检查清单(送你一句话总结) 探针类型判断问题失败后果建议策略Liveness活着没?重启容器慢一点、稳一点Readiness能干活吗?下线流量灵敏一点、轻一点 💡 温馨提醒 现在,回头检查你的 Pod YAML —— 是否有探针配置太激进?路径是否正确?延时是否充足? 别等到下一个凌晨,才发现代价有多大。

END

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-10-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DevOps和k8s全栈技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、两个探针,两个世界
    • 1️⃣ 存活探测(Liveness Probe)
    • 2️⃣ 就绪探测(Readiness Probe)
  • 三、实战:健康检查的正确打开方式
    • 1. HTTP 检查(最常用)
  • 四、三个真实场景下的最佳实践
    • ✅ 场景一:启动依赖多,加载时间长
  • 六、快速排查思路
    • 查看探针事件
    • 查看Pod日志
    • 检查Pod就绪状态
  • 七、结语:健康检查不是装饰,而是生死线
    • ✅ 检查清单(送你一句话总结) 探针类型判断问题失败后果建议策略Liveness活着没?重启容器慢一点、稳一点Readiness能干活吗?下线流量灵敏一点、轻一点 💡 温馨提醒 现在,回头检查你的 Pod YAML —— 是否有探针配置太激进?路径是否正确?延时是否充足? 别等到下一个凌晨,才发现代价有多大。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档