Elasticsearch 可观察性:采用 Prometheus 和 OpenMetrics 标准收集指标
本篇博文将介绍以下内容:
- 为什么开放标准很重要
- Prometheus 公开格式
- Elastic 如何看待可观察性
- Elasticsearch 可以使用 Prometheus 指标的三种方式
- 举例说明如何收集和可视化由 Prometheus Redis 导出器公开的指标
开放标准
在 opensource.com 上,有一篇名为“什么是开放标准?”的参考性资源文档。 在该文档中 阐述了很多重要观点,但基于多年的 操作经验来看,我对下面几点比较认同:
- 可用性:开放标注可供所有人读取和 实施。
- 使最终用户的选择最大化
- 无歧视(供应商中立):开放标准以及 管理开放标准的组织不会偏爱 其中的某个实施者。
- 没有刻意的秘密:标准不得隐瞒 针对可互操作实施所必需的任何详细信息。
这些无可争议的理由足以说明为什么开放标准是优秀的了。 接下来,我们先来谈谈为什么 Prometheus 公开格式是 OpenMetrics 的基础。在 PromCon 2018 和 KubeCon + CloudNativeCon North America 2018 的会谈中,Richard Hartmann 总结了 受 Prometheus 公开格式影响而创建开放标准的几点原因:
- 大部分数据格式是专有的,或者很难实施, 亦或是两种情况都有
- Prometheus 已成为云原生 指标监测的实际标准
- 公开数据的易用性使得 兼容指标端点出现激增
- Prometheus 的公开格式虽然是基于大量操作 经验,但一直是在少数人之中设计的
- 其他一些项目和供应商在采用 “竞争性”产品中的某些功能时极为受挫
Prometheus 公开格式
您可以在 Prometheus Github 存储库中阅读有关公开格式的信息。现在,我们来看一个示例。 我有一个导出器, Oliver006 Redis 导出器,其在 /metrics 端点的端口 9121 上发布指标。 我在这里只介绍有关 Redis 的“每秒即时操作数”指标的信息。 有三行 需要阅读:
- 帮助文本
- 指标类型(在此用例中为仪表)
- 当前测量的 Redis 服务器(localhost 端口 6379),及其 当前读数(每秒操作数为 9 个)
Elastic 可观察性
我建议您阅读有关 Elastic 如何看待可观察性的文章,但其中 我最喜欢的部分是:
设计和构建“可观察”系统的目标在于, 确保当它在生产中运行时, 负责操作它的人员能够检测到不良行为(例如,服务停机、 错误、响应缓慢),并拥有可操作的信息, 以有效地确定根本原因(例如,详细的事件日志、 细粒度的资源使用信息,以及应用程序跟踪)。
我完全同意这种说法,它表明 我们需要所有日志、指标和跟踪信息,以运行、 修复和管理我们提供的服务。 Prometheus 是 可观察性中极其重要的一部分,因为它已被广泛采用 且拥有活跃的社区。 只有为“操作中产生”的符合常理的指标格式 扫除了采用障碍(无论这些障碍是真实的还是感知的), OpenMetrics 标准才会实现增值。
我交谈过的大部分人对使用 Elastic Stack (ELK) 进行日志分析都十分熟悉。 如果您不了解 Elastic Stack 还非常适合指标和 APM,请查看 指标和 APM/分布式跟踪。
我们认为,在 Elastic Stack 和 Prometheus 指标导出方式之间 进行深度集成很有意义,主要原因如下:
- 在 Elasticsearch 中将指标与日志和 APM 合并, 并在 Kibana 中将它们关联起来。请查看来自 NS1 的 一个 用户案例,了解有关在 Elastic Stack 中合并日志与指标的信息。
- 使用 Elasticsearch 作为长期存储,用于通过 Prometheus 服务器收集的指标, Prometheus 服务器目前 不支持原生集群。
- 对分散在不同地理位置 的 Prometheus 实例的指标实现全球查看。
本博文的其余部分将详细描述我们如何实现这些 集成。
示例导出器
我的演示环境运行于 Google Kubernetes 引擎 (GKE) 中,所以我的应用程序、 Metricbeat 和 Prometheus 导出器都是在 Kubernetes 中运行。 下面 是一段 Oliver006 的清单,用于将 Redis 导出器部署 为 Redis 映像旁边的挎斗。 如您所见,导出器 在端口 9121 上发布指标,这是 Prometheus Redis 导出器的 默认分配的端口号 。
... - name: redis-exporter image: oliver006/redis_exporter:latest resources: requests: cpu:100m memory:100Mi ports: - containerPort:9121 ...
使用 Metricbeat Prometheus 模块收集指标
Metricbeat 是 Elastic 的轻量型指标采集器。 Metricbeat 随附的 Prometheus 模块可以采用三种方式 收集指标:
- 通过端口 9090 连接到 Prometheus 服务器, 并使用 Prometheus 联合 API 拉取已收集的指标 (以获得 Prometheus 收集的指标)
- 使用 /metrics 端点 通过端口 9090 连接到 Prometheus 服务器(Prometheus 自我监测)
- 连接到各个 Prometheus 导出器并解析 公开格式
至于您选择哪种方法收集指标,要取决于 您对 Prometheus 服务器的熟悉程度。
- 如果您已经设置了 Prometheus 服务器来收集指标, 并希望直接查询这些指标以进行集成, 则可以从选项 (1) 和 (2) 入手。
- 另一方面,如果您还没有 Prometheus 服务器, 或者不介意通过多个工具并行收集导出器, 则可以使用选项 (3)。
注意:上述某些 Metricbeat 功能在 Metricbeat 版本 7.0 中为公测版。 我们建议您 下载 7.0 公测版, 或从 https://www.docker.elastic.co/ 复制容器链接,并在非生产环境中运行公测版。
Prometheus 联合 API
一般来说,联合用于支持扩展、将数据集合并在一起,或在不同位置提供数据副本(用于灾难恢复)。 Prometheus 服务器提供一个 /federation
端点,Elastic 可以连接到此端点,以复制 Prometheus 出于上述原因而收集的指标。
... - module: prometheus period:10s hosts: ["prometheus-service.monitoring.svc.cluster.local:9090"] metrics_path: '/federate' query: 'match[]': '{__name__!=""}' ...
在上例中,查询设置为“具有非空名称的任何内容”。 您不需要获取所有内容,Prometheus 文档中包含了有关如何编写更具限制性的匹配条件的信息。 此外,该示例中将期间设置为每 10 秒连接到 Pometheus 服务器一次,我的演示服务器仅从少数 Pod 和 kube-state-metrics 收集指标,但您可能需要更改该时间间隔。
Prometheus 自我监测
Prometheus 提供一个 /metrics
端点,像导出器一样。 这样您就可以收集有关 Prometheus 服务器的指标。 该端点的配置如下:
... - module: prometheus period:10s hosts: ["prometheus-service.monitoring.svc.cluster.local:9090"] metrics_path: /metrics ...
Prometheus 导出器收集
某一清单中的这段 YAML 用于部署一个 Metricbeat
DaemonSet,告知 Metricbeat 自动发现
其中
kubernetes.labels.app
== redis
的内容,并从该 Pod
的端口 9121 读取指标。 请记住,为 Redis 导出器容器设置的 containerPort
为 9121。
... - condition.equals: kubernetes.annotations.prometheus.io/scrape: "true" config: - module: prometheus period:10s # Redis pods hosts: ["${data.host}:9121"] metrics_path: /metrics ...
部署 Metricbeat 后,任何满足条件 kubernetes.labels.app == redis 的 Pod 都会应用 Prometheus 模块, 并从 端口 9121 的导出器挎斗中收集指标。
但是,在 k8s 环境中怎能缺了元数据呢,对吗? 让我们用 元数据和 Beats 自动发现功能来一展身手。 请看下面这段代替 上述 YAML 的内容:
... - condition.equals: kubernetes.annotations.prometheus.io/scrape: "true" config: - module: prometheus period:10s hosts: ["${data.host}:${data.kubernetes.annotations.prometheus.io/port}"] metrics_path: /metrics ...
现在,我们寻找的不是 Redis pod 的导出器,
而是任何注释
kubernetes.annotations.prometheus.io/scrape
设置为 true 的 Pod 导出器。 这也是
Prometheus 自动发现的设置方式。 通常情况下,Metricbeat
自动发现由 elastic.co
命名空间中的注释驱动,但既然我们在讨论从 Prometheus
导出器读取,我们就应遵守与
Prometheus 关联的标准 k8s 注释。 如果您查看上述内容中的主机列表:
hosts: ["${data.host}:${data.kubernetes.annotations.prometheus.io/port}"]
您可以看到,我们不再硬编码端口 9121,因为
它是 Redis 导出器的端口。 注释
prometheus.io/port
设置为导出器的端口号。 为了完整起见,
下面提供一段 guestbook.yaml,
其中设置了这些注释:
... kind:Deployment metadata: name: redis-master spec: replicas:1 template: metadata: annotations: prometheus.io/scrape: "true" prometheus.io/port:"9121" labels: app: redis ...
我提到过元数据在 k8s 环境中不可或缺吗? 那不是七十年代后期的一首歌吗?
通过可视化获得洞察力
虽然将数据引入 Elastic Stack 非常好,但您必须能够与数据进行交互。 在以下视频中,我们将看到如何使用由 Prometheus 收集(然后导入 Elastic Stack)的 Redis 指标,以及使用 Metricbeat 直接从 kube-state-metrics 收集的 Kubernetes 事件来构建有用的可视化。
如果您希望按照视频操作并获得更详细的说明,请 参阅 示例存储库。
返回可观察性
在最后这部分,我们为 Oliver006 Redis 导出器公开的 关键 Redis 指标(每秒即时操作数) 创建了一个 Kibana 可视化。 我们的下一步是收集日志, 然后创建一个仪表板,并在 我们的应用程序中将日志和指标合并在一起。
如需了解如何在 Kubernetes 环境中收集日志, 我建议您按照 elastic/examples GitHub 存储库中的说明进行操作。 只需几分钟,即可 让 Filebeat、Metricbeat 和 Packetbeat 收集数据,并 发布到 Elasticsearch。 使用随附的各种 Beats 的示例仪表板, 您可以随意 为 Prometheus 数据创建自己的可视化,并混合使用这些可视化, 以创建适合您工作方式的仪表板。如果您遇到任何问题或希望讨论可观察性,请访问 讨论论坛。