Elastic Observability 中的 Prometheus 指标:你的 PromQL 可以保持不变地运行

发布时间:2026/7/22 9:42:47
Elastic Observability 中的 Prometheus 指标:你的 PromQL 可以保持不变地运行 作者来自 Elastic Bahubali Shetti使用一个配置块将你的 Kubernetes 集群中的 Prometheus 指向 Elastic Observability。PromQL 可以保持不变地运行保留你的 PromQL不产生基数计费。现在是凌晨 2:14你的 Kubernetes 集群触发了一条告警。你打开 Grafana 查看内存图表然后打开 Loki 查看容器日志接着打开 APM 工具检查上游服务是否已经出现性能下降。三个标签页11 分钟之后你得到了一个假设而用于验证它的那个标签在上个季度为了降低指标账单已经被删除。Elasticsearch 现在可以在与日志和追踪相同的列式后端中存储 Prometheus 指标每个数据点仅需 3.75 字节并且不会产生自定义指标额外费用。图表、日志和追踪都可以通过一种查询语言进行查询。使用一个现有的 Kubernetes 集群本文示例使用 AWS EKS通过一个配置块将 Prometheus 指向 Elastic无需构建任何仪表板即可在 Discover 中查看所有指标运行大部分现有 PromQL 而无需修改探索 ES|QL 如何突破 PromQL 的表达能力限制最后使用相同的查询语言读取日志。你的采集方式不会发生任何变化。你的抓取配置、重新标记规则以及服务发现配置都可以原样迁移。大部分 PromQL 也可以继续使用 —— 第 5 步中的覆盖说明会介绍其中的差异。第 1 步从 Elastic Observability 获取 Prometheus 端点和 API 密钥你需要 Elastic Cloud Serverless 或 Elastic Cloud Hosted。这两者都无需配置即可提供 Prometheus 端点。Serverless是最快的开始方式。登录 cloud.elastic.co 并创建一个 Observability 项目。无需进行容量规划也无需进行资源配置。Elastic Cloud Hosted对本文中的所有内容同样适用并且当你需要特定的技术栈版本、特定区域拓扑或者托管集群提供的部署级控制能力时它是更合适的选择。在 UI 中查找 Prometheus 端点并创建 API 密钥要获取 Prometheus 端点和 API 密钥请进入 Kibana点击左侧导航栏中的Add data。对于 Prometheus滚动到页面底部的Connect directly to the endpoint然后选择Prometheus标签页。需要复制两项内容端点。它看起来像https://my-observability-project-xxx.ingest.us-west-2.aws.elastic.cloud。注意其中的.ingest.主机名。它与你的 Elasticsearch 搜索端点或 Kibana URL 不是同一个主机。API 密钥。点击Create key。在关闭对话框之前复制该值因为之后无法再次获取。如果你希望手动设置权限范围可以使用Open in API keys打开完整编辑器。指标写入所需的最低权限如下{ ingest: { indices: [ { names: [metrics-*], privileges: [auto_configure, create_doc] } ] } }第 2 步确保 Prometheus 正在抓取你的 Kubernetes 集群Prometheus 应该已经在抓取你的集群。如果还没有最快的方式是使用kube-prometheus-stackHelm chart它可以通过一个命令安装 Prometheus Operator、Prometheus 本身、kube-state-metrics和node-exporterhelm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update helm install prometheus prometheus-community/kube-prometheus-stack \ --namespace monitoring --create-namespace这会提供本文后续部分中看到的指标cAdvisor 容器指标container_cpu_usage_seconds_total、container_memory_working_set_byteskube-state-metrics 集群对象kube_deployment_spec_replicas、kube_daemonset_status_number_ready。第 3 步配置 Prometheus 远程写入到第 1 步中的 Prometheus 端点Elasticsearch 原生实现了 Prometheus Remote Write 协议。不需要适配器、不需要 sidecar也不需要转换层。你只需要添加一个配置块数据就会在下一个抓取周期开始流入。如果你运行 Prometheus OperatorOperator 不会读取你手动编写的prometheus.yml。它会根据Prometheus自定义资源生成配置文件而其中的authorization.credentials是对 Kubernetes Secret 的引用而不是内联值。首先创建这个 Secretkubectl create secret generic elastic-prometheus \ --namespace monitoring \ --from-literalapi_keyYOUR_API_KEY然后在values.yaml中引用它prometheus: prometheusSpec: remoteWrite: - url: https://my-observability-project-xxxx.ingest.us-west-2.aws.elastic.cloud:443/api/v1/write authorization: type: ApiKey credentials: name: elastic-prometheus key: YOUR_API_KEY然后应用它helm upgrade prometheus prometheus-community/kube-prometheus-stack \ --namespace monitoring \ -f values.yaml使用 prometheus.yml 配置 Prometheus remote write同样在prometheus.yml中remote_write: - url: https://YOUR_ES_ENDPOINT/_prometheus/metrics/node/eks/api/v1/write authorization: type: ApiKey credentials: YOUR_API_KEY如果你运行 Grafana Alloy请使用以下配置prometheus.remote_write elasticsearch { endpoint { url https://YOUR_ES_ENDPOINT/_prometheus/metrics/node/eks/api/v1/write headers {Authorization ApiKey YOUR_API_KEY} } }remote write URL 如何映射到 Elasticsearch 数据流你不需要在任何地方指定索引。在remote_write配置中请求负载中没有索引字段也没有数据流字段。Elasticsearch 会根据写入路径推导目标数据流并在收到第一个样本时创建它。/metrics/后面的两个路径段分别代表数据集和命名空间URL数据流/_prometheus/api/v1/writemetrics-generic.prometheus-default/_prometheus/metrics/{dataset}/api/v1/writemetrics-{dataset}.prometheus-default/_prometheus/metrics/{dataset}/{namespace}/api/v1/writemetrics-{dataset}.prometheus-{namespace}上面的示例使用/metrics/node/eks/它会写入metrics-node.prometheus-eks。这是你将在下一步 Discover 中看到的数据流。使用数据集和命名空间可以区分生产环境和预发布环境或者为每个集群和每个团队提供具有独立保留策略和降采样策略的数据流。如果你更希望保持简单的/api/v1/writeURL也可以通过每个时间序列进行路由为时间序列添加data_stream_dataset和data_stream_namespace标签它们的优先级高于 URL 路径。这两个字段属于控制字段因此它们会路由文档但不会存储在其labels对象中。Elasticsearch 会自行安装metrics-*.prometheus-*的索引模板。你不需要创建模板或映射。Prometheus 指标在 Elastic Observability 中的形式每个 Prometheus 样本都会变成一个文档。标签会成为作为时间序列维度的 keyword 字段。数值会存储在metrics.metric_name下{ timestamp: 2026-07-02T10:30:00.000Z, data_stream: { type: metrics, dataset: node.prometheus, namespace: eks }, labels: { __name__: container_memory_working_set_bytes, pod: checkout-7d9f6c4b8-x2kqp, namespace: oteldemo, container: checkout, node: ip-10-0-3-14.us-west-2.compute.internal }, metrics: { container_memory_working_set_bytes: 36700160 } }现在需要了解的一个注意事项。Elasticsearch 会根据指标名称推断某个指标是 counter 还是 gauge。以_total、_sum、_count或_bucket结尾的名称会被识别为 counter。其他所有指标都会被识别为 gauge。对于container_cpu_usage_seconds_total和container_memory_working_set_bytes这种推断是正确的。但对于你的环境中任何不遵循 Prometheus 命名规范的指标这种推断可能是错误的而错误分类的指标会被本应支持它的函数拒绝RATE(my_metric::counter)只能用于 counter。第 6 步会介绍如何覆盖这种推断。当前限制。仅支持 Remote Write v1。经典 histogram 和 summary 通过它们的_bucket、_sum和_count序列获得支持并分别映射到正确的指标类型。原生稀疏histogram 和 exemplars 会随着 Remote Write v2 到来目前已在路线图中。Staleness 标记不会被存储或遵循非有限值NaN、Infinity会被静默丢弃。完整列表请查看 Prometheus remote write ingest 文档。第 4 步验证 Prometheus 指标是否正在流入 Elasticsearch不要先去构建仪表板。首先确认数据管道是否正常而 Elastic 可以通过一个命令完成验证。在 Kibana 中打开Discover将查询编辑器切换到 ES|QL然后输入你刚刚写入的数据流名称TS metrics-node.prometheus-eks这就是完整的查询。Discover 会读取数据流找到其中的每个指标并将每个指标渲染为独立的时间序列图表。50 个指标50 个图表不需要构建仪表板也不需要为每个指标编写查询。它会读取指标类型并正确绘制图表gauge 使用平均值counter 使用速率histogram 使用 p95 分布。你也可以不用输入任何内容直接到达这里。在 Kibana 中选择Observability→Streams会列出集群中的所有数据流。带有Time series标记的数据流表示它是一个时间序列数据流。点击View in Discover系统会自动为你填入TS查询。这是你的数据摄取健康检查。需要关注三件事数据正在流入。存在最新且连续的值。不是出现间断也不是一条一小时前就停止的曲线。数值合理。小型容器的内存应该是几十 MB。CPU 应该是核心使用量的一部分。网络字节数应该反映真实流量。覆盖范围符合预期。如果缺少kube_pod_container_status_restarts_total说明你的 kube-state-metrics 抓取配置有问题你应该现在发现这个问题而不是等到基于它构建告警时才发现。在判断任何问题之前扩大时间选择范围。一个安静时段内的 15 分钟窗口可能会让健康的数据看起来像一条平线。要列出实际存在数据的内容而不是映射中声明的内容TS metrics-node.prometheus-eks | METRICS_INFO | SORT metric_name图表上方的No dimensions selected控件可以让你根据标签拆分每个图表选择pod每个图表会按照 pod 拆分成一条独立的时间序列。第 5 步在 Elastic Observability 中对 Prometheus 指标运行 PromQL 查询如果你的团队编写 PromQL就继续编写 PromQL。PROMQL是 ES|QL 中的源命令与FROM和TS并列并且可以在所有运行 ES|QL 的地方执行Discover、仪表板面板以及告警规则。它不会运行一个独立的引擎。它会解析表达式将每个函数解析为对应的 ES|QL 等价形式并构建一个TS执行计划因此你的 PromQL 可以获得与原生 ES|QL 相同的向量化并行执行能力。当前限制。PROMQL已在 Elastic Cloud Serverless 中正式发布并且在 Elastic Stack 9.4 中作为技术预览功能提供。根据热门 Grafana OSS 仪表板进行测试其查询覆盖率超过 80%。在直接粘贴仪表板查询之前需要了解以下差异histogram_quantile尚未实现这一点最重要因为几乎所有延迟仪表板都使用它计算 p95分组修饰符on(...) group_left(...)以及集合运算符or、and和unless不受支持此外predict_linear、label_join和label_replace目前也不可用。时间桶会按照固定日历边界对齐而不是根据查询开始时间对齐因此短时间范围或较大的步长可能会与 Prometheus 存在轻微差异。请查看当前的PROMQL 命令参考获取完整列表。CPU使用 PromQL 查询每个 pod 的 CPU 速率这是按照 pod 分组的容器每秒 CPU 使用速率。当某个地方出现高负载时这是你首先查看的内容PROMQL sum by (pod) (rate(container_cpu_usage_seconds_total[5m]))也可以按照 namespace 拆分用于查找哪个团队正在消耗集群资源PROMQL sum by (namespace) (rate(container_cpu_usage_seconds_total[5m]))注意返回的内容有一个pod列、一个step列以及一个以表达式本身命名的值列。这是一个普通的 ES|QL 表这正是其核心也是第 6 步构建的基础。内存使用 PromQL 查询工作集和 RSS工作集working set是与 OOM 风险相关的重要指标。它是内核用于计算限制的数值并且它不同于总分配内存PROMQL sum by (pod) (container_memory_working_set_bytes)常驻集resident set用于对比当你需要区分真正的内存泄漏和页面缓存时PROMQL sum by (pod) (container_memory_rss)网络使用 PromQL 查询每个 pod 的接收速率PROMQL sum by (pod) (rate(container_network_receive_bytes_total[5m]))集群对象使用 PromQL 查询副本数量查看声明的副本数未达到预期的 DeploymentPROMQL kube_deployment_spec_replicas有一个值得特别指出的便利之处在 Prometheus 中每个查询都需要显式指定start、end和step。而在 Kibana 中你无需指定这三个参数。时间选择器会提供时间范围Kibana 会自动推导step这就是为什么上面的每个查询都只有一行。使用 PromQL 查询构建 Kibana 仪表板上面的每个查询都可以作为一个仪表板面板。在 Discover 中点击Save或者进入Dashboards→Create→Add panel→ES|QL然后将查询粘贴进去即可。时间选择器会自动驱动start、end和step因此一个面板只需编写一次就可以适用于任意缩放级别。四个面板四条单行 PromQL 查询没有任何转换步骤。如果你是从 Grafana 迁移过来的这与你已有的仪表板完全相同大约五分钟就能重新构建完成。如果你根本不想重新构建也可以继续使用 Grafana并将现有的 Prometheus 数据源指向 Elasticsearch。文章末尾会介绍这种方式。第 6 步使用 ES|QL 查询 Prometheus 指标突破 PromQL 的表达能力ES|QL 中的PROMQL命令会编译为TS。下面这两个查询是等价的PROMQL sum by (pod) (rate(container_cpu_usage_seconds_total[5m]))TS metrics-node.prometheus-eks | WHERE TRANGE(1h) | STATS SUM(RATE(metrics.container_cpu_usage_seconds_total, 5m)) BY labels.pod, TBUCKET(1m)第二种形式才是真正让指标不再是一个与日志和追踪分离的世界——真正实现关联查询join的地方。Top-N 和过滤TS查询返回的是一个普通的 ES|QL 表因此后续可以直接使用SORT、LIMIT和WHERE。Top-N 不需要任何特殊函数也不需要topk。查找内存使用量最高的 10 个 pod只需要一个SORT和一个LIMITTS metrics-node.prometheus-eks | WHERE labels.pod IS NOT NULL | STATS mem SUM(metrics.container_memory_working_set_bytes) BY labels.pod | SORT mem DESC | LIMIT 10过滤也是同样的方式对聚合后的列使用WHERE即可。例如只显示内存超过 50 MB 的 podTS metrics-node.prometheus-eks | WHERE labels.pod IS NOT NULL | STATS mem SUM(metrics.container_memory_working_set_bytes) BY labels.pod | WHERE mem 50000000 | SORT mem DESC实际上你也可以对PROMQL查询的结果继续使用管道pipe并通过普通的 ES|QL 进行后处理。内存使用量与请求值的对比在发生内存问题时一个非常有用的问题是哪些 pod 的内存使用量已经超过了它们申请的资源超过了多少这个查询组合了两个指标而 ES|QL 可以通过一次扫描和过滤聚合来表达每个指标使用一个MAXTS metrics-node.prometheus-eks | WHERE labels.pod IS NOT NULL AND labels.namespace IS NOT NULL | STATS used_memory MAX(metrics.container_memory_working_set_bytes), requested_memory MAX(metrics.kube_pod_container_resource_requests) WHERE labels.resource memory BY labels.pod, labels.namespace, time_bucket TBUCKET(5 minute) | EVAL pct_of_request 100 * used_memory / requested_memory | WHERE pct_of_request 80 | SORT pct_of_request DESC | LIMIT 100附加在requested_memory上的WHERE是一个过滤聚合filtered aggregationkube_pod_container_resource_requests在labels.resource维度下同时包含 CPU 和内存因此该过滤条件仅保留内存相关的记录从而使计算得到的比例是真正的“内存使用量 / 内存请求值”。每个指标都存储在各自独立的文档中共享的BY键会将两个聚合结果落到同一行中。第 7 步使用 ES|QL 同时查询 Prometheus 指标和日志在前面的几个章节中我们使用了 ES|QL 和 PromQL 来分析指标。ES|QL 同样可以读取日志。下面是一个针对运行在该集群上的 OpenTelemetry demo 的简单查询FROM logs-* | WHERE TRANGE(30m) AND kubernetes.pod.name checkout-9656cbd88-fsr9v | STATS events COUNT(*) BY log.level, TBUCKET(1m) | SORT events DESC同一个编辑器同一个用于查询指标的时间选择器。唯一变化的是源命令从TS变成了FROM现在你查看的是按分钟、按日志级别统计的日志数量。一个查询语言即可覆盖指标和日志无需切换标签页也无需使用第二个工具。现在 Elastic Observability 中已经具备的能力Prometheus 通过一个配置块即可将数据写入 Elastic。每个指标都会自动在 Discover 中渲染无需构建仪表板。你现有的大多数 PromQL 查询都可以直接运行而 ES|QL 则更进一步支持 Top-N、过滤以及跨指标比率计算并且可以继续通过管道传递给 ES|QL 的其他命令。指标和日志可以在同一个窗口中使用同一种查询语言进行查询。整个过程中你无需删除任何标签也不会因为高基数cardinality而产生额外费用。后续步骤Grafana、仪表板迁移和 OpenTelemetry如果你希望继续使用 Grafana就继续使用。Elasticsearch 提供了兼容 Prometheus 的读取 API地址为endpoint/_prometheus。将 Grafana 现有的 Prometheus 数据源指向该地址并将数据源的httpMethod设置为GET你的 PromQL 仪表板即可继续工作。保留 Grafana替换 Mimir。迁移你的 Grafana 仪表板。当你准备完全迁移到 Kibana而不是仅仅让 Grafana 连接 Elasticsearch 时可以使用Observability Migration Platform。它能够将 Grafana 仪表板、面板和告警规则转换为 Kibana 原生格式。它是一个与数据源无关的 CLI 工具obs-migrate能够自动转换可转换的内容并标记需要人工处理的部分同时生成迁移报告展示哪些内容已成功转换以及哪些地方仍存在语义差异确保不会静默丢失任何内容。相关的迁移演练涵盖了从 Grafana 和 Datadog 到 Kibana 的完整迁移流程。想要添加 OpenTelemetry如果你同时使用 OpenTelemetry或者希望使用 OTel Collector 而不是 Prometheus 进行采集请阅读第 2 部分。两种方式的数据都会写入同一个存储并且可以使用相同的查询进行分析。开始免费试用https://cloud.elastic.co/registration文档Elastic Observability solution overview | Elastic Docs常见问题如何将 Prometheus 指标发送到 Elasticsearch在 Prometheus 配置中添加一个remote_write配置块将其指向https://YOUR_ES_ENDPOINT/_prometheus/metrics/{dataset}/{namespace}/api/v1/write并添加Authorization: ApiKey YOUR_KEY请求头即可。Elasticsearch 原生支持 Prometheus Remote Write v1 协议无需任何 adapter 或 sidecar。我可以在 Elasticsearch 中运行现有的 PromQL 查询吗大多数情况下可以。ES|QL 包含PROMQL源命令可直接接受标准 PromQL 表达式。在热门 Grafana OSS 仪表板上的测试覆盖率超过 80%。该功能已在 Elastic Cloud Serverless 正式发布并作为 Elastic Stack 9.4 的技术预览提供。目前histogram_quantile、predict_linear、label_join和label_replace尚未实现分组修饰符以及集合运算符or、and和unless也暂不支持。Elasticsearch 是否会根据 Prometheus 指标的 cardinality 收费不会。Elasticsearch 以每个数据点 3.75 字节的存储效率保存 Prometheus 指标不会根据 cardinality 收费也没有自定义指标费用无论你的指标包含多少种唯一标签组合。如何将 Prometheus 指标路由到 Elasticsearch 中不同的数据流Remote Write URL 中/metrics/后面的两个路径段分别指定 dataset 和 namespace。例如/metrics/node/eks/api/v1/write会写入metrics-node.prometheus-eks。你也可以针对每个时间序列通过data_stream_dataset和data_stream_namespace标签进行路由它们的优先级高于 URL 路径。Elasticsearch 支持哪些 Prometheus 指标类型Elasticsearch 支持 Remote Write v1包括 counter、gauge、经典 histogram 和 summary。counter 与 gauge 的分类会根据指标名称自动推断以_total、_sum、_count或_bucket结尾的名称会被识别为 counter其余则识别为 gauge。原生 histogram 和 exemplars 需要 Remote Write v2目前已在路线图中。我可以在 Elasticsearch 中同时查询 Prometheus 指标和日志吗可以。ES|QL 可以在同一个查询编辑器、同一个时间选择器中同时读取时间序列指标和日志。只需将TS metrics-node.prometheus-eks改为FROM logs-*语法保持一致窗口保持一致也无需使用第二个工具。相关阅读Elasticsearch日志领域的最佳选择如今也是指标领域的最佳选择使用 Remote Write 将 Prometheus 指标发送到 Elasticsearch使用原生 PromQL 支持在 Elasticsearch 中查询 Prometheus 指标不要浪费你的指标使用 ES|QL TS 命令查询它们将 Elasticsearch 作为 Grafana 的后端我们如何将 Elasticsearch 重构为列式指标引擎本文中描述的任何特性或功能的发布时间和交付时间均由 Elastic 自行决定。当前尚未提供的任何特性或功能可能无法按时交付或者根本不会交付。原文Prometheus metrics in Elastic Observability: your PromQL runs unchanged — Elastic Observability Labs