news 2026/6/10 9:33:03

【Kubernetes探针避坑指南】Kubernetes探针核心应用:3大场景+2个致命坑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Kubernetes探针避坑指南】Kubernetes探针核心应用:3大场景+2个致命坑

几年前我接手一个Java SpringBoot服务,K8s部署,看起来一切正常。结果上线后每周总有那么两三次,凌晨三点被告警轰炸——“502 Bad Gateway”。查了半天,发现Pod状态是Running,但实际业务线程早死锁了,Kubelet还以为服务健康。为什么?因为没配liveness探针,容器一直没重启,流量照常往里打。

后来配了探针,又出了新幺蛾子:服务启动慢(60秒),liveness探针30秒就超时,K8s疯狂重启容器,陷入“启动-被杀-再启动”的死循环。配错比不配更惨

所以这篇文档,不跟你聊虚的。直接告诉你:三个探针分别用在什么场景,参数给多大合适,以及两个我亲自踩碎的坑。


前置条件

  • 一个K8s集群(本地minikube或云上EKS/ACK都行)
  • kubectl已配置好
  • 你有一个可修改Deployment的权限
  • 熟悉YAML基本写法

我用的是K8s v1.27(集群环境),命令在MacOS上跑,Linux也一样。


三大探针,到底干嘛的?

用一个类比你就懂了:

探针类型

类比

失败后动作

典型场景

livenessProbe

心跳监视器

重启容器

进程死锁、内存泄漏、goroutine死等

readinessProbe

服务上线检查

从Service的Endpoints摘除

启动预热、依赖未就绪、过载保护

startupProbe

慢启动保镖

重启容器(但只保护启动阶段)

启动超过30秒的Java/Node/Python应用

SRE铁律

  • liveness只检查进程自身是否活着,不要依赖外部(比如数据库、Redis)。
  • readiness可以依赖外部,但超时要短(否则流量切不走)。
  • startup优先级高于liveness,启动期间liveness会被屏蔽。

实战:每种探针怎么配最稳

1. livenessProbe:保命用的,但别乱用

错误示范(我当年就犯过):

livenessProbe: httpGet: path: /health # 这个接口里面调用了DB、缓存、下游RPC port: 8080 initialDelaySeconds: 30 periodSeconds: 10

一旦DB抖动,/health返回500 → 容器被重启 → 雪崩。liveness探针应该只检查本进程的主线程是否还活着

推荐写法

livenessProbe: exec: command: - /bin/sh - -c - "pgrep -f 'java -jar app.jar' || exit 1" # 简单粗暴,只检查进程PID # 或者用httpGet但端点只返回200,不做任何逻辑 initialDelaySeconds: 15 # 等15秒再开始检查,避免启动未完成就杀 periodSeconds: 10 # 每10秒查一次 timeoutSeconds: 1 # 1秒超时,别等太久 failureThreshold: 3 # 连续失败3次才重启(容忍短暂抖动) successThreshold: 1 # 成功1次就恢复健康

关键参数解释

  • initialDelaySeconds:容器启动后等多久开始探测。对Java(Spring Boot)建议至少30秒,Go二进制可以10秒。
  • failureThreshold:默认3次。不要改成1,否则网络瞬时波动就会重启Pod。
  • timeoutSeconds:探针自身超时。如果你的健康检查接口里做了sleep 2,那timeoutSeconds至少设3,否则必然失败。

2. readinessProbe:接入流量前,先确认自己还活着

这是我最推荐的探针——配好readiness,基本能避免大部分“Pod Running但服务不可用”的故障

生产级配置示例(以HTTP接口/ready为例):

readinessProbe: httpGet: path: /ready port: 8080 httpHeaders: - name: X-Custom-Header value: ReadyCheck initialDelaySeconds: 5 # 启动后5秒就开始检查(别等太久,否则流量已切进来) periodSeconds: 5 # 5秒查一次,快速反应 timeoutSeconds: 2 failureThreshold: 2 # 连续2次失败就摘流量(快速隔离) successThreshold: 1

你的应用必须在/ready里做什么?

  • 检查数据库连接池是否初始化完成
  • 检查消息队列(Kafka/RabbitMQ)是否可连接
  • 检查本地缓存是否加载完毕
  • 如果有依赖的gRPC服务,只做快速超时的探活(200ms内)

注意:如果/ready里做了复杂业务逻辑,超时设大一点(比如5秒),但这样流量摘除也会变慢。折中方案:readiness只做“基础依赖就绪检查”,别做深层校验。

3. startupProbe:专治启动慢的“老应用”

你的Java Spring Boot应用启动要90秒?Node.js要加载大量依赖?用startupProbe

startupProbe: httpGet: path: /healthz # 随便一个轻量端点,只要应用能响应HTTP就行 port: 8080 failureThreshold: 30 # 30次失败 periodSeconds: 5 # 每5秒查一次 → 总共150秒启动窗口 timeoutSeconds: 2

组合使用
一旦startupProbe成功一次,它就退役了,把控制权交还给livenessProbe。所以你可以这样配:

  • startupProbe:宽松容忍,允许150秒启动。
  • livenessProbe:启动后每10秒检查,3次失败重启。

个人不推荐为了省事把liveness的initialDelaySeconds调到很大(比如300秒)。那样如果应用运行中途死锁,需要等5分钟才能重启,太慢了。


两个真实踩过的坑(希望你别再踩)

坑①:liveness探针依赖下游服务 → 雪崩

场景:一个API网关Pod,liveness探针调用/health,这个接口会去Redis做PING。某次Redis抖动,/health返回500,Kubelet认为网关死了,重启容器。重启后Redis还在抖,liveness又失败,反复重启。半小时后Redis恢复了,但网关已经被重启废了。

教训liveness探针绝对不能依赖外部组件。它只检测“本进程是否还能跑”。
正确做法:liveness用exec检查进程PID,或者用tcpSocket检查端口监听状态。

livenessProbe: tcpSocket: port: 8080

TCP握手成功就说明进程还活着,够用了。

坑②:readiness探针和liveness探针共用同一个HTTP端点 → 启动风暴

场景:懒省事,把/health同时配给liveness和readiness。结果应用启动慢,readiness一直失败(正常),但liveness也失败,Kubelet直接杀容器。应用还没来得及完成初始化就被杀了。

教训两个探针必须用不同的端点,或者至少逻辑不同。

  • /live:只返回200,不做任何检查。
  • /ready:做依赖就绪检查。
  • 启动慢的应用必须配startupProbe,否则liveness永远在启动期杀容器。

顺便提一嘴,老版本K8s(1.16之前)没有startupProbe,那时候的通用解法是把liveness的initialDelaySeconds设成超大(比如300秒)。我现在还看到有人这么干,赶紧改掉。用startupProbe才优雅。


验证你的探针配置是否生效

不要信“我感觉配好了”,用kubectl describekubectl get events看证据。

步骤1:模拟探测失败
进入容器,手动让健康检查失效:

# 假如你的readiness探针检查文件 /tmp/ready kubectl exec -it <pod-name> -- touch /tmp/ready # 先让他就绪 # 然后删除文件 kubectl exec -it <pod-name> -- rm /tmp/ready

等待periodSeconds(比如5秒),然后看Pod状态:

kubectl get pod <pod-name> -w

你应该看到READY1/1变成0/1,但STATUS仍然是Running(只有liveness失败才会重启)。

步骤2:看事件

kubectl describe pod <pod-name> | grep -A5 Events

会输出类似:

Warning Unhealthy 2s kubelet Readiness probe failed: cat: /tmp/ready: No such file or directory

步骤3:强制触发liveness重启
在容器里模拟死循环:

kubectl exec -it <pod-name> -- kill -STOP 1 # 冻结主进程(仅Linux)

等liveness探测三次失败后,RESTARTS会增加,events里能看到Liveness probe failed: ...

注意:别在生产环境乱试,用测试namespace。


常见问题(来自生产环境真实报错)

Q1:报错probe returned 503但容器内服务正常?
A:检查你的健康检查端口是否写对了(比如容器监听8080,但你填了8081)。或者Pod里有两个容器,health端点暴露在不同端口。我遇到过最蠢的:Spring Boot的management端口是8081,但探针指向了业务端口8080,结果业务端口返回404,探针判定失败。

Q2:failureThresholdperiodSeconds怎么配最安全?
A:给一个通用公式:容忍总时间 = failureThreshold × periodSeconds + timeoutSeconds

  • liveness:容忍总时间建议30~60秒,防止误杀。
  • readiness:容忍总时间10秒以内,快速隔离。
    示例:failureThreshold: 3, periodSeconds: 10→ 容忍30秒。

Q3:TCP探针和HTTP探针哪个好?
A:HTTP能返回具体状态码(200/500),更精确;TCP只能知道端口在监听。我推荐HTTP,只要你的应用能提供一个轻量/live端点。但如果你的业务代码容易死锁但端口还能监听(比如goroutine死锁但TCP连接还在),那TCP探针就失效了,必须用HTTP探针配合内部状态检查。

Q4:initialDelaySecondsstartupProbe同时用,会不会双重等待?
A:不会。startupProbe执行期间,liveness和readiness探针都会被屏蔽,直到startup成功或失败。initialDelaySeconds在startup之后才生效。所以不用重复设大值。

Q5:探针的successThreshold有什么用?
A:默认是1,表示失败转健康只需要一次成功。但在readiness里可以设为2,防止健康状态在边界抖动导致流量频繁切出切入。不过会增加响应延迟,自己权衡。


最后说几句

探针这东西,看着简单,但生产环境一跑就暴露各种“我以为”。我总结三个核心原则,你记一下:

  1. liveness探针只管自己死活,别碰外部依赖。
  2. readiness探针是服务自愈的灵魂,务必配得细致。
  3. 启动慢的应用必须上startupProbe,别再用傻等initialDelaySeconds。

你还有什么更好的玩法?或者踩过更离谱的坑?评论区见,咱们交流一下。

(如果这篇对你有帮助,转发给那个还在用initialDelaySeconds: 300的同事吧。)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 9:31:04

SQL 注入实战:DVWA Medium完整测试指南

文章目录1. 环境准备1.1 获取 Session Cookie2. Medium 安全级别源码分析2.1 源码2.2 Low vs Medium 关键变化2.3 防护机制分析&#xff1a;mysqli_real_escape_string()2.4 漏洞分析&#xff1a;为什么 Medium 仍然可被注入&#xff1f;3. Burp Suite 自动化注入测试3.1 环境准…

作者头像 李华
网站建设 2026/6/10 9:27:12

图片翻译工具测评:几款主流产品的功能对比与选择建议

一、跨境电商多语言素材制作的现实困境对于从事跨境电商的卖家来说&#xff0c;将产品推向海外市场时&#xff0c;语言障碍是最直接也最耗时的问题之一。尤其是当店铺规模扩大、SKU数量增加之后&#xff0c;需要处理的多语言素材量会呈指数级增长。以一位典型的亚马逊或速卖通卖…

作者头像 李华
网站建设 2026/6/10 9:26:11

AI写小说素材怎么找?蛙趣拼文语义检索功能评测

素材库最大的难点不是存得多&#xff0c;而是写作时能不能找得到。蛙趣拼文支持素材向量化和语义检索&#xff0c;作者可以用写作意图查找相近素材。ai写小说素材素材库越用越大以后&#xff0c;新的问题会出现。作者明明记得有一段好素材&#xff0c;却找不到它在哪里。文件名…

作者头像 李华
网站建设 2026/6/10 9:25:22

UVM验证进阶:拆解start_item源码,搞懂sequencer参数怎么用才高效

UVM验证进阶&#xff1a;拆解start_item源码与sequencer参数高效用法第一次在UVM源码中看到start_item函数原型里那个不起眼的sequencer参数时&#xff0c;我正调试一个跨时钟域的复杂验证场景。当时项目中有三个不同时钟域的sequencer需要协同工作&#xff0c;而uvm_do_on宏的…

作者头像 李华
网站建设 2026/6/10 9:18:30

告别虚拟机:实战解析Windbg真机双机调试的3个关键点与性能对比

告别虚拟机&#xff1a;实战解析Windbg真机双机调试的3个关键点与性能对比调试工具的选择往往决定了开发效率的天花板。当你在虚拟机中反复经历卡顿、断连和功能受限时&#xff0c;是否考虑过真机调试的潜力&#xff1f;本文将带你跳出虚拟机沙盒&#xff0c;直击真机调试的核心…

作者头像 李华