基于 ES|QL 的 Kubernetes 监控工具箱:使用 ES|QL 进行 Kubernetes 监控,从内存压力到错误日志
本文提供的 Elasticsearch ES|QL 查询快速定位 Kubernetes 集群中的崩溃循环、OOM 前夕的内存压力、节点资源饱和以及命名空间级别的错误尖峰。所有查询均基于 Elastic 发行的 OpenTelemetry CollectorEDOT采集的数据可 Discover 中运行也可保存为仪表板面板或告警规则。前置条件Elasticsearch 9.2 或更高版本ES|QL 在 8.11 中引入但 9.2 后的 TS 命令更完善。EDOT Collector 已在集群中运行并启用了以下接收器receiverskubeletstats采集 Pod、容器、节点的资源指标CPU、内存、网络等。k8s_cluster采集 Kubernetes 对象状态如 Pod 相位、容器重启次数。filelog配合k8sattributes处理器采集容器日志并添加上下文属性命名空间、Pod 名等。EDOT 会将这些数据通过 OpenTelemetry 协议OTLP发送至 Elasticsearch指标存储在metrics-*索引日志存储在logs-*索引。ES|QL 之 Kubernetes 监控ES|QL 是一种管道式查询语言它的核心思想是从一个数据源开始每一行追加一个操作——过滤、计算、聚合、排序——逐步精炼你的查询。这种结构天然适合故障排查因为你可以像剥洋葱一样层层缩小问题范围。例如一个典型的 ES|QL 查询流程如下FROM metrics-* // 数据源 | WHERE timestamp NOW() - 1h // 时间过滤 | STATS count BY namespace // 聚合统计 | SORT count DESC // 排序每行只做一件事逻辑清晰易于调试和复用。TS 命令与时间序列Kubernetes 指标绝大多数是计数器Counter或仪表盘Gauge它们随时间变化采样而来。使用TSTime Series命令可以正确处理时间序列的语义对于Gauge如当前内存使用率你关心的是最新值或峰值而非平均值。对于Counter如累计重启次数你关心的是增量或最大值而非对时间窗口内的所有样本求和那样会得到一个无意义的巨大数字。TS命令为每个时间序列由维度如pod、container唯一标识单独处理聚合函数并支持TBUCKET对时间进行分桶。普通FROM则适用于计数去重、简单取最大值等不涉及时间窗口内序列间计算的场景。EDOT 采集器与依赖字段EDOT 采集的数据遵循OpenTelemetry 语义约定但具体的指标名称由接收器定义而非语义规范本身。因此不同接收器输出的字段名可能不同。接收器典型指标/字段说明kubeletstatsk8s.container.memory_limit_utilizationk8s.pod.cpu.node.utilizationk8s.node.cpu.usagek8s.container.restarts资源利用率指标来自 kubelet 的 APIk8s_clusterk8s.pod.phasePod 相位编码为数字filelogk8sattributesbody.text日志内容severity_text日志级别k8s.pod.name、k8s.namespace.name日志消息与上下文注意如果你启用的接收器不同或自定义了采集配置某些字段可能缺失。请将下面的查询视为模板根据实际索引映射调整字段名称。集群概览从全局开始在深入具体问题之前先把握集群的整体面貌。以下查询统计过去一小时内每个命名空间有多少个不同的 Pod 上报了指标FROM metrics-* | WHERE timestamp NOW() - 1 hour | STATS pod_count COUNT_DISTINCT(k8s.pod.name) BY k8s.namespace.name | SORT pod_count DESC原理解释COUNT_DISTINCT会去重同一个 Pod 在时间窗口内产生的多个采样点因此每个 Pod 只被计数一次。结果是一个“命名空间 — Pod 数量”的排行榜快速告诉你哪些命名空间负载最重也能帮你发现预期运行的 Pod 是否“消失”了如果某个命名空间计数为 0说明它可能已缩容或没有被采集到。定位 Pod 重启与崩溃循环重启是问题的第一信号。k8s.container.restarts是一个 Gauge 类型报告每个容器的当前累计重启次数该值会持续增长直到容器被重新创建。以下查询列出过去 24 小时内重启次数最多的容器FROM metrics-* | WHERE timestamp NOW() - 24 hours AND k8s.container.restarts IS NOT NULL | STATS restarts MAX(k8s.container.restarts) BY k8s.namespace.name, k8s.pod.name, k8s.container.name | WHERE restarts 0 | SORT restarts DESC | LIMIT 20原理解释MAX(k8s.container.restarts)取得该时间窗口内每个容器重启计数的最新值因为 Gauge 的值会随时间更新最大值即当前最新值。如果一个容器的重启次数很高且在持续上升这几乎是CrashLoopBackOff的教科书式信号。拿到 Pod 名称后你可以直接跳转到后面的日志查询查看它崩溃前输出了什么。发现非 Running 状态的 Pod重启次数告诉你“过去发生过故障”而Pod 相位Phase告诉你“现在是否健康”。k8s.pod.phase是一个编码为数字的 Gauge数值相位1Pending2Running3Succeeded4Failed5Unknown以下查询使用TS读取每个 Pod 的最新相位并筛选出非 Running的 PodTS metrics-* | WHERE TRANGE(15m) | STATS phase MAX(LAST_OVER_TIME(k8s.pod.phase)) BY k8s.namespace.name, k8s.pod.name | WHERE phase ! 2 | EVAL phase_name CASE( phase 1, Pending, phase 3, Succeeded, phase 4, Failed, phase 5, Unknown, Other) | SORT phase_name原理解释TRANGE(15m)限定时间范围为最近 15 分钟。LAST_OVER_TIME从每个 Pod 的时间序列中取出最新样本确保我们比较的是当前状态而非平均值。MAX在这里只是辅助因为每个 Pod 在最后一个时间点只有一个值语法要求必须有聚合函数。结果中Pending的 Pod 通常表明调度问题资源不足Failed或Unknown则需要立即关注。在 OOM 发生前捕捉内存压力OOMOut-Of-MemoryKill是 Kubernetes 中最常见的故障之一而且预防远胜于事后调试。当你在kubeletstats接收器中启用了 limit 元数据默认开启EDOT 会上报k8s.container.memory_limit_utilization它表示容器内存使用量占其limit的比例取值范围 0~1。以下查询找出过去一小时内容器内存使用峰值超过 85% limit的容器TS metrics-* | WHERE TRANGE(1h) | STATS peak_mem_pct MAX(MAX_OVER_TIME(k8s.container.memory_limit_utilization)) BY k8s.namespace.name, k8s.pod.name, k8s.container.name | EVAL peak_mem_pct ROUND(peak_mem_pct * 100, 1) | WHERE peak_mem_pct 85 | SORT peak_mem_pct DESC原理解释MAX_OVER_TIME在每个容器的时间序列内部找出峰值因为 Utilization 是 Gauge随时间波动。外层MAX确保每个容器只输出一个最终峰值由于TS可能产生多个时间分片此处用MAX取最大值。如果一个容器的峰值反复超过 95%那它极有可能成为下一个 OOM 牺牲品。结合重启查询如果一个容器同时满足“重启次数高”和“内存峰值高”几乎可以断定它因 OOM 被杀后重启了。追踪 CPU 使用率与节点压力CPU 问题通常表现为节流Throttling和响应变慢而非崩溃。k8s.pod.cpu.node.utilization指标报告每个 Pod 的 CPU 使用量占整个节点容量的比例因此所有 Pod 的该值之和不应超过 1。5 分钟粒度下最繁忙的 PodTS metrics-* | WHERE TRANGE(1h) | STATS avg_cpu AVG(AVG_OVER_TIME(k8s.pod.cpu.node.utilization)) BY k8s.pod.name, TBUCKET(5m) | SORT avg_cpu DESCTBUCKET(5m)将时间划分为 5 分钟桶每个桶内AVG_OVER_TIME对每个 Pod 的时间序列求平均外层AVG再合并同名 Pod因为一个 Pod 可能包含多个容器但其 Pod 级指标只有一个时间序列。结果可渲染为时间序列图直观展示 CPU 使用高峰。节点级别的资源饱和检查若要判断节点本身是否过载直接查询节点指标TS metrics-* | WHERE TRANGE(1h) | STATS cpu AVG(AVG_OVER_TIME(k8s.node.cpu.usage)), mem AVG(LAST_OVER_TIME(k8s.node.memory.usage)) BY k8s.node.name, TBUCKET(5m) | SORT cpu DESCk8s.node.cpu.usage是节点 CPU 使用率百分比通常 0~1k8s.node.memory.usage是内存使用率。如果某个节点的 CPU 长期接近 100%那它上面所有 Pod 都会受到节流影响这很容易被误认为是应用程序自身的问题。深入容器日志排查当指标将你指向某个 Pod 后日志会告诉你它当时在做什么。EDOT 将日志消息存储在body.text字段日志级别存储在severity_text同时附带了k8s.*上下文字段与指标一致。按错误量对 Pod 排名FROM logs-* | WHERE timestamp NOW() - 1 hour AND severity_text IN (ERROR, FATAL) | STATS errors COUNT(*) BY k8s.namespace.name, k8s.pod.name | SORT errors DESC | LIMIT 20这个查询帮你快速识别错误集中的 Pod。如果错误分布均匀可能是集群级问题如果集中在某个 Pod则是该工作负载的个例。查看特定 Pod 的日志带关键词过滤FROM logs-* | WHERE timestamp NOW() - 1 hour AND k8s.pod.name checkout-your-hash AND body.text LIKE *timeout* | KEEP timestamp, severity_text, body.text | SORT timestamp DESC | LIMIT 50LIKE *timeout*执行通配符匹配。若想进行全文相关性搜索可替换为MATCH(body.text, timeout)。KEEP只保留你关心的字段使结果更清晰。组合查询一次 Kubernetes 事故的完整调查链实际运维中我们通常串联多个查询而非孤立运行。典型的调查循环如下是否按错误量排名 Pod检查目标 Pod 的重启次数和内存峰值是否因 OOM 重启查看该 Pod 的日志搜索 OOM 相关关键词查看日志搜索异常堆栈或超时确认问题根因并采取措施因为所有查询都使用相同的k8s.namespace.name和k8s.pod.name字段你可以将 Pod 名称从一个查询直接复制到下一个。这种一致性也方便构建联动仪表板——点击某个命名空间或 Pod所有面板同步过滤。将查询升级为告警与仪表板本文中任何生成聚合值的查询都可以转化为告警规则而不仅仅是临时排查工具。以重启查询为例若要监控“15 分钟内重启超过 5 次”的情况只需稍作调整FROM metrics-* | WHERE timestamp NOW() - 15 minutes AND k8s.container.restarts IS NOT NULL | STATS restarts MAX(k8s.container.restarts) BY k8s.namespace.name, k8s.pod.name, k8s.container.name | WHERE restarts 5将此查询配置为Elasticsearch 查询规则Elastic 的告警框架当结果非空时触发告警。你就能在用户发现之前第一时间收到通知。同样的模式可应用于内存利用率 90%节点 CPU 95%错误日志数 阈值Pod 相位非 Running总结构建你的 ES|QL 监控工具包ES|QL 用一种统一的语法覆盖了 Kubernetes 所有的可观测信号对象状态Pod 相位、重启次数资源指标CPU、内存、网络容器日志错误、堆栈、事件查询类型关键函数适用场景集群概览COUNT_DISTINCT查看命名空间负载重启排行MAXGauge发现崩溃循环非运行 PodLAST_OVER_TIME检查当前健康状态内存压力MAX_OVER_TIME预测 OOM 风险CPU 使用AVG_OVER_TIMETBUCKET追踪资源热点错误日志排名COUNT(*)定位故障 Pod日志详情LIKE/MATCH深入排查根因开始你的监控之旅吧先用概览查询熟悉集群面貌然后将重启、相位、内存、CPU 和日志查询保存为常用工具。当事故发生时按调查链串联使用。再进一步将高频查询制作成仪表板将关键阈值升级为告警。小贴士根据你实际启用的接收器某些指标字段名可能有所不同。请查阅 EDOT 文档调整查询中的字段名称。但核心逻辑和聚合函数是通用的足以应对大多数场景。现在你已经拥有了一套。祝排查愉快

相关新闻

45-学生场景-构建学习笔记系统

45-学生场景-构建学习笔记系统

45 学生场景:构建学习笔记系统 解剖学笔记的逆袭 小林是某医科大学的大三学生。去年秋季学期,他选了最让人头疼的《人体解剖学》——全书将近1000页,需要记忆的骨骼、肌肉、神经和血管数量多到让人绝望。 "开学第一周我就懵了。老师讲课速度很快,每节课讲几十个解剖…

2026/10/4 11:40:38 阅读更多 →
【2027最新】基于SpringBoot+Vue的社区团购系统管理系统源码+MyBatis+MySQL

【2027最新】基于SpringBoot+Vue的社区团购系统管理系统源码+MyBatis+MySQL

博主介绍:🌟 个人简介 CSDN特邀作者 | 掘金优质创作者,深耕Java生态与现代Web开发技术栈。专业领域涵盖Java企业级开发、Spring Boot微服务架构、前后端分离解决方案,以及学术项目的工程化实践。 📊 影响力数据 全平台…

2026/10/6 10:55:16 阅读更多 →
TMS320VC5510/5510A DSP架构解析与嵌入式开发实战指南

TMS320VC5510/5510A DSP架构解析与嵌入式开发实战指南

1. 项目概述:深入解析TMS320VC5510/5510A定点DSP在嵌入式信号处理领域,尤其是对功耗和实时性有严苛要求的便携式音频设备、早期视频编解码器或工业控制系统里,德州仪器(TI)的TMS320C55x系列DSP曾经是许多工程师的“老朋…

2026/10/12 0:28:29 阅读更多 →

最新新闻

KNN图像识别入门:从PCA降维到手写数字分类实战

KNN图像识别入门:从PCA降维到手写数字分类实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:37:04 阅读更多 →
52pojie 的 IoT 固件分析:熵值会告诉你哪一段藏了东西

52pojie 的 IoT 固件分析:熵值会告诉你哪一段藏了东西

副题:魔术字、香农熵、结构体——拆开一个固件镜像的三把钥匙 摘要:吾爱破解软件调试区里有一篇《IoT 漏洞分析之模拟环境搭建》(6037 回复),同区还有《记一次手机付费充电设备研究》(7196)。这…

2026/10/15 1:37:04 阅读更多 →
双 11 核心链路变异测试大摸底:让关键交易状态机测试坚不可摧

双 11 核心链路变异测试大摸底:让关键交易状态机测试坚不可摧

在电商交易系统中,最核心、也最令架构师夜不能寐的领域内核,永远是有限状态机(Finite State Machine, FSM)。 在双 11 狂风暴雨般的流量洪峰冲击下,一笔交易订单在几毫秒内可能经历极其错综复杂的状态跳转:…

2026/10/15 1:37:04 阅读更多 →
u-boot-2020.07在Exynos4412上的电源时钟内存初始化实战

u-boot-2020.07在Exynos4412上的电源时钟内存初始化实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:37:04 阅读更多 →
行业术语同义词图谱挖掘:从非结构化语料到标准化知识库的语义归一

行业术语同义词图谱挖掘:从非结构化语料到标准化知识库的语义归一

在将海量企业内部非结构化语料(如研发设计文档、售后工单、专家经验纪要、行业研报)汇聚到统一知识库并驱动 RAG(检索增强生成)系统时,工程团队往往面临一个巨大的语义鸿沟——“专有名词的极度多样性与非标准性”。 在…

2026/10/15 1:37:04 阅读更多 →
工业机器人坐标系全解析:从原理到标定实操

工业机器人坐标系全解析:从原理到标定实操

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:36:03 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →