Bartek Płotka 自 2019 年以来一直是 Prometheus 的维护者,现任 Red Hat 首席软件工程师。他是 CNCF Thanos 项目的共同作者,CNCF 大使以及 CNCF TAG 可观测性技术负责人。在业余时间,他正在与 O'Reilly 合作撰写一本名为《高效 Go》的书籍。以上观点仅代表我个人!
我个人非常喜欢 Prometheus 项目,这也是我加入该团队的众多原因之一,那就是项目对目标的激光般聚焦。Prometheus 一直致力于突破界限,提供实用、可靠、廉价但又非常宝贵的基于指标的监控。Prometheus 超稳定且强大的 API、查询语言和集成协议(例如 Remote Write 和 OpenMetrics)使得云原生计算基金会 (CNCF) 指标生态系统能够在这些坚实的基础上发展壮大。结果令人惊叹。
- 我们可以看到社区为几乎所有事物开发了导出器,例如 容器、eBPF、Minecraft 服务器统计信息,甚至 园艺时植物的健康状况。
- 现在大多数人期望云原生软件具有 Prometheus 可以抓取的 HTTP/HTTPS
/metrics
端点。这个概念最初在 Google 内部秘密开发,并由 Prometheus 项目在全球范围内率先推广。
- 可观测性范式发生了转变。我们看到 SRE 和开发人员从一开始就严重依赖指标,这提高了软件的弹性、可调试性和数据驱动的决策能力!
最终,我们几乎看不到没有运行 Prometheus 的 Kubernetes 集群。
Prometheus 社区的强大关注也促使其他开源项目发展壮大,从而将 Prometheus 的部署模型扩展到单节点之外(例如 Cortex、Thanos 等)。更不用说云厂商也采用了 Prometheus 的 API 和数据模型(例如 Amazon Managed Prometheus、Google Cloud Managed Prometheus、Grafana Cloud 等)。如果您正在寻找 Prometheus 项目如此成功的一个原因,那就是:将监控社区的注意力集中在重要的事情上。
在这篇(冗长的)博客文章中,我想介绍一种新的 Prometheus 运行操作模式,称为“Agent”(代理)。它直接内置于 Prometheus 二进制文件中。代理模式禁用了 Prometheus 的一些常用功能,并针对抓取和远程写入到远程位置进行了优化。引入减少功能的模式可以实现新的使用模式。在这篇博文中,我将解释为什么它对于 CNCF 生态系统中的某些部署来说是一个游戏规则改变者。我对此感到非常兴奋!
转发用例的历史
Prometheus 的核心设计在其整个生命周期中一直没有改变。受 Google 的 Borgmon 监控系统 的启发,您可以将 Prometheus 服务器与您要监控的应用程序一起部署,告诉 Prometheus 如何访问它们,并允许定期抓取其指标的当前值。这种收集方法通常被称为“拉取模型”,是 使 Prometheus 变得轻量级和可靠 的核心原则。此外,它使得应用程序仪表化和导出器变得非常简单,因为它们只需要提供一个简单的人类可读的 HTTP 端点,其中包含所有跟踪指标的当前值(以 OpenMetrics 格式)。所有这些都无需复杂的推送基础设施和非平凡的客户端库。总的来说,简化的典型 Prometheus 监控部署如下所示:

这非常有效,多年来我们已经看到了数百万个像这样的成功部署,它们处理了数千万个活跃序列。其中一些用于更长时间的保留,例如两年左右。所有这些都允许查询、告警和记录对集群管理员和开发人员都有用的指标。
然而,云原生世界正在不断发展和演变。随着托管 Kubernetes 解决方案的增长以及在几秒钟内按需创建的集群,我们现在终于能够将集群视为“牲畜”,而不是“宠物”(换句话说,我们不太关心这些集群的单个实例)。在某些情况下,解决方案甚至不再具有集群的概念,例如 kcp、Fargate 和其他平台。

另一个有趣的用例是 边缘 集群或网络的概念。随着电信、汽车和物联网设备等行业采用云原生技术,我们看到越来越多资源受限的小型集群。这迫使所有数据(包括可观测性数据)都必须传输到远程、更大的对等方,因为几乎没有数据可以存储在这些远程节点上。
这意味着什么?这意味着监控数据必须以某种方式聚合、呈现给用户,有时甚至存储在全局级别。这通常被称为 全局视图 功能。
天真地,我们可以考虑通过将 Prometheus 放在全局级别并跨远程网络抓取指标,或者直接从应用程序将指标推送到中央位置进行监控来实现这一点。让我解释一下为什么这两种方法通常都是非常糟糕的主意:
🔥 跨越网络边界进行抓取可能会带来挑战,因为它会在监控管道中增加新的未知因素。本地拉取模型允许 Prometheus 确切地知道指标目标为何以及何时出现问题。也许它已关闭、配置错误、重新启动、速度太慢无法提供指标(例如 CPU 饱和)、服务发现无法发现、我们没有访问凭据,或者只是 DNS、网络或整个集群都已关闭。通过将抓取器放在网络外部,我们可能会因引入与单个目标无关的不可靠抓取而丢失一些信息。最重要的是,如果网络暂时中断,我们可能会完全失去重要的可见性。请不要这样做。不值得。(
🔥 直接从应用程序将指标推送到某个中央位置同样糟糕。尤其是当您监控大型集群时,当您看不到来自远程应用程序的指标时,您实际上什么都不知道。应用程序是否已关闭?我的接收器管道是否已关闭?也许应用程序未能授权?也许它未能获取远程集群的 IP 地址?也许它太慢了?也许网络已关闭?更糟糕的是,您甚至可能不知道某些应用程序目标的数据丢失了。而且您并没有获得太多好处,因为您需要跟踪应该发送数据的每件事的状态和状况。这种设计需要仔细分析,因为它很容易成为失败的根源。
注意: 无服务器函数和短生命周期的容器通常是我们考虑从应用程序推送作为补救措施的情况。然而,此时我们讨论的是事件或指标片段,我们可能希望将其聚合到更长时间的时间序列中。此主题在
此处 讨论,欢迎您贡献力量,帮助我们更好地支持这些情况!
Prometheus 引入了三种方法来支持全局视图用例,每种方法都有其优点和缺点。让我们简要地了解一下这些方法。它们在下图中以橙色显示:

-
联邦(Federation) 作为第一种聚合功能被引入。它允许全局级别的 Prometheus 服务器从叶级 Prometheus 服务器抓取指标子集。“联邦”抓取减少了跨网络的一些未知因素,因为联邦端点公开的指标包括原始样本的时间戳。然而,它通常会受到无法联合所有指标以及在较长的网络分区(分钟)期间丢失数据的困扰。
-
Prometheus 远程读取(Remote Read) 允许从远程 Prometheus 服务器的数据库中选择原始指标,而无需直接的 PromQL 查询。您可以将 Prometheus 或其他解决方案(例如 Thanos)部署在全局级别,以便在此数据上执行 PromQL 查询,同时从多个远程位置获取所需的指标。这非常强大,因为它允许您“本地”存储数据,并在需要时才访问它。不幸的是,也有缺点。在没有像 查询下推(Query Pushdown) 这样的功能的情况下,在极端情况下,我们需要拉取 GB 级的压缩指标数据来回答单个查询。此外,如果发生网络分区,我们将暂时失明。最后但并非最不重要的一点是,某些安全指南不允许入口流量,只允许出口流量。
- 最后,我们有 Prometheus 远程写入(Remote Write),这似乎是目前最流行的选择。由于代理模式专注于远程写入用例,让我们更详细地解释一下它。
远程写入
Prometheus 远程写入协议允许我们将 Prometheus 收集的所有或部分指标转发(流式传输)到远程位置。您可以配置 Prometheus 将某些指标(如果需要,可以包含所有元数据和样本!)转发到一个或多个支持远程写入 API 的位置。事实上,Prometheus 既支持接收也支持发送远程写入,因此您可以将 Prometheus 部署在全局级别以接收该流并聚合跨集群的数据。
虽然官方的 Prometheus 远程写入 API 规范仍处于审查阶段,但生态系统已将远程写入协议作为默认的指标导出协议。例如,Cortex、Thanos、OpenTelemetry 和云服务(如 Amazon、Google、Grafana、Logz.io 等)都支持通过远程写入摄取数据。
Prometheus 项目还为其 API 提供了官方的合规性测试,例如为提供远程写入客户端功能的解决方案提供的 远程写入发送器合规性。这是一个快速判断您是否正确实施此协议的好方法。
从这样的抓取器流式传输数据可以通过允许您在集中位置存储指标数据来实现全局视图用例。这也有助于关注点分离,当应用程序由不同的团队管理,而不是可观测性或监控管道时,这非常有用。此外,这也是供应商选择远程写入的原因,他们希望尽可能多地减轻客户的工作负担。
等一下,Bartek。你之前不是提到直接从应用程序推送指标不是最好的主意吗!
当然,但令人惊奇的是,即使使用远程写入,Prometheus 仍然使用拉取模型从应用程序收集指标,这使我们能够了解这些不同的故障模式。之后,我们批量处理样本和序列,并将数据导出、复制(推送)到远程写入端点,从而限制了中央点拥有的监控未知数!
重要的是要注意,可靠且高效的远程写入实现是一个非平凡的问题。Prometheus 社区花费了大约三年的时间才提出了稳定且可扩展的实现。我们多次重新实现了 WAL(预写日志),添加了内部排队、分片、智能退避等。所有这些都对用户隐藏起来,用户可以享受高性能的流式传输或存储在集中位置的大量指标。
远程写入实践示例:Katacoda 教程
所有这些在 Prometheus 中都不是新鲜事物。我们中的许多人已经使用 Prometheus 来抓取所有必需的指标,并将所有或部分指标远程写入到远程位置。
假设您想尝试远程写入功能的实践体验。在这种情况下,我们推荐 Thanos Katacoda 教程:从 Prometheus 远程写入指标,其中解释了 Prometheus 将所有指标转发到远程位置所需的所有步骤。它是免费的,只需注册一个帐户即可享受教程!🤗
请注意,此示例使用 Thanos 以接收模式作为远程存储。如今,您可以使用大量其他与远程写入 API 兼容的项目。
因此,如果远程写入工作正常,为什么我们要向 Prometheus 添加特殊的 Agent 模式?
Prometheus Agent 模式
从 Prometheus v2.32.0
(下一个版本)开始,每个人都将能够使用实验性的 --enable-feature=agent
标志运行 Prometheus 二进制文件。如果您想在发布之前尝试它,请随时使用 Prometheus v2.32.0-beta.0 或使用我们的 quay.io/prometheus/prometheus:v2.32.0-beta.0
镜像。
Agent 模式优化了 Prometheus 以用于远程写入用例。它禁用了查询、告警和本地存储,并将其替换为自定义的 TSDB WAL。其他一切都保持不变:抓取逻辑、服务发现和相关配置。如果您只想将数据转发到远程 Prometheus 服务器或任何其他与远程写入兼容的项目,则可以将其用作 Prometheus 的直接替代品。本质上,它看起来像这样:

关于 Prometheus Agent 最好的部分是它内置于 Prometheus 中。相同的抓取 API、相同的语义、相同的配置和发现机制。
如果您计划不在本地查询或告警数据,而是将指标流式传输到外部,那么使用 Agent 模式有什么好处呢?有以下几点:
首先,效率。我们的自定义 Agent TSDB WAL 在成功写入后立即删除数据。如果无法访问远程端点,它会将数据临时持久化到磁盘上,直到远程端点恢复在线。目前这仅限于两小时的缓冲区,与非 Agent Prometheus 类似,希望很快解除限制。这意味着我们不需要在内存中构建数据块。我们不需要维护用于查询目的的完整索引。从本质上讲,Agent 模式使用的资源只是正常 Prometheus 服务器在类似情况下使用资源的一小部分。
这种效率重要吗?是的!正如我们所提到的,对于某些部署来说,边缘集群上使用的每 GB 内存和每个 CPU 核心都很重要。另一方面,使用指标执行监控的范式在今天已经相当成熟。这意味着您可以以相同的成本传输更多相关的、更高基数的指标 - 就越好。
注意: 随着 Agent 模式的引入,原始 Prometheus 服务器模式仍然是推荐的、稳定和维护的模式。带有远程存储的 Agent 模式带来了额外的复杂性。请谨慎使用。
其次,新的 Agent 模式的好处是它可以更容易地实现水平扩展以进行数据摄取。这是我最兴奋的事情。让我解释一下原因。
梦想:自动可扩展的指标摄取
真正的自动可扩展的抓取解决方案需要基于指标目标的数量及其公开的指标数量。我们需要抓取的数据越多,我们自动部署的 Prometheus 实例就越多。如果目标数量或其指标数量减少,我们可以缩减规模并删除几个实例。这将消除手动调整 Prometheus 大小的负担,并停止在集群暂时较小时过度分配 Prometheus 的需求。
仅使用服务器模式的 Prometheus,这很难实现。这是因为服务器模式下的 Prometheus 是有状态的。无论收集到什么都保持原样在一个地方。这意味着缩减规模的过程需要在终止之前将收集到的数据备份到现有实例。然后我们将面临抓取重叠、误导性陈旧标记等问题。
最重要的是,服务器模式下 Prometheus 的资源使用量取决于比数据摄取更多的因素。例如,告警、记录、查询、压缩、远程写入等,可能需要更多或更少的资源,而与指标目标的数量无关。
Agent 模式本质上将发现、抓取和远程写入移动到一个单独的微服务。这使得操作模型专注于仅进行数据摄取。因此,Agent 模式下的 Prometheus 或多或少是无状态的。是的,为了避免指标丢失,我们需要部署一对 HA 代理并为它们附加持久磁盘。但从技术上讲,如果我们有数千个指标目标(例如容器),我们可以部署多个 Prometheus 代理,并安全地更改哪个副本正在抓取哪些目标。这是因为,最终,所有样本都将被推送到相同的中央存储。
总的来说,Agent 模式下的 Prometheus 实现了基于 Prometheus 的抓取的轻松水平自动扩展能力,可以对指标目标的动态变化做出反应。这绝对是我们未来将与 Prometheus Kubernetes Operator 社区一起研究的方向。
现在让我们看一下 Prometheus 中当前实现的 Agent 模式的状态。它可以使用了吗?
Agent 模式已在大规模环境中得到验证
下一个版本的 Prometheus 将包含 Agent 模式作为实验性功能。标志、API 和磁盘上的 WAL 格式可能会更改。但由于 Grafana Labs 的开源工作,该实现的性能已经过实战检验。
我们的 Agent 自定义 WAL 的初始实现灵感来自当前 Prometheus 服务器的 TSDB WAL,由 Robert Fratto 在 2019 年在 Prometheus 维护者 Tom Wilkie 的指导下创建。然后,它被用于开源 Grafana Agent 项目中,该项目自那时起已被许多 Grafana Cloud 客户和社区成员使用。鉴于该解决方案的成熟度,现在是将该实现捐赠给 Prometheus 以进行原生集成和更广泛采用的时候了。Robert (Grafana Labs) 在 Srikrishna (Red Hat) 和社区的帮助下,将代码移植到 Prometheus 代码库中,该代码库在 2 周前合并到 main
分支!
捐赠过程非常顺利。由于一些 Prometheus 维护者之前在 Grafana Agent 中为此代码做出了贡献,并且由于新的 WAL 受 Prometheus 自己的 WAL 的启发,因此当前的 Prometheus TSDB 维护者不难将其纳入全面维护!Robert 加入 Prometheus 团队担任 TSDB 维护者(祝贺!)也确实很有帮助。
现在,让我们解释一下如何使用它!(
如何详细使用 Agent 模式
从现在开始,如果您显示 Prometheus 的帮助输出(--help
标志),您应该会看到大致如下的内容:
usage: prometheus [<flags>]
The Prometheus monitoring server
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
(... other flags)
--storage.tsdb.path="data/"
Base path for metrics storage. Use with server mode only.
--storage.agent.path="data-agent/"
Base path for metrics storage. Use with agent mode only.
(... other flags)
--enable-feature= ... Comma separated feature names to enable. Valid options: agent, exemplar-storage, expand-external-labels, memory-snapshot-on-shutdown, promql-at-modifier, promql-negative-offset, remote-write-receiver,
extra-scrape-metrics, new-service-discovery-manager. See https://prometheus.ac.cn/docs/prometheus/latest/feature_flags/ for more details.
由于 Agent 模式位于功能标志之后,如前所述,请使用 --enable-feature=agent
标志在 Agent 模式下运行 Prometheus。现在,其余标志要么用于服务器模式和 Agent 模式,要么仅用于特定模式。您可以通过检查标志的帮助字符串的最后一句话来查看哪个标志用于哪种模式。“仅用于服务器模式”意味着它仅用于服务器模式。如果您没有看到任何类似的提及,则表示该标志是共享的。
Agent 模式接受相同的抓取配置,具有相同的发现选项和远程写入选项。
它还公开了一个 Web UI,其中禁用了查询功能,但显示了构建信息、配置、目标和服务发现信息,与正常的 Prometheus 服务器相同。
Prometheus Agent 实践示例:Katacoda 教程
与 Prometheus 远程写入教程类似,如果您想尝试 Prometheus Agent 功能的实践体验,我们推荐 Thanos Katacoda 教程:Prometheus Agent,其中解释了运行 Prometheus Agent 的简易程度。
总结
希望您觉得这很有趣!在这篇文章中,我们回顾了出现的新用例,例如:
- 边缘集群
- 有限访问网络
- 大量集群
- 短暂且动态的集群
然后,我们解释了新的 Prometheus Agent 模式,该模式允许高效地将抓取的指标转发到远程写入端点。
与往常一样,如果您有任何问题或反馈,请随时在 GitHub 上提交工单或在邮件列表中提问。
这篇博客文章是 CNCF、Grafana 和 Prometheus 之间协调发布的一部分。也欢迎阅读 CNCF 公告 和关于 Grafana Agent(Prometheus Agent 的基础)的角度。