news 2026/10/22 8:59:12

Kubernetes健康检查实战:三种探针配置与排错指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kubernetes健康检查实战:三种探针配置与排错指南

1. 先搞清楚 Kubernetes 健康检查到底在检查什么

1.1 健康检查不是“应用自检”,而是 kubelet 的外部视角

做 Kubernetes 运维这几年,“健康检查”这个词我几乎每天都在碰。很多刚上手的朋友会把探针当成“容器内的一个定时器”,以为只要写了 liveness 就能保证服务不出事,结果生产上一个误杀就把整条链路打挂了。这篇文章不吃理论大餐,直接讲 Kubernetes 健康检查的三种探针怎么配、参数怎么推导、常见翻车场景怎么排查。

首先要纠正一个认知:健康检查是 kubelet 从宿主机视角对容器做“外部探测”,不是应用自己往控制面报告“我还活着”。你在 Pod 里写一个脚本检测自身状态,那只是应用逻辑,Kubernetes 是不认的。kubelet 会按照你配置的探针,定期发起 HTTP 请求、TCP 连接或者 exec 命令,根据结果决定这个容器的生死和流量归属。

这个外部视角非常重要。容器进程存在不代表业务就绪,端口监听不代表依赖可用。我见过很多案例:Java 进程还在,但线程池耗尽、数据库连接池打满,接口全部超时;这时候从容器层面看,PID 是活的,CPU 也正常,但用户请求已经全挂在等待队列里。如果没有 Readiness 探针把这些异常实例从负载均衡端点里摘掉,流量会继续灌进去,雪崩就是这么一步步扩大的。

健康检查解决的是两个完全不同的目标:一是“要不要继续给它发流量”,二是“出问题了要不要把它重启掉”。这两个目标如果混在一个探针里,后果往往很严重——要么流量打到坏实例上,要么一个瞬时抖动触发大规模重启。

1.2 三类探针怎么分工

Kubernetes 里内置了三类探针:livenessProbe、readinessProbe、startupProbe。名字很直白,但很多人栽在“以为字面意思就是全部”上。

livenessProbe 管存活,失败后 kubelet 会杀掉容器并按 restartPolicy 决定是否重启。这是自愈机制,适合兜底死锁、内存泄漏导致的进程僵死。readinessProbe 管就绪,失败后 Pod 会被标记为 NotReady,然后从 Service 的 Endpoints 中剔除,但它不会被重启。startupProbe 是后来加的保护机制,专门对付启动特别慢的容器,在它成功之前,liveness 和 readiness 都会被暂时禁掉。

用一个表格看清楚:

探针类型失败后果适用场景核心关键词
livenessProbe容器被 kill、可能重启进程死锁、业务僵死、内存泄漏无法自愈要不要活
readinessProbe从 Service Endpoints 摘除,不重启依赖未就绪、流量过载、启动未完成要不要接流量
startupProbe容器被 kill、可能重启老应用启动特慢、liveness 误杀启动过程等它慢慢起

注意一个细节:liveness 失败时,kubelet 通常只重启“容器”,不一定是整个 Pod。具体取决于 restartPolicy,如果策略是 Always,容器会在同一个 Pod 内重新拉起,restartCount 加 1。如果策略是 Never,容器不会被重启,Pod 会进入 Failed。这个差异在排查“Pod 一直 Running 但容器不停重启”的时候很关键。

我个人的理解是:startupProbe 是给 livenessProbe 上的一道保险。很多老旧应用从进程启动到真正可服务需要 40 秒甚至 2 分钟,如果 liveness 从容器启动那一刻就开始算,极大概率在应用还没起来时就触发重启,形成 CrashLoopBackOff。有了 startup 探针,你只需要告诉 kubelet:“先给它 XX 秒,别急着杀它。” 等它起来了,再把“存活判断权”交还给 liveness。

2. 探针配置:参数含义与“踩坑”阈值计算

2.1 五个标准参数逐个拆解

所有探针都有一组共同的配置参数:initialDelaySeconds、periodSeconds、timeoutSeconds、failureThreshold、successThreshold。刚接触的人往往只关心 path 和 port,把后面这些默认值当成空气,实际上这才是最容易埋雷的地方。

initialDelaySeconds 表示容器启动之后,等多少秒才开始第一次探测。期间 kubelet 不执行任何探针,给应用留出“进程初始化”的时间。periodSeconds 是两次探测之间的间隔,默认 10 秒,最小可以设成 1 秒,但我不建议小于 3 秒。timeoutSeconds 是每次探测的超时时间,默认只有 1 秒,这个值在很多业务系统里根本不够用,接口响应只要超过 1 秒就会被判定为失败,这一点我后面会专门讲。

failureThreshold 是连续失败多少次之后才认定探针失败。默认 3 次,看的是“连续失败”,只要中间成功一次,计数器就会清零。successThreshold 正好相反,连续成功多少次才认为探针通过,默认 1 次。Readiness 探针的 successThreshold 可以设置成 2 或 3,用来防止“刚 Ready 又被打掉”的抖动;但 liveness 和 startup 探针的 successThreshold 必须保持 1,这是硬限制。

我见过的生产事故里,至少有三分之一和“默认值直接上线”有关。默认 periodSeconds=10、failureThreshold=3,意味着一次失败判定至少要经过约 20 到 30 秒窗口,如果业务调用方超时只有 2 秒,这个恢复速度根本不够看。反过来,如果你把一个纯 liveness 探针设成 period=1、failureThreshold=1,那就是在制造不稳定——稍微抖一次就把容器杀了。

2.2 一次完整重启周期推导

探针的失败判定时间是有公式的,但是网上很多文章没说透。最坏情况的下,持续失败到判定失败的时间大约是:

初始等待时间 + (连续失败次数 - 1) * 探测周期

也就是说,如果一个探针配置是initialDelaySeconds: 10, periodSeconds: 10, failureThreshold: 3,那么最坏情况下,容器启动后 10 秒开始第一次探测,20 秒第二次,30 秒第三次,第三次失败后 kubelet 认定探针失败。这里的“判定失败时刻”是 10 + (3-1)*10 = 30 秒。

举例来说,一个 Java 服务进程起来大约需要 20 秒,Spring 上下文加载完要 45 秒。如果你只配了 liveness:

livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 3

按公式算,第 3 次失败发生在 30 秒左右,可应用要到 45 秒才起来,这必然触发重启。容器被杀了之后又会重新启动,30 秒后又杀,形成一个永远起不来的循环。这就是“启动太慢导致 CrashLoopBackOff”的典型原因。

正确的做法是引入 startupProbe,让它来覆盖启动窗口。比如:

startupProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 0 periodSeconds: 5 failureThreshold: 12

这个 startup 探针在容器启动后立刻开始探测,每 5 秒一次,连续 12 次失败才会判定失败,也就是最多给容器约 55 秒的启动时间。如果应用在 45 秒就绪,那 startup 就能成功,随后 liveness 才正式接管。

这里有个很多人都忽略的时序问题:startup 探针成功之前,readiness 和 liveness 都会被禁用;startup 成功之后,它们才开始执行。所以你在配 liveness 的时候,initialDelaySeconds 不要比 startup 窗口大太多,一般只要保证“在 startup 成功之后,liveness 还能有至少一到两个周期的缓冲”就够了。

2.3 参数设置的“宁可长一点,也别过早下结论”

探针参数的调优原则,我一直跟团队说的是:宁可长一点,也别过早下结论。这个“长”是有上限的,不是无脑大。

如果是普通无状态 HTTP 服务,我通常这样定初始值:

  • readiness:initialDelaySeconds=10,periodSeconds=5,timeoutSeconds=2,failureThreshold=3,successThreshold=1
  • liveness:initialDelaySeconds=30,periodSeconds=10,timeoutSeconds=2,failureThreshold=3
  • startup:initialDelaySeconds=0,periodSeconds=5,timeoutSeconds=2,failureThreshold=12

遇到老系统、依赖多、启动慢的,startup 的 failureThreshold 直接给到 20 甚至 30。比如一个应用需要 90 秒才能就绪,period=5、failureThreshold=20,窗口大约是 (20-1)*5 = 95 秒,够用了。注意不要把启动等待全压在 initialDelay 上,因为 initialDelay 只影响探针开始时间,不参与失败计数逻辑;startup 才是更合理的“启动保护伞”。

还有一点,periodSeconds 不宜追求过分激进。readiness 设成 5 秒可以接受,liveness 我建议至少 10 秒。因为 liveness 每次失败都可能导致重启,周期太短会把一次瞬时抖动放大成全量重启;而 readiness 失败只是摘流量,可以更敏感一点,但也要配合 failureThreshold 和 successThreshold,避免频繁抖动。

3. 三种探针实现的具体写法与适用场景

3.1 httpGet 探针:最常用,但路径和状态码要盯紧

绝大多数 Web 服务都用 httpGet 探针,因为它最直观:kubelet 定期向容器内某个 HTTP 接口发起 GET 请求,只要返回的状态码在 200 到 399 之间就视为成功,否则视为失败。也就是说 4xx 和 5xx 都算失败。

写起来很简单:

livenessProbe: httpGet: path: /healthz/live port: 8080 httpHeaders: - name: X-K8s-Probe-Token value: "some-static-token" initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 2 failureThreshold: 3

这里有几个坑必须说清楚。

第一,探针是从宿主机发起的,不是从 Pod 内部发起的。如果应用只监听了 127.0.0.1,httpGet 探针会失败,因为 kubelet 访问的是 Pod IP。应用监听地址要写成 0.0.0.0 或者 Pod IP。这一点在网络插件和防火墙策略复杂的集群里特别容易踩。

第二,健康检查接口要轻量。别在/healthz里做全量数据库查询、清缓存、跑定时任务,否则一次探针请求就可能把实例拖垮。liveness 的职责是“进程还活着”,readiness 的职责是“依赖基本可用”,都不适合做重型检查。

第三,timeoutSeconds 要大于接口的真实响应时间。很多开发同学默认把健康检查接口写成“即时返回”,但实际上应用在高负载下,一个健康检查请求也可能排队 1 到 2 秒。如果 timeoutSeconds 保持默认 1 秒,高峰期探针就会连续失败,触发误判。我一般在生产环境至少给到 2 秒,复杂的给到 3 到 5 秒。

第四,健康检查接口如果需要登录或者鉴权,要么用 httpHeaders 把 token 显式带上,要么做成无需鉴权的独立端点。我见过有团队把健康检查放到需要 SSO 登录的路径后面,探针全部 302 跳转,最后一堆 Pod 从 Endpoints 里消失,业务直接中断。

3.2 tcpSocket 探针:只通端口不等于业务可用

tcpSocket 探针做的事情更底层:kubelet 尝试与容器指定端口建立 TCP 连接,只要能连上就判定成功,连不上就失败。

readinessProbe: tcpSocket: port: 3306 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 2 failureThreshold: 3

tcpSocket 的适用场景很明确:非 HTTP 协议的服务,比如 MySQL、Redis、消息队列、自研 TCP 网关。它不需要应用实现一个专门的健康检查协议,只要端口能监听起来就行。

但它的局限也非常明显:端口通,不等于业务可用。一个服务可能 TCP 三次握手能成功,但内部线程池已经打满,新的连接虽然建立了却得不到响应。另一个常见例子是:代理服务监听端口正常,但后端的真实服务已经挂了,TCP 探针仍然显示成功。

所以 tcpSocket 更适合作为“进程是否在监听”的兜底探针,而不是业务质量探针。如果你的服务既能用 HTTP 探针,就尽量用 HTTP 探针;实在只能 TCP,也要接受它的判定粒度比较粗。

3.3 exec 探针:适合容器内没有 HTTP 服务的场景

exec 探针是在容器内执行一条命令,通过退出码判断结果:0 表示成功,非 0 表示失败。

livenessProbe: exec: command: - /bin/sh - -c - pgrep -f myapp || exit 1 initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3

exec 探针最典型的用处是:容器里的主程序不是 Web 服务,或者不方便暴露 HTTP 健康端点。比如一个后台任务进程、一个消息消费 worker,你想知道它是否还在运行,可以用 pgrep 或者检查 PID 文件。

但 exec 探针有三个非常容易踩的坑。

第一个是性能开销。每次探测都要在容器内 fork 一个进程,如果反复执行复杂 shell 脚本,对节点 CPU 和容器文件系统都有压力。健康检查频率越高,开销越明显。所以 exec 探针的 periodSeconds 不建议低于 10 秒,command 也要尽量短。

第二个是 shell 的退出码陷阱。很多同学写成/bin/sh -c "pgrep myapp && exit 0",或者干脆写pgrep myapp,但没注意到sh -c返回的是最后一个命令的退出码,有时候最后一条 pipeline 成功了,前面核心判断却失败了,探针结果完全偏离预期。

第三个是“进程在但业务死”的问题。exec 探针通常只能判断进程是否存在,判断不了线程池是否可用、依赖是否健康。如果你的 worker 进程陷入了死循环但还没退出,exec 探针照样显示成功。这种情况还得靠业务层自己上报心跳。

3.4 探针类型怎么选:先看进程在不在,再看业务通不通

我给团队定的选型逻辑很简单:第一层确认进程在不在,第二层确认业务通不通。

应用类型推荐 readiness推荐 liveness推荐 startup
Web/HTTP 服务httpGet/healthz/readyhttpGet/healthz/livehttpGet/healthz/live
TCP/MySQL/Redis 类tcpSocket 端口tcpSocket 端口 或 exec根据启动速度而定
后台 Worker/Consumerexec 或业务心跳接口exec 判断进程存活启动慢则加 startup
短时任务/批处理不建议配 readiness通常不配 liveness一般不配 startup

还有一个容易忽略的组合:一个容器可以同时配置三个探针,也可以只配其中两个。比如纯批处理任务,跑完就退出,如果你配了 liveness,任务退出时 liveness 会判定失败,然后容器被重启,业务逻辑重新执行一遍,这很可能是灾难。短时任务的容器通常不需要探针,或者只需要在任务入口处做 readiness 控制,让 Job 的调度逻辑来判断。

4. 从零配置一套健康检查:完整实战流程

4.1 先确认业务健康检查点

很多团队做健康检查是在部署文件里抄一段模板,根本没有想清楚健康检查接口要长什么样。我的习惯是:先让应用侧把健康检查端点拆分出来,再写 Kubernetes 配置。

一个比较稳的分法是两个端点:

  • /healthz/live:只检查进程是否活着、主线程是否没有死锁。它不依赖数据库、Redis、消息队列等外部组件。这个端点给 liveness 和 startup 用。
  • /healthz/ready:检查当前实例是否具备服务能力,比如数据库是否能连、缓存是否能读写、关键依赖是否可用。这个端点给 readiness 用。

为什么要分开?因为 liveness 失败会导致容器重启,如果把数据库检查放进去,数据库一抖动,所有实例就可能同时被重启,这是最典型的雪崩诱因。数据库恢复之后,服务还得重新冷启动,恢复时间反而更长。

你可以把/healthz/ready设计成“容忍短时抖动”的检查:依赖出问题时可以延迟判断,而不是一失败立刻返回 500。例如连续 3 次从数据库读取失败才标记依赖不健康,单次失败不要立刻影响 readiness。

4.2 一份可以直接改的 Deployment YAML

下面是一份我常用的示例配置,你可以直接套用:

apiVersion: apps/v1 kind: Deployment metadata: name: demo-app spec: replicas: 3 selector: matchLabels: app: demo-app template: metadata: labels: app: demo-app spec: containers: - name: demo-app image: registry.example.com/demo-app:v1.0.0 ports: - containerPort: 8080 resources: requests: cpu: 100m memory: 256Mi startupProbe: httpGet: path: /healthz/live port: 8080 initialDelaySeconds: 0 periodSeconds: 5 timeoutSeconds: 2 failureThreshold: 12 readinessProbe: httpGet: path: /healthz/ready port: 8080 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 2 failureThreshold: 3 successThreshold: 1 livenessProbe: httpGet: path: /healthz/live port: 8080 initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 2 failureThreshold: 3

这份配置对应的是一个需要大约 45 秒才能完成启动、之后进入稳定状态的 Java 服务。

startupProbe 的窗口是(12-1)*5 = 55秒,默认放行窗口约 55 秒;如果你的应用需要更长时间,把 failureThreshold 增大,比如 15 次就是 70 秒,20 次就是 95 秒。readinessProbe 每隔 5 秒探测一次,启动完成后如果依赖没就绪,最多连续失败 3 次就把实例从 Endpoints 摘掉。livenessProbe 的 initialDelaySeconds 给了 60 秒,目的是让 startup 保护窗口结束后,liveness 仍然有一段缓冲期,避免刚完成启动就被误杀。

这里的端口不一定要写在 containerPort 里,探针可以直接探测任何容器内可访问的端口,但写出来更清晰,也方便其他配置引用。

4.3 部署后如何验证探针是否生效

写完配置不是结束,验证才是关键。部署之后我会按这样的顺序来检查:

先用kubectl apply发布,然后kubectl get pods -w观察 Pod 状态。正常情况下,Pod 会从 Pending 走到 ContainerCreating,再走到 Running,然后 Ready 列变成1/1。如果 Ready 一直是0/1,说明探针已经判定失败,需要进一步排查。

用kubectl describe pod <pod-name>可以看到探针的详细配置和最近事件。比如事件里出现Unhealthy,后面会跟着探针类型和失败原因;如果是 HTTP 探针失败,会显示HTTP probe failed with statuscode: 500;如果是 exec 失败,会显示退出码或错误信息。这些事件是排错的第一手资料。

之后做两个主动故障演练:

第一个演练是“kill 主进程”。进入容器后把应用主进程杀掉,比如 Java 应用ps -ef | grep java找到 PID,再 kill。如果配置了 liveness,kubelet 会在下一轮探测时发现进程不存在,或者健康检查接口无响应,然后容器被重启。你会在kubectl get pod -o yaml里看到restartCount增加。

第二个演练是“让 readiness 失败”。你可以在容器内临时停掉/healthz/ready所依赖的组件,或者直接改返回值,让 healthz 返回 500。这时 Pod 的状态会变成 NotReady,但容器不会重启。同时用kubectl get endpoints或kubectl get endpointslices观察,这个 Pod 的 IP 会从 Ready 地址列表里消失。等恢复健康后,它又会自动加回来。

我非常建议在测试环境把这两个演练做成自动化用例,每次改完探针配置都跑一遍。这样能避免“上线时探针配错了,但流量少没暴露,到高峰期突然流量全部打挂”的情况。

4.4 滚动更新里的“串行放量”为什么要靠 readiness

Deployment 滚动更新时,探针的作用会被放大。默认情况下,Deployment 会先创建一个新 Pod,等它 Ready 之后再删除旧 Pod。如果新 Pod 一直没有 Ready,滚动更新会卡住,旧 Pod 不会被删,新 Pod 也不会继续扩容。

这其实是保护机制:新版本有问题时,readiness 探针会拦住它上量。但前提是你把 readiness 配对了。如果 readiness 探针只是“端口通就行”,新 Pod 即使业务初始化失败,也会被标记为 Ready,流量照样打进去。

建议给 Deployment 额外配一个minReadySeconds。它不算探针,但和探针是黄金搭档。minReadySeconds表示 Pod 转为 Ready 之后,至少要保持多少秒才算真正可用。比如:

spec: minReadySeconds: 30

这个参数可以防止“新 Pod 刚 Ready,进入流量后马上抖动,readiness 又失败,滚动更新中断”的恶性循环。配合 readinessProbe,新 Pod 只有“探针通过 + 稳定运行 30 秒”这两个条件都满足,才会被纳入流量。

maxSurge 和 maxUnavailable 是控制滚动更新速率的,但如果探针配置有问题,调这两个参数只能事倍功半。我的经验是:先把探针调稳,再根据发布速度去调滚动参数。

5. 常见探针翻车现场与排查套路

5.1 场景一:容器疯狂重启,但业务日志没有报错

这是最迷惑人的问题。你去看应用日志,一切正常,连异常堆栈都没有,但 Pod 里的容器一直重启。这时候十有八九是探针把你杀了。

用kubectl describe pod <pod-name>查看事件,通常能看到类似:

Warning Unhealthy 3s Liveness probe failed: HTTP probe failed with statuscode: 500

如果看到这条,直接去访问应用的/healthz接口,看看 500 是哪里来的。常见原因有三个:应用监听地址绑定了 localhost,探针访问不到;健康检查路径写错,返回 404 被当成失败;健康检查接口内部依赖某个组件,该组件当前抖动。

还有一种情况是健康检查接口本身响应太慢,超过了 timeoutSeconds。事件里可能显示context deadline exceeded或者timeout。这时把 timeoutSeconds 从 1 秒调到 2 到 3 秒,多半能解决。但如果一个健康检查接口经常需要超过 2 秒才能响应,那这个接口本身就太重了,建议把业务逻辑拆分出去。

5.2 场景二:服务被 Readiness 频繁摘流量,接口超时量增加

某天监控里突然发现服务时不时从 Endpoints 里掉出去,但容器没重启,一看事件全是Readiness probe failed。

先别急着调探针,先想清楚这个实例是不是真的不健康。如果它只是响应慢,readiness 把它摘掉是对的;但如果它只是偶尔一次抖动,摘掉之后流量转移到其他实例,又导致其他实例过载,形成连锁反应,那就说明 readiness 太敏感。

我的调法有几个方向:

一是把 successThreshold 从 1 调到 2。对于新启动的实例,这个参数要求连续两次成功才加入流量,可以避免“刚 Ready 又挂了”的振荡。

二是把 failureThreshold 从 3 调到 5。这样单次网络抖动不会触发摘除,只有持续失败一段时间才判定不健康。

三是检查健康检查端点是否包含了过于严格的依赖检查。比如 readiness 接口一旦查不到 Redis 就返回 500,而 Redis 恰好重启了一次,那所有实例会在同一时间被摘掉,这非常恐怖。

四是结合 minReadySeconds。很多时候不是探针参数问题,而是滚动更新太快,新 Pod 一 Ready 就接流量,瞬间负载上来,readiness 被打掉。加 30 到 60 秒稳定期,问题就会消失。

5.3 场景三:老应用启动特别慢,一上线就 CrashLoopBackOff

这种问题几乎都出在“没有配置 startupProbe 或者配置不当”。老应用启动慢、依赖多,甚至第一次请求前要做一堆初始化,期间健康检查接口要么不响应,要么返回 503。

解决办法是给启动过程一个明确的宽限窗口。比如应用需要 90 秒启动,配置:

startupProbe: httpGet: path: /healthz/live port: 8080 initialDelaySeconds: 0 periodSeconds: 5 timeoutSeconds: 2 failureThreshold: 20

这样最坏情况下有(20-1)*5 = 95秒的启动窗口。如果 95 秒还不够,就把 failureThreshold 继续加大,直到覆盖实际启动时间,再留出 20% 到 30% 的余量。

注意一个反面教训:有人为了省事,不给应用配 startupProbe,而是把 livenessProbe 的 failureThreshold 调到 100,并设置一个超长的 initialDelay。这个方法表面上也能让应用启动起来,但代价是:业务真正死锁后,需要很久才能被探测出来并重启,故障恢复时间被严重拉长。启动这件事就交给 startupProbe,liveness 只负责运行时兜底,职责边界要清晰。

5.4 排查工具箱与速查表

探针排错的核心工具链其实就那么几个,整理成速查表:

现象可能原因优先检查
容器不断重启,应用日志正常liveness/startup 误判kubectl describe 查看 Unhealthy 事件
Pod 长时间 NotReady,但容器运行readiness 失败curl 健康检查端点,观察 Endpoints
探针事件显示 timeout接口响应慢 / timeoutSeconds 过小调大 timeoutSeconds,压测响应耗时
事件无探针告警,容器仍重启进程本身崩溃退出kubectl logs --previous,查看退出码
滚动更新卡住新版本 readiness 一直不通过查看新版 Pod 的健康检查状态
健康检查请求被拒绝网络插件/探针来源 IP 被安全策略拦截在宿主机手动 curl Pod IP 验证

还有两条实用心得。第一,Pod 的/status里会显示 containerStatuses 的 restarts 次数和 lastTerminationReason,这个是确认容器是否被探针杀掉的最快途径。第二,很多 CNI 安全策略可能会拦截 kubelet 到 Pod IP 的探针流量,排查时要记住“探针是从宿主机发起的”,不能只看容器内部。

最后给一个平时不太有人提的小技巧:如果你发现探针事件里频繁出现 Unhealthy,但应用整体表现正常,可以先看看最近有没有集群 Node 的网络或者内核抖动。kubelet 探针发出后如果短时间内收不到响应,也会被判失败,这种情况下应用是“被无辜牵连”的。你可以在 Node 上执行journalctl -u kubelet -f --grep probe,观察是否有大量探测超时,再决定是调探针参数还是优先修基础设施问题。

我个人在实际操作中的体会是:健康检查不是上线前最后一个想到的配置项,而是服务可用性设计的一部分。每个服务从开发第一天就应该把/healthz/live和/healthz/ready两个端点定好,探针参数写进发布变更单里,每次业务改动都要重新过一遍启动时间和慢接口情况。你愿意在这上面多花半小时,后面能少熬好几个凌晨的故障恢复夜。

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

TIA Portal中IO Link通信组态与调试实战指南

简介&#xff1a;这份资源是面向工业自动化工程师与PLC编程学习者的IO Link通信程序案例包&#xff0c;围绕点对点通信协议在传感器、执行器与上层控制系统之间的数据交换展开&#xff0c;覆盖从原理认知到工程落地的完整链路。压缩包共136个文件&#xff0c;约11.88MB&#xf…

作者头像 李华
网站建设 2026/10/22 8:58:16

智慧养老AI落地实践:从跌倒检测到情感陪护的避坑指南

我做了三年的社区智慧养老项目&#xff0c;一个很深的感受是&#xff1a;AI在银发经济里不是概念&#xff0c;而是已经渗进日常的"隐形管家"。但和面向年轻人的AI产品不同&#xff0c;给老人做AI&#xff0c;难点从来不在模型有多强&#xff0c;而在于场景够不够细、…

作者头像 李华
网站建设 2026/10/22 8:57:34

Kubernetes入门:从核心概念到集群搭建与部署实战

1. 先搞清楚k8s到底在解决什么问题先说个场景&#xff0c;你去年在几台服务器上用Docker部署了业务&#xff0c;平时人少的时候还挺安稳。结果今年流量涨了&#xff0c;每次发版要靠人去登录机器拉镜像、重启容器&#xff0c;扩容要提前申请机器、手动加副本&#xff0c;流量一…

作者头像 李华
网站建设 2026/10/22 8:57:28

深度学习参数初始化:Xavier与He的搭配指南

1. 从一次训练失控说起&#xff1a;初始化如何决定网络的生死如果你调试过深度学习模型&#xff0c;大概率碰到过这样一种情况&#xff1a;模型结构没问题、数据预处理没问题、损失函数也正确&#xff0c;但只要一跑训练&#xff0c;loss先是纹丝不动&#xff0c;然后突然跳成N…

作者头像 李华
网站建设 2026/10/22 8:55:12

微信小程序开发智能家居控制端的实战避坑指南

简介&#xff1a;这是一款仿米家APP界面与交互逻辑的微信智能家居小程序源码&#xff0c;面向前端初学者及小程序开发者&#xff0c;帮助其快速掌握真实IoT控制类应用的工程化实现路径。资源为ZIP压缩包&#xff0c;大小2.67MB&#xff0c;包含完整小程序项目结构&#xff08;W…

作者头像 李华
网站建设 2026/10/22 8:54:32

基于Python+CNN的中草药识别实战:从数据清洗到模型微调全流程

去年冬天&#xff0c;一个在药房实习的同学发了我一张照片&#xff0c;问我能不能写个程序自动识别照片里的中草药。我盯着屏幕看了好一会儿&#xff0c;说实话&#xff0c;粉末状的药材光靠肉眼真的很难说准。后来我把这件事当作一个正儿八经的选题完整做了一轮——基于Python…

作者头像 李华