经验报告:在 Cloud Foundry 中采用 OpenTelemetry 进行指标收集
博客文章在发布后不会更新。这篇文章已经发布一年多了,其内容可能已过时,部分链接可能无效。在依赖任何信息之前,请务必核实。
Cloud Foundry 最近集成了 OpenTelemetry Collector 进行指标出口,我们在整个过程中学到了很多。我们对当前的集成所提供的功能以及它为我们打开的各种可能性感到兴奋。
我们寻找的目标
Cloud Foundry 是一个大型的多租户平台即服务,运行 12-factor 应用程序。Cloud Foundry 平台工程团队通常运行 4 到 8 个 Cloud Foundry 部署,托管数千个应用程序和数十万个容器。Cloud Foundry 的用户众多,我们在指标方面的目标是让平台工程团队能够集成他们选择的监控工具,而不是强制规定单一解决方案。
历史上,为新监控工具添加支持是通过我们自己的 Firehose API 实现的,这需要为每个工具编写一个新的“Nozzle”,进入门槛很高。Firehose API 在处理大量日志和指标时也被发现存在固有的性能限制。由于 API 和集成方法的不可扩展性,我们开始寻找替换 Cloud Foundry 指标出口方式的方法。
我们正在寻找一种可扩展的方式,能够从数百台虚拟机和数千个容器中出口指标,且没有瓶颈或单点故障。我们还希望有一个活跃的社区来支持平台工程团队可能希望使用的各种监控工具,这样我们就可以不再维护自定义集成。
我们评估的选项
我们很容易就同意在每台虚拟机上添加一个代理,将指标直接发送到监控工具。在 Cloud Foundry 中,我们已经看到这种方法对于日志出口效果很好,消除了瓶颈和单点故障。
我们评估了几种流行的指标出口解决方案。除了 OpenTelemetry,我们还认真研究了 Fluent Bit 和 Telegraf。
对于我们考虑的每一个解决方案,我们都从以下几个方面进行了评估:
- 灵活性:我们可以发送到多少个监控工具?
- 性能:CPU 和内存使用效率如何?
- 社区:社区参与度如何?他们使用什么语言/工具?
- 部署:能否作为 BOSH 作业进行部署并在 Cloud Foundry 部署的约束下工作?是否可以热重载配置?
我们选择 OpenTelemetry 的原因
当我们研究 Fluent Bit 时,发现它是用 C 语言编写的,这可能带来一些性能优势,但我们主要使用 Go 语言。我们很早就放弃了 Fluent Bit,因为我们对代码库的贡献能力会非常有限,这让我们担心未来可能会受到限制。
然后我们更认真地研究了 Telegraf 和 OpenTelemetry。两者都是用 Go 语言编写的,在这方面我们都很满意。我们选择 OpenTelemetry 的主要原因是其可定制的构建过程:OpenTelemetry 允许我们 构建一个 Collector,其中包含我们自己组件和社区组件的精选组合。
此外,在研究 OpenTelemetry 时,我们发现许多 工具 和 供应商 都增加了对 OpenTelemetry Protocol (OTLP) 的原生支持。这让我们有信心采用 OpenTelemetry Collector,因为它是一个被广泛采用的 OTLP 的第一方实现。
我们 在 RFC 中提议将 OpenTelemetry Collector 添加到 Cloud Foundry,并征集了社区的反馈。该提议于 2023 年 7 月 7 日被接受,随后我们开始着手实施。
我们如何将 OpenTelemetry 集成到我们当前的指标系统中
在 Cloud Foundry 中,我们有一套负责转发日志和指标的代理。入口是一个“Forwarder Agent”,它以我们自己的自定义格式接收日志和指标,并将它们多路复用给其他代理。
我们在我们的代理中添加了支持,将指标转换为 OTLP 并转发给 OpenTelemetry Collector。这只需要 大约 200 行 Go 代码,其中大部分代码只是为了闭合花括号。在编写这些代码时,我们不得不思考如何将我们现有的数据模型转换为 OpenTelemetry Protobuf 数据模型。我们发现 OpenTelemetry 已经考虑了许多我们过去遇到过,以及我们尚未遇到的边缘情况。有一天,我们希望能够有效地使用 Scopes 和 Resources。
我们的实现效果很好,但我们发现 OpenTelemetry Collector 使用了大量的 CPU。我们最初采取了最简单的方式,每次 gRPC 请求只发送一个指标。当我们 添加批处理功能后,Collector 的资源利用率急剧下降。
它如何服务于 Cloud Foundry 平台工程团队
平台工程团队现在可以在部署 Cloud Foundry 时 选择性地提供 OpenTelemetry Collector 导出器配置。部署中的每个虚拟机将运行一个 Collector,该 Collector 使用该配置将指标转发到指定的监控工具。
我们从小处着手,目前仅支持 OTLP 和 Prometheus 导出器。然而,我们期待听到平台工程团队希望使用的其他导出器,并将其添加到我们的 OpenTelemetry Collector 发行版中。
下一步
当我们着手这项工作时,我们完全专注于指标。为我们的 OpenTelemetry Collector 集成添加日志作为另一种支持的信号类型有着清晰的路径。我们目前在 Cloud Foundry 中尚未内置支持追踪,但我们对追踪能够为平台组件和在平台上运行的应用程序提供的可能性感到兴奋。
我们当前的 OpenTelemetry Collector 集成提供了我们称之为“聚合通道”的功能,用于导出平台或在平台上运行的应用程序生成的信号。我们还希望提供“应用程序通道”,它将只将来自单个应用程序的信号导出到应用程序团队选择的监控工具。这涉及复杂的路由以及导出器的频繁创建和删除,这可能需要新的 OpenTelemetry Collector 功能。
如果我们能够实现这些目标,我们就可以用每台虚拟机上运行的单个 OpenTelemetry Collector 取代我们整个代理套件。这些 Collector 将处理系统组件以及平台上运行的每个应用程序的日志、指标和追踪。