使用 Elasticsearch 与 Kibana 中的 PromQL 调查 Kubernetes 基础设施问题

张开发
2026/5/10 21:38:25 15 分钟阅读

分享文章

使用 Elasticsearch 与 Kibana 中的 PromQL 调查 Kubernetes 基础设施问题
作者来自 Elastic Miguel Sánchez本文将逐步介绍如何使用 PromQL 在 Elastic Observability 中对 Kubernetes 集群范围内的 CPU 使用情况进行调查从集群到命名空间再到出现问题的 Pod。Elasticsearch 现在已经原生支持 PromQL并且你可以通过 ES|QL 中的 PROMQL source command 在 Kibana 中运行 PromQL 查询。这意味着你可以直接使用 PromQL 查询存储在 Elasticsearch 中的 Kubernetes 指标数据并在 Discover、Dashboards 或 alerting rules 中运行这些查询。当集群 CPU 突然飙升而你需要找出究竟是哪一个 workload导致问题时可以按层级逐步收敛范围从 fleet → namespace → pod一步一步定位。你需要准备的内容一个 Observability Serverless project或版本为 9.4 及以上的 self-managed / Elastic Cloud Hosted StackPromQL 当前作为 metrics 的预览查询语言提供Kubernetes metrics 已写入 Elasticsearch本文示例基于 OpenTelemetry 数据至少一个正在运行 workload 的 Kubernetes 集群以便 group by 查询可以进行对比分析场景你正在管理一组 Kubernetes 集群集群区域角色prod-us-east-1美国东部生产环境服务、ML 训练prod-eu-west-1欧洲西部生产环境区域 Web 层、缓存staging-us-east-1美国东部预发布环境QA、集成测试dev-sandbox美国东部开发者沙箱环境美国东部的生产集群运行着多种服务以及 ML 训练任务分布在多个 namespace 中。此时一个告警触发整个集群的 CPU 使用率升高但只有某一个团队反馈响应时间变慢。你的排查目标是先定位哪个 cluster出问题 → 再定位哪个 namespace→ 最后定位具体哪个 pod。你的目标并不是用一条查询完成完整 root-cause 证明而是快速锁定 “嫌疑对象” 并完成交接。你的数据OpenTelemetry Collector 的 Kubelet Stats Receiver 会生成如下 data streammetrics-kubeletstatsreceiver.otel-default指标遵循 k8s.* 命名规范例如 k8s.pod.cpu.usage并通过如下标签进行切分k8s.cluster.namek8s.namespace.namek8s.pod.name这些标签允许你按 cluster、namespace 或 pod 进行分析。为了确认数据已经存在打开 Discover → 切换到 ES|QL 模式 → 运行TS metrics-* | WHERE data_stream.dataset kubeletstatsreceiver.otel即可验证数据流是否正常写入。调查找出 noisy neighbor噪声邻居步骤 1哪个 cluster 最“热”当你管理多个 Kubernetes 集群时应先从 fleet 层级开始排查。PROMQL sum by (k8s.cluster.name) (k8s.pod.cpu.usage)该查询会按 cluster 聚合所有 pod 的 CPU 使用量。结果中prod-us-east-1 立刻显现异常其 pod 总 CPU 使用量比其他集群高出一个数量级。而欧洲生产集群、staging以及 dev-sandbox 都相对平稳。现在你已经知道问题出在哪个 cluster接下来该继续向下钻取。步骤 2查看热点 cluster 的整体 CPU先过滤到 prod-us-east-1再观察整体 CPU 使用情况PROMQL sum(k8s.pod.cpu.usage{k8s.cluster.nameprod-us-east-1})这会显示整个 cluster 中 pod CPU 使用量随时间变化的整体趋势。如果总量持续上升或出现尖峰说明某些 workload 发生了变化但此时你还不知道具体是谁导致的。步骤 3按 namespace 拆分要最快定位“哪个团队在制造负载”最直接的方法就是按 namespace 进行分组分析。PROMQL sum by (k8s.namespace.name) (k8s.pod.cpu.usage{k8s.cluster.nameprod-us-east-1})设置 Kibana 的 time picker 覆盖你的 incident window。ml-training 在 ~2.0 cores 时占主导而其他每个 namespace 都远低于 0.2 cores。步骤 4下钻到 pod现在你已经知道 namespace接下来定位具体的 podPROMQL sum by (k8s.pod.name) (k8s.pod.cpu.usage{k8s.cluster.nameprod-us-east-1, k8s.namespace.nameml-training})它会按该 namespace 内的 CPU 总使用量对 pod 进行排序。这个图表应该能让异常值一目了然。Pod model-train-v2-run-47-d9j67 正在消耗完整的 2.0 cores。它是一个训练任务已经把分配的资源打满了。步骤 5检查资源利用率比例原始 CPU cores 只能告诉你用了多少而利用率比例可以告诉你距离上限还有多近。一个 pod 如果 CPU 利用率达到 100%说明它正在被 throttling限流既是 noisy neighbor同时也因为自身限制而受影响。PROMQL sum by (k8s.namespace.name) (k8s.container.cpu_limit_utilization{k8s.cluster.nameprod-us-east-1})ml-training 显示约 ~100% 的 CPU limit utilization卡在 2-core 的上限而其他 namespace 都低于 20%。这进一步确认该训练任务已经耗尽其分配资源并可能正在对共享节点造成调度压力。接下来会发生什么PromQL query 已经定位到嫌疑对象训练任务 model-train-v2-run-47 在 ml-training 中。从这里开始日志在 Discover 中按 pod name 过滤查看训练任务在做什么以及是否记录了错误或警告。Kube events检查同一时间窗口内是否有 OOMKilled、throttling 或 eviction 事件。资源策略检查训练任务的 requests 和 limits 是否匹配实际使用情况。request 和 limit 之间的较大差距会让 pod 突破 scheduler 预期的资源规划。考虑在 namespace 上设置ResourceQuota或LimitRange。原文https://www.elastic.co/observability-labs/blog/promql-investigate-kubernetes-infrastructure

更多文章