K8s 健康但请求卡死?排查隐藏延迟

当 Kubernetes 集群各项指标正常但请求仍然卡顿时,问题往往藏在网络策略、服务发现、资源争用等盲区。本文梳理常见原因与排查思路,帮助开发者快速定位隐藏延迟。
2026-10-15 0来源:The New Stack
健康检查通过,请求却卡死
这是 Kubernetes 运维中最令人困惑的场景之一:Pod 状态全是 Running,Readiness Probe 全部通过,Prometheus 面板上的 CPU、内存、网络指标看起来都很平稳,但用户端却反映请求超时或响应极慢。
问题的根源通常在于——健康检查只验证了"进程活着",而没有验证"请求能正常走完全链路"。真正的延迟可能隐藏在健康检查覆盖不到的环节。
常见隐藏延迟来源
1. 网络策略与服务发现
- NetworkPolicy 的静默丢弃:某些网络策略不会报错,而是直接丢弃数据包,导致请求超时而非立即失败。
- CoreDNS 解析延迟:当 DNS 查询量大或缓存未命中时,服务发现阶段可能引入数秒级延迟。
- Service 后端选择问题:kube-proxy 的 iptables 或 IPVS 模式下,如果后端 Pod 刚启动还未就绪,请求可能被路由到空后端。
2. 资源层面的隐性瓶颈
- CPU Throttling:Pod 的 CPU limit 设置过低时,内核会进行 CFS 配额节流,但常规 CPU 使用率指标不会反映这一情况。需要查看
container_cpu_cfs_throttled_periods_total指标。 - 磁盘 I/O 争用:共享存储或节点磁盘带宽不足时,日志写入或临时文件操作可能阻塞请求处理。
- 内存交换:节点内存紧张时,即使 Pod 未触发 OOMKill,也可能发生 swap,导致间歇性卡顿。
3. 应用层与中间件
- 连接池耗尽:数据库或下游服务的连接池满了,新请求排队等待,但 Pod 本身依然健康。
- Goroutine 泄漏:Go 服务中未正确关闭的 goroutine 会持续占用资源,最终导致调度器饥饿。
- TLS 握手延迟:跨节点或跨可用区的 TLS 连接建立可能比预期慢,尤其是证书链较长时。
实用排查思路
第一步:从用户视角测量端到端延迟
不要只看集群内部指标。在用户入口侧(Ingress、API Gateway)埋点,记录每个请求的完整耗时分解:
- DNS 解析耗时
- TCP 连接建立耗时
- TLS 握手耗时
- 服务端处理耗时
- 响应传输耗时
如果某一段耗时异常,就能快速缩小排查范围。
第二步:检查 CFS 节流与节点压力
# 查看 Pod 是否被 CPU 节流
kubectl top pod -n <namespace>
# 查看节点压力状态
kubectl describe node <node-name> | grep -A 10 "Conditions"
重点关注 container_cpu_cfs_throttled_seconds_total 指标,如果节流比例超过 10%,建议调高 CPU limit 或移除 limit。
第三步:追踪请求链路
使用分布式追踪工具(如 OpenTelemetry、Jaeger)在请求全链路中打点。重点关注:
- 请求在 Service Mesh(如 Istio、Linkerd)中的 sidecar 转发耗时
- 跨命名空间的网络策略是否引入了额外延迟
- 重试机制是否导致请求堆积
第四步:对比健康检查与实际请求
很多团队的健康检查只请求 /healthz 端点,这个端点通常不经过完整的业务逻辑。建议:
- 增加深度健康检查:模拟真实业务请求,验证数据库连接、下游服务调用是否正常。
- 使用 Synthetic Monitoring:定期从外部发起真实请求,记录端到端延迟。
- 设置 Canary 端点:用一个轻量但覆盖核心路径的端点作为探针目标。
对谁有价值
- 平台工程团队:在集群层面建立隐藏延迟的监控基线,提前发现资源争用。
- 应用开发者:理解 K8s 环境下的性能陷阱,避免在 limit、连接池、健康检查设计上踩坑。
- SRE 运维人员:当告警系统显示一切正常但用户投诉时,有一套系统的排查流程。
总结
Kubernetes 的"健康"不等于"好用"。隐藏延迟往往藏在健康检查的盲区——网络策略的静默丢弃、CPU 节流的指标缺失、连接池的排队等待。建立端到端延迟追踪、增加深度健康检查、关注 CFS 节流指标,是应对这类问题的三个关键实践。

本文目录(12 节)
本文基于 The New Stack 的公开内容,由 AI 辅助整理改写后发布。
原标题:Where do you look when Kubernetes is healthy but requests stall?
阅读原文