1. 引言
1.1. 背景设定
现代计算系统,特别是云原生环境和微服务架构,其复杂性日益增长,对先进的可观测性解决方案提出了迫切需求。传统的监控方法在这些高度动态和分布式的环境中常常捉襟见肘,难以提供足够深入和实时的洞察力。为了应对这些挑战,业界不断探索新的技术组合以提升系统的可见性、性能诊断能力和安全审计水平。
1.2. 技术主角介绍
在此背景下,两种强大的技术脱颖而出:eBPF(Extended Berkeley Packet Filter)和 Prometheus。eBPF 是一项革命性的 Linux 内核技术,它允许在内核的特权上下文中安全地运行沙盒化的程序,从而无需修改内核源码或加载内核模块即可扩展内核功能。Prometheus 则已成为云原生生态系统中基于指标的监控和告警的事实标准,特别适用于收集、存储和查询时间序列数据。
1.3. 报告主旨
本报告旨在提供一份专家级的深度分析,探讨 eBPF 与 Prometheus 的集成。我们将深入研究这两种技术各自的核心原理,并重点剖析它们结合使用的机制、优势、挑战以及实际应用场景。通过这种结合,可以实现更深层次的系统可见性、增强的性能监控和更强大的安全审计能力,为现代复杂系统提供前所未有的观测能力。
1.4. 目标读者与范围
本报告主要面向技术专业人士,包括站点可靠性工程师(SRE)、DevOps 工程师、云/系统架构师、安全工程师以及相关领域的研究人员。报告范围涵盖 eBPF 和 Prometheus 的基础知识、集成方法、协同优势、典型用例、潜在挑战、生态系统工具,并对这种技术组合的价值进行总结和比较。
现代系统监控正在经历一个明显的融合趋势,即利用内核级别的洞察力来丰富应用程序和基础设施的监控数据。将 eBPF 与 Prometheus 相结合正是这一趋势的体现,它旨在打破传统监控中基础设施监控(如 Prometheus Node Exporter)、应用性能监控(APM 代理)和安全监控(独立工具)之间的孤岛,迈向统一的可观测性。eBPF 能够观测系统调用、网络数据包和函数调用,提供了跨越这些传统领域的数据来源。而 Prometheus 则提供了收集、存储和查询这些多样化数据的强大平台。这种集成反映了业界希望整合不同维度的视图,以更全面地理解复杂系统(如 Kubernetes)内部交互的需求。这不仅仅是添加新的指标,更是为了构建对系统行为的整体性理解。
2. 理解 eBPF:内核的可编程性
2.1. 定义与起源
eBPF(Extended Berkeley Packet Filter)是一种允许在 Linux 内核的特权上下文中运行沙盒化程序的技术。它起源于最初用于网络数据包过滤的 BPF(Berkeley Packet Filter),但经过扩展,已发展成为一种通用的内核扩展机制。其核心价值在于能够安全、高效地扩展内核功能,而无需修改内核源代码或加载内核模块,从而避免了传统内核模块可能带来的风险和复杂性。
2.2. 核心概念
eBPF 的强大功能建立在一系列核心概念之上:
-
钩子 (Hooks): eBPF 程序是事件驱动的,当内核或应用程序执行到特定的“钩子点”时被触发执行。常见的钩子类型包括:
- 系统调用 (System Calls): 拦截用户空间应用对内核发起的调用。
- 内核探针 (Kernel Probes - kprobes/kretprobes): 对内核函数进行动态插桩,可以在函数入口或出口执行 eBPF 程序。
- 用户探针 (User Probes - uprobes/uretprobes): 对用户空间应用程序的函数进行动态插桩。
- 跟踪点 (Tracepoints): 内核中预定义的静态插桩点,用于追踪特定的内核事件。
- 网络事件 (XDP, TC): 附加到网络协议栈的不同位置,用于高效的数据包处理和分析。
-
映射 (Maps): eBPF Maps 是存在于内核中的键值存储结构,可供 eBPF 程序(内核空间)和用户空间应用程序通过系统调用进行访问。它们是 eBPF 程序存储状态、聚合数据以及与用户空间进行通信的关键机制。eBPF 支持多种类型的 Map,如哈希表、数组、环形缓冲区 (Ring Buffer)、性能事件缓冲区 (Perf Buffer)、栈跟踪存储、最长前缀匹配 (LPM) 表等,以满足不同场景的需求。
-
验证器 (Verifier): 在加载到内核之前,eBPF 程序必须通过一个严格的验证器检查,以确保其安全性。验证器执行多项检查,包括:
- 权限检查:确保加载程序的进程拥有必要的权限(通常是 root 或
CAP_BPF
/CAP_SYS_ADMIN
能力)。 - 程序终止保证:确保程序不会陷入无限循环,保证其最终会执行完毕。允许有界循环,但验证器必须能证明循环一定会退出。
- 内存安全:禁止访问越界内存或使用未初始化的变量。
- 资源限制:确保程序的大小和复杂度在系统允许的范围内。 验证器是 eBPF 安全性的基石,它保证了 eBPF 程序不会导致内核崩溃或破坏系统稳定,但它并不检查程序的逻辑意图是否符合安全策略。
- 权限检查:确保加载程序的进程拥有必要的权限(通常是 root 或
-
即时编译 (JIT Compilation): 通过验证后,eBPF 字节码会被 JIT 编译器翻译成目标机器的原生指令。这使得 eBPF 程序的执行效率接近原生编译的内核代码,极大地提升了性能。
-
辅助函数 (Helper Functions): eBPF 程序不能调用任意内核函数,而是通过一组预定义的、稳定的内核函数(称为辅助函数)来与系统交互,例如操作 Map、获取时间戳、修改网络数据包等。可用的辅助函数集合由内核定义,并随着内核版本不断扩展。
-
BPF CO-RE (Compile Once – Run Everywhere): CO-RE 是提高 eBPF 程序可移植性的关键技术。它依赖于 BTF(BPF Type Format)信息,允许 eBPF 程序在编译后无需在目标机器上重新编译就能适应不同的内核版本和配置。这显著降低了 eBPF 程序的开发和部署复杂性。
eBPF 的发展已经超越了简单的钩子机制,演变成一种内核内部的可编程接口。钩子、映射、辅助函数以及尾调用/函数调用的结合,使得开发者能够在内核中构建复杂的、事件驱动的逻辑。这类似于用户空间的微服务,但在操作系统层面运行,并享有内核的权限和效率。eBPF 程序不仅能被动地观察内核事件,还能主动地进行计算和操作,例如实现高性能负载均衡或执行安全策略。这种强大的内核内编程能力,实质上是在操作系统内部创建了一个动态的可编程层。
然而,eBPF 的强大功能伴随着固有的权衡。验证器在确保安全性的同时,也施加了严格的限制,例如禁止无限循环、限制内存访问方式和指令集。与内核模块相比,内核模块提供了最大的灵活性,但任何错误都可能导致系统崩溃。eBPF 通过验证器优先保证了安全性,但这使得 eBPF 程序的开发更具挑战性,并限制了其能够实现的复杂度,某些极其复杂的任务可能仍需依赖内核模块或无法用纯 eBPF 高效实现。这种安全性保证是 eBPF 得以广泛应用的关键因素,但开发者必须在安全约束和功能灵活性之间找到平衡。辅助函数和 CO-RE 等技术的发展,旨在通过提供安全的抽象和改善可用性来缓解这些限制。
2.3. 关键能力与独立应用场景
eBPF 的独特能力使其在多个领域得到广泛应用:
-
可观测性 (Observability): 以极低的开销提取细粒度的系统数据,包括指标、事件和追踪信息。典型应用包括应用程序追踪(帮助开发者理解行为和瓶颈)、性能剖析(识别系统和应用的性能问题)以及系统监控(收集详细的性能和资源利用率指标)。常用的工具有 bcc、bpftrace 等。
-
网络 (Networking): 实现高性能的网络数据包处理、负载均衡、流量控制和网络可见性。例如,Cilium 项目利用 eBPF 在 Kubernetes 中提供高性能的服务网格和网络策略。XDP(eXpress Data Path)则提供了在网络驱动层进行超高速包处理的能力。
-
安全 (Security): 在内核层面实施安全策略、检测入侵行为、提供运行时安全防护和进行安全审计。例如,Falco 使用 eBPF 检测异常系统活动,Tetragon 提供基于 eBPF 的安全可观测性和运行时强制执行。
3. 理解 Prometheus:云原生监控标准
3.1. 定义与角色
Prometheus 是一个开源的系统监控和告警工具集,最初由 SoundCloud 开发,现已成为云原生计算基金会(CNCF)的毕业项目。它特别适用于监控高度动态的、面向服务的架构,例如 Kubernetes 环境。其核心功能是收集和存储时间序列数据,并基于这些数据提供查询、可视化和告警能力。
3.2. 架构概览
Prometheus 生态系统由多个组件构成,其中许多是可选的:
- Prometheus Server: 这是核心组件,负责服务发现、指标抓取(采用拉模型)、数据存储(TSDB)和查询处理(PromQL)。Prometheus Server 通常设计为独立运行,依赖本地存储以保证可靠性。
- 时序数据库 (Time Series Database - TSDB): Prometheus Server 内建了一个高效的时序数据库,用于存储抓取到的指标样本。默认情况下,数据会保留一段时间(例如 15 天),并可以通过配置进行调整。
- Exporter: Exporter 是一个中间件,用于将第三方系统(如数据库、硬件、消息队列等)或未直接使用 Prometheus 客户端库进行插桩的应用程序的指标,转换为 Prometheus 可理解的格式,并暴露出来供 Prometheus Server 抓取。常见的 Exporter 包括 Node Exporter(用于主机指标)、JMX Exporter(用于 JVM 应用)等。
- Alertmanager: 负责处理由 Prometheus Server 根据告警规则生成的告警。它管理告警的去重、分组、静默,并将通知路由到不同的接收器(如 Email, Slack, PagerDuty)。
- Pushgateway: 允许生命周期短暂的、无法被 Prometheus Server 主动抓取的作业(如批处理任务)将它们的指标推送给 Prometheus。需要注意的是,Pushgateway 适用于特定的场景,并非主要的指标收集方式。
- Client Libraries: Prometheus 提供了多种语言的客户端库,方便开发者直接在应用程序代码中进行插桩,以暴露符合 Prometheus 格式的指标。
3.3. 数据模型
Prometheus 的数据模型是其强大功能的基础:
- 时间序列 (Time Series): Prometheus 存储的所有数据都是时间序列,即带有时间戳的指标值流。
- 指标名称 (Metric Name) 与标签 (Labels): 每个时间序列由其指标名称和一组可选的键值对(称为标签)唯一标识。指标名称通常表示被测量的物理量(例如
http_requests_total
),而标签则用于区分同一指标的不同维度(例如method="POST"
,handler="/api/users"
)。 - 指标类型 (Metric Types): Prometheus 定义了四种主要的指标类型:
- Counter (计数器): 一个单调递增的累积值,只能增加或在重启时重置为零。常用于记录事件发生的总次数,如处理的请求总数、发生的错误总数。
- Gauge (仪表盘): 表示一个可以任意上升或下降的数值。常用于测量瞬时值,如当前温度、内存使用量、队列中的任务数。
- Histogram (直方图): 对观察值(如请求延迟或响应大小)进行采样,并将其分布情况计入可配置的桶 (bucket) 中。它还提供所有观察值的总和以及观察值的总数。Prometheus 的直方图是累积的,即每个桶的值包含小于等于该桶上边界的所有观察值数量。
- Summary (摘要): 与直方图类似,也对观察值进行采样。但它直接计算并存储可配置的分位数(Quantile)在一个滑动的时间窗口内,同时也提供观察值的总数和总和。
- 标签的重要性: 标签是 Prometheus 多维数据模型的核心,它提供了强大的过滤、分组和聚合能力,使得用户能够灵活地查询和分析数据。
3.4. 拉模型 (Pull Model) 与服务发现
- 拉模型: Prometheus 主要采用拉模型进行指标收集。Prometheus Server 定期通过 HTTP 请求主动从配置的目标(Exporter 或已插桩的应用)暴露的端点(通常是
/metrics
)抓取指标。这与许多采用推模型(由被监控端主动推送数据)的系统不同。 - 服务发现: 在动态环境中,手动配置所有目标是不现实的。Prometheus 支持静态配置目标,更重要的是,它支持多种动态服务发现机制,可以自动发现和更新需要抓取的目标列表。常见的服务发现方式包括基于 Kubernetes API、Consul、EC2 等。这对于自动化监控云原生环境至关重要。
3.5. PromQL 简介
- 定义: PromQL (Prometheus Query Language) 是 Prometheus 使用的一种强大而灵活的函数式查询语言,专门用于查询和操作其存储的时间序列数据。
- 用途: PromQL 用于即时查询、在仪表盘(如 Grafana)中创建图表,以及定义告警规则。
- 基本概念: PromQL 允许用户通过指标名称和标签选择时间序列,并应用各种函数(如计算速率
rate()
、求和sum()
、求平均avg()
)和运算符(算术、比较、逻辑、聚合)来进行复杂的分析和聚合。
Prometheus 的设计哲学是优先保证可靠性而非 100% 的数据准确性。这意味着 Prometheus 被设计成在系统发生故障时仍然可用的监控系统,以便快速诊断问题,但它不保证捕获到每一个数据点。Prometheus 服务器的独立性和对本地存储的依赖增强了其可靠性,因为故障域被隔离了。然而,拉模型意味着如果目标宕机或响应缓慢,抓取可能会失败,导致数据出现间隙。此外,数据可能是采样收集的,而非记录每一个事件。这种设计确保了即使在系统不稳定时,Prometheus 本身仍能提供服务,允许查询历史数据以进行故障排查。但这种潜在的数据缺失或采样特性意味着它不适用于需要绝对完整和精确数据的场景,例如按请求计费。
Prometheus 强大的多维数据模型(通过标签实现)既是其优势,也是其潜在的弱点。高基数(High Cardinality),即存在大量唯一的标签组合,会对 Prometheus 的性能、内存使用和存储造成严重影响。标签使得过滤和聚合非常灵活,但每一个唯一的“指标名称+标签集”组合都会创建一个独立的时间序列。在高度动态的环境中(例如 Kubernetes,包含大量 Pod、容器、请求 ID、用户 ID 等),标签组合的数量可能爆炸式增长。Prometheus 需要存储和处理所有这些时间序列,导致内存消耗急剧增加(甚至引发 OOMKilled)、存储需求膨胀以及查询性能下降。这迫使用户必须积极管理基数,通过谨慎设计指标和标签、使用聚合规则或丢弃某些标签来控制,但这可能会牺牲数据的粒度。如何在细节和性能之间取得平衡,是 Prometheus 运维中的核心挑战之一。
4. 集成 eBPF 与 Prometheus:连接内核洞察与指标体系
4.1. 集成的必要性
eBPF 在内核空间收集原始的、低级别的数据,如事件或统计信息,而 Prometheus 则通过 HTTP 端点消费标准化的时间序列指标。这两者之间存在语义和协议上的差距。因此,需要一个桥梁来将 eBPF 收集到的丰富但原始的数据进行转换、聚合,并以 Prometheus 能够理解和抓取的格式暴露出来。没有这个转换层,Prometheus 无法直接利用 eBPF 提供的深度内核可见性。
4.2. 暴露 eBPF 数据的机制
将 eBPF 数据传递给用户空间并最终转换为 Prometheus 指标,主要依赖以下机制:
- eBPF Maps: 如前所述,eBPF Maps 是内核空间 eBPF 程序与用户空间应用程序之间共享数据的主要方式。用户空间进程可以读取 Maps 中的数据(例如计数器、状态信息、聚合结果)。
- Perf/Ring Buffers: 对于事件流数据(例如每次网络连接、每次文件打开),使用 Perf Buffer 或 Ring Buffer 是更高效的方式。eBPF 程序可以将事件数据推送到这些缓冲区,用户空间进程再从中读取。
- 用户空间处理: 通常需要一个运行在用户空间的应用程序来负责从 eBPF Maps 或 Buffers 中读取数据。这个应用程序会对原始数据进行必要的处理,例如:统计事件发生频率、计算速率、构建直方图分布、添加上下文标签等,最终将其格式化为 Prometheus 指标。
4.3. Prometheus Exporter 的角色
在此集成场景中,Prometheus Exporter 特指一个用户空间应用程序,它承担了以下关键职责:
- 加载并管理一个或多个 eBPF 程序到内核。
- 通过 eBPF Maps 或 Perf/Ring Buffers 从内核收集数据。
- 对收集到的数据进行处理、聚合和转换,生成符合 Prometheus 指标格式(Counter, Gauge, Histogram, Summary)的时间序列数据。
- 启动一个 HTTP 服务器,并在特定端点(通常是
/metrics
)上暴露这些生成的指标。 - 等待 Prometheus Server 定期访问该端点进行抓取。
这些 Exporter 可以是通用的、可配置的工具,也可以是为特定 eBPF 监控任务量身定制的专用程序。
4.4. 常见的 eBPF Exporter 方法与工具
目前,将 eBPF 数据暴露给 Prometheus 主要有以下几种途径:
-
通用可配置 Exporter:
cloudflare/ebpf_exporter
: 这是一个广受欢迎的 Exporter,它允许用户通过 YAML 配置文件定义如何从 eBPF Maps 中提取数据并将其映射为 Prometheus 指标。用户需要提供预编译的 eBPF 程序(.o
文件)和相应的 YAML 配置。其主要目的是导出那些无法通过标准 Exporter 获取的自定义内核级指标。它通常依赖 libbpf,并需要较高的权限(如CAP_BPF
和CAP_PERFMON
,或 root)来运行。配置过程涉及理解 eBPF Map 结构和 Prometheus 指标类型,具有一定的复杂性。digitalocean-labs/ebpf_exporter
: 这是 Cloudflare Exporter 的一个纯 Go 实现的替代品,但设计目标不同。它专注于导出内核自身提供的、关于已加载 eBPF 资源(程序、映射、链接)的元数据和统计信息,而不是自定义的应用或系统指标。它依赖于cilium/ebpf
Go 库,并且需要CAP_SYS_ADMIN
权限。其目的是监控 eBPF 子系统本身的状态。josecv/ebpf-userspace-exporter
: 这个 Exporter 专门针对用户空间探针(uprobes, USDT),设计为作为 sidecar 运行,解决了在容器化环境中难以对其他容器内进程进行用户空间探测的问题。它依赖 bcc,并且目前仍处于早期开发阶段,存在一些局限性。
-
使用库自定义 Exporter: 开发者可以使用 eBPF 相关的库,如
cilium/ebpf
(Go)、libbpf (C/C++) 或 bcc (Python/Lua),来编写完全自定义的 Exporter。这种方法提供了最大的灵活性,可以实现高度定制化的数据收集和处理逻辑,但需要投入相应的开发工作。许多开源项目和内部工具都采用了这种方式。 -
集成解决方案: 一些大型项目已经将 eBPF 数据导出到 Prometheus 作为其核心功能的一部分。例如:
- Cilium/Hubble: Cilium 是一个基于 eBPF 的 Kubernetes 网络和安全解决方案,其内置的 Hubble 组件可以直接暴露丰富的网络流、策略和性能指标给 Prometheus。
- Falco: Falco 是一个运行时安全检测工具,较新版本可以直接通过其内置的 Web 服务器暴露内部运行状况和规则触发相关的 Prometheus 指标。
- 其他工具: 如 Grafana Beyla、Pixie 等也利用 eBPF 进行自动插桩,并将收集到的指标(可能包括 Prometheus 格式)导出到相应的后端。
4.5. 数据流示例
一个典型的 eBPF 到 Prometheus 的数据流如下:
- 内核中发生特定事件(如网络数据包到达、系统调用被触发)。
- 该事件触发已加载的 eBPF 程序执行。
- eBPF 程序处理事件,可能会更新 eBPF Map 中的计数器或状态,或将事件详情推送到 Ring/Perf Buffer。
- 运行在用户空间的 Exporter 进程定期读取 Map 中的数据或从 Buffer 中拉取事件。
- Exporter 对读取到的数据进行聚合(如统计特定事件发生次数)、转换(如计算延迟分布)并格式化为 Prometheus 指标(如 Counter, Gauge, Histogram)。
- Exporter 通过其内置的 HTTP 服务器在
/metrics
端点暴露这些指标。 - Prometheus Server 根据其配置,定期向 Exporter 的
/metrics
端点发起 HTTP GET 请求(抓取)。 - Prometheus Server 将抓取到的指标样本连同时间戳存储到其本地 TSDB 中,之后便可通过 PromQL 进行查询和分析。
eBPF Exporter 不仅仅是一个简单的数据管道,它扮演着关键的抽象层角色。它负责将来自内核的、通常是低级别的、基于事件的原始数据,转换为 Prometheus 所期望的、基于时间序列的、结构化的指标模型。Exporter 的设计和实现质量直接影响到监控的性能、可用性以及最终数据的保真度。如何在 Exporter 中进行聚合(例如,将离散事件聚合成计数器)、如何表示 Map 中的状态(例如,将其转换为 Gauge)、如何从原始延迟数据构建 Histogram——这些转换逻辑,无论是通过 YAML 配置还是硬编码在 Exporter 中,都决定了最终在 Prometheus 中能够获得什么样的洞察力。一个设计不佳的 Exporter 可能会丢失重要信息、引入不必要的性能开销,或者产生难以管理的高基数指标。因此,选择或开发合适的 Exporter 并正确配置它,与编写高效的 eBPF 程序本身同等重要。
虽然 eBPF 技术能够减少甚至消除对应用程序代码进行手动插桩的需求,从而简化某些方面的部署,但在将其与 Prometheus 集成时,复杂性往往会转移到 eBPF 程序本身以及 Exporter 的配置上。用户现在需要具备编写或选择合适的 eBPF 程序的能力(通常使用 C 语言或 bpftrace 等 DSL),并且需要深入理解 Exporter 的配置方式(例如 ebpf_exporter
的 YAML 文件)。这包括正确解析 eBPF Map 的数据结构、定义恰当的 Prometheus 指标类型(Counter, Gauge, Histogram)、管理标签以提供上下文,以及可能需要处理数据聚合。这要求用户同时掌握 eBPF(包括 Map 布局、数据类型、潜在的内存对齐问题)和 Prometheus(指标类型、标签最佳实践)的知识。这种技能组合与使用标准库进行应用插桩相比,可能更加复杂和专业化。
5. 集成的协同优势
将 eBPF 的深度内核洞察力与 Prometheus 成熟的指标监控框架相结合,可以带来一系列显著的优势:
5.1. 前所未有的系统可见性
这种集成能够将 eBPF 提供的内核级细粒度信息(如系统调用、网络数据包细节、调度器事件)与 Prometheus 强大的标签模型所提供的应用程序和基础设施上下文(如 Pod 名称、命名空间、服务标识)相结合。这使得实现真正的全栈可观测性成为可能,能够将底层系统事件与高层服务行为关联起来进行分析。例如,可以将在 eBPF 中观察到的网络延迟峰值与 Prometheus 中记录的特定 Pod 部署事件或资源饱和度指标进行关联分析。
5.2. 低开销、高性能的监控
eBPF 程序直接在内核中执行,并受益于 JIT 编译,因此其数据收集过程相比传统的用户空间代理或内核模块具有显著的性能优势和更低的系统开销。它减少了内核态与用户态之间的上下文切换以及数据拷贝的开销。这使得收集那些对于传统方法而言成本过高的细粒度指标成为可能。
5.3. 细粒度指标的收集
eBPF 能够访问到标准 Exporter 通常无法触及的数据点。例如,可以直接测量内核函数或用户空间函数的执行延迟、获取详细的 TCP 重传统计信息、精确计量每个进程或 cgroup 的资源消耗等。用户可以根据具体需求,利用 eBPF 创建高度定制化的指标,满足特定的监控或诊断需求。
5.4. 先进的网络流量分析
集成方案可以超越传统网络接口计数器(如 Node Exporter 提供)的限制,提供基于流的网络可见性,并能关联到具体的进程或容器。可以直接在内核层面监控 L3/L4 甚至 L7(如 HTTP, gRPC, DNS)的服务间或 Pod 间的流量模式。能够高精度地测量网络延迟、丢包、重传等关键性能指标。更重要的是,可以将丰富的上下文信息(如 Pod 名称、命名空间)作为标签附加到 Prometheus 指标中,极大地增强了网络指标的可分析性。
5.5. 增强的安全事件检测与审计
eBPF 允许在事件发生的源头——内核——以高保真度监控与安全相关的活动。例如,可以实现文件完整性监控(监控敏感文件的读写执行)、进程执行追踪、系统调用审计(检测策略违规或可疑调用)、网络异常检测(如连接到恶意 IP、端口扫描)等。这些检测到的事件或聚合后的指标可以导出到 Prometheus 中,用于关联分析、触发告警(通过 Alertmanager),以及进行长期的安全审计和态势感知。
这种集成,特别是通过像 ebpf_exporter
这样的工具,实际上降低了利用 eBPF 强大能力的门槛。它使得那些不具备深厚内核专业知识的团队也能够将内核级别的洞察力整合到他们现有的、熟悉的 Prometheus 和 Grafana 监控体系中。传统上,获取深度内核信息需要编写复杂且有风险的内核模块,或者使用像 SystemTap 这样复杂的追踪工具。Prometheus 作为广泛采用且易于理解的监控平台,与 eBPF Exporter 结合,提供了一个桥梁。用户可以通过标准的 Prometheus 指标和 PromQL 查询来消费 eBPF 数据。虽然配置 Exporter 仍需一定的努力(见 4.2 复杂性转移),但这通常比开发内核模块要容易得多。像 Cilium/Hubble 这样的集成解决方案进一步抽象了底层的复杂性,提供了与 Prometheus 集成的、预打包的 eBPF 监控能力。这使得内核级数据对更广泛的 DevOps 和 SRE 团队来说触手可及。
然而,这种强大的组合也带来了一个潜在的挑战。eBPF 收集细粒度数据的能力(优势 5.3)与 Prometheus 丰富的标签系统(优势 5.1)相结合,极易导致指标基数的爆炸式增长。这会显著增加 Prometheus 的资源消耗(内存、CPU、存储),并可能抬高运营成本,尤其是在使用托管 Prometheus 服务或在云环境中运行时。eBPF 可以生成非常精细的指标(例如,每个连接的延迟、每次系统调用的计数)。Prometheus 鼓励使用标签来添加上下文(例如,Pod、命名空间、服务)。将这两者结合(例如,记录每个连接的延迟,并用源/目标 Pod 作为标签)会产生大量唯一的时间序列。在大型动态系统(如 Kubernetes)中,时间序列的数量可能达到数百万甚至数十亿,这会给 Prometheus 带来巨大压力,导致内存耗尽(OOMKills)、存储成本增加,并拖慢查询速度。因此,在享受 eBPF 带来的深度可见性的同时,必须进行仔细的规划和基数管理(见挑战 7.3)。
6. 关键用例与场景
eBPF 与 Prometheus 的结合在多个实际场景中展现出巨大价值:
6.1. 深度 Kubernetes 集群监控
标准的 Kubernetes 监控(如 Kubelet、cAdvisor 指标)提供了基础信息,但 eBPF+Prometheus 可以提供更深层次的洞察:
- Pod 间网络通信: 监控 Pod 之间网络连接的延迟、吞吐量、错误、丢包情况,并能结合 Cilium 等工具验证网络策略的执行情况。一个具体的例子是 Polar Signals 公司使用 eBPF 监控并优化 Kubernetes 集群中的跨可用区网络流量成本。
- 细粒度资源使用: 比标准工具更精确地追踪容器和 Pod 的 CPU、内存、磁盘 I/O 等资源消耗。
- 系统组件交互: 观察工作负载与 Kubernetes 控制平面组件或节点上其他系统服务的交互情况。
- 相关工具: Cilium/Hubble、使用支持 Kubernetes 感知的 eBPF 程序的通用 Exporter。
6.2. 应用程序性能诊断 (APD)
将 eBPF 的底层观察能力与 Prometheus 的指标体系结合,可以有效地诊断应用程序性能问题:
- 请求追踪: 通过监控相关的系统调用(如
read
,write
,sendmsg
,recvmsg
)或利用 uprobes 监控用户空间函数调用,来追踪请求在系统中的处理路径。 - 函数延迟测量: 直接在内核或用户空间测量关键函数的执行耗时,生成延迟指标或直方图。
- 性能剖析与火焰图: 利用 eBPF 进行 CPU 或 Off-CPU 性能剖析,并将结果(例如通过 Pyroscope/Parca)导出为 Prometheus 指标或生成火焰图。
- 底层事件关联: 将应用程序行为(如响应变慢)与 eBPF 可见的底层系统事件(如 TCP 重传、上下文切换、缺页中断)进行关联分析。
- 相关工具: 使用自定义 eBPF 程序的
ebpf_exporter
、bpftrace(可能通过 PCP 集成)、Pixie/New Relic、Grafana Beyla、Pyroscope/Parca。
6.3. 系统安全审计与运行时威胁检测
eBPF 能够在内核层面可靠地捕获安全相关事件,结合 Prometheus 进行存储和告警:
- 文件完整性与访问监控: 监控对敏感文件或关键配置的读、写、执行操作,检测未授权访问或篡改。
- 系统调用审计: 记录和分析系统调用序列,检测是否符合安全策略,识别可疑或恶意的系统调用模式。
- 网络异常检测: 识别异常网络活动,如连接到已知的恶意 IP 地址、端口扫描行为、非预期的出站连接等。
- 进程与权限监控: 追踪进程的创建和执行,检测权限提升尝试、容器逃逸行为等。
- 相关工具: Falco、Tetragon、Tracee、使用安全相关 eBPF 程序的自定义 Exporter。
6.4. 网络流量深度分析
利用 eBPF 在网络栈中的挂载点,可以实现比传统工具更深入的网络分析:
- 上下文丰富的流日志: 生成包含进程、容器、服务等上下文信息的网络流记录,并可导出为指标。
- DNS 监控: 捕获和分析 DNS 查询和响应,监控解析延迟和错误。
- TCP 连接分析: 监控 TCP 连接的建立、关闭过程,分析错误、重传、往返时间 (RTT) 等性能指标。
- L7 协议可见性: 解析 HTTP、gRPC、Kafka 等应用层协议,获取请求速率、错误率、延迟等指标。
- 相关工具: Cilium/Hubble、使用网络分析 eBPF 程序的
ebpf_exporter
、kyanos、pwru。
选择哪种集成方法(通用 Exporter 还是像 Cilium/Falco 这样的集成解决方案)在很大程度上取决于主要的应用场景。对于 Kubernetes 网络和安全监控,集成工具通常是更好的选择,因为它们提供了针对该领域的深度集成和相关抽象。例如,Cilium 专为 Kubernetes 网络和安全而设计,提供了丰富的开箱即用功能和指标。Falco 则专注于运行时安全检测。这些工具为其核心领域提供了精心策划的指标和策略。相比之下,通用的 Exporter 如 ebpf_exporter
提供了极大的灵活性,但需要用户自己定义 eBPF 程序和指标映射。这使得它们更适合那些集成工具未覆盖的定制化需求,例如特定的应用程序性能分析或特殊的合规性审计。因此,选择过程是在预置功能的便利性与定制化的灵活性之间进行权衡。
7. 挑战与考量因素
尽管 eBPF 与 Prometheus 的结合带来了诸多优势,但在实际部署和应用中也面临一些挑战和需要仔细考虑的因素:
7.1. eBPF 程序开发与维护的复杂性
- 技能要求: 编写 eBPF 程序通常需要 C 语言编程能力,并且需要对 Linux 内核的某些内部机制有所了解。虽然存在一些高级语言抽象(如 bpftrace DSL、bcc 的 Python/Lua 绑定),但底层复杂性依然存在。
- 验证器限制: eBPF 验证器的严格检查(如禁止无限循环、限制内存访问)虽然保证了安全,但也给程序设计带来了挑战,需要开发者适应其约束。
- 可移植性: 确保 eBPF 程序在不同内核版本和配置上都能正确运行是一个挑战。BPF CO-RE 技术旨在解决这个问题,但并非万能,有时仍需处理兼容性问题或依赖 BTF 信息。
- 调试困难: 调试在内核中运行的 eBPF 程序比调试用户空间程序更加困难。
7.2. 潜在的性能开销
- 运行时影响: 虽然 eBPF 通常被认为是低开销的,但编写不当或过于复杂的 eBPF 程序,尤其是在高频事件触发点上执行的程序,仍然可能对系统性能产生负面影响。
- 加载与编译开销: 加载 eBPF 程序时,验证器需要进行静态分析,JIT 编译器也需要消耗 CPU 资源进行编译。
- 特定功能开销: 启用某些内核功能,如 BPF 程序统计信息(记录运行次数和耗时),会给所有加载的 BPF 程序带来额外的运行时开销。
7.3. Prometheus 的可扩展性:应对高基数数据
- 基数爆炸风险: eBPF 提供的细粒度数据(见优势 5.3)结合 Prometheus 的标签维度(见优势 5.1),极易产生海量的唯一时间序列,即高基数问题 [见 Insight 5.2]。
- 资源压力: 高基数会急剧增加 Prometheus Server 的内存消耗(可能导致 OOMKilled)、CPU 使用率和存储需求。
- 查询性能下降: 处理大量时间序列会显著降低 PromQL 查询的响应速度。
- 管理策略: 成功扩展的关键在于积极管理基数。这需要仔细设计指标和标签(避免使用变化频繁或唯一性过高的值作为标签,如用户 ID、请求 ID)、在 eBPF 程序内部、Exporter 或 Prometheus 规则层面进行预聚合,或者有选择地丢弃低价值的标签或指标。使用托管 Prometheus 服务可能提供更好的可扩展性,但通常伴随着基于活跃序列数或数据量的成本增加。
7.4. Exporter 的可靠性、维护与配置
- 运维负担: eBPF Exporter 是部署架构中的一个额外组件,需要进行部署、监控、更新和维护。
- 配置复杂性: 通用 Exporter 的配置(如
ebpf_exporter
的 YAML)可能相当复杂,需要精确映射 eBPF 数据结构到 Prometheus 指标。 - 权限要求: Exporter 通常需要较高的系统权限(如
CAP_SYS_ADMIN
,CAP_BPF
,CAP_PERFMON
)才能加载 eBPF 程序和访问内核数据。 - 性能匹配: 需要确保 Exporter 的处理能力能够跟上 eBPF 程序产生数据的速度,避免成为瓶颈或丢失数据。
- 成熟度与支持: 并非所有可用的 Exporter 都达到了生产环境的要求,一些可能是个人项目或缺乏持续维护和支持。
7.5. 内核版本依赖与兼容性
- 功能依赖: eBPF 的许多高级功能(如某些 Map 类型、Helper 函数、程序类型)都依赖于较新的 Linux 内核版本。在较旧的内核上,可用的 eBPF 功能会受到限制。
- 内核配置: 运行 eBPF 程序通常需要内核编译时启用了特定的配置选项。
- 可移植性挑战: 即使有 CO-RE/BTF,有时仍可能需要目标系统提供内核头文件或外部 BTF 文件才能成功加载程序。
- 平台限制: eBPF 目前主要是一项 Linux 技术。虽然微软等公司正在努力将其引入 Windows,但在其他操作系统上的支持仍然有限或处于早期阶段。
虽然 eBPF 因其在内核中运行而减少了传统监控代理的部分运行时开销,但实现基于 eBPF 的可观测性并非没有成本。所谓的“可观测性税”并没有消失,而是发生了转移。成本从运行时的 CPU 和内存消耗,转向了 eBPF 程序的开发复杂性(需要 C 语言和内核知识、应对验证器限制)、配置管理的复杂性(管理 Exporter、处理 CO-RE/BTF 依赖),以及潜在的后端系统(如 Prometheus)的可扩展性挑战。因此,虽然被监控应用的直接性能“税”可能降低了,但构建和维护整个可观测性系统所需的总体工作量、技能要求以及潜在的基础设施成本可能会增加或改变性质。
在 eBPF 与 Prometheus 集成的所有挑战中,高基数问题可以说是最突出和最具影响力的实际障碍。eBPF 的深度洞察能力与 Prometheus 的多维标签模型相结合,天然地容易导致时间序列数量的激增 [见 Insight 5.2]。许多实践报告和文档都明确指出了 Prometheus 在处理高基数时的困难。解决方案往往需要在数据粒度、上下文信息和系统资源消耗之间做出权衡:要么在早期聚合数据(牺牲细节),要么丢弃标签(牺牲上下文),要么投入大量资源来扩展 Prometheus(增加成本和复杂性)。这个特定的交互点是使用这两种技术组合在生产环境中规模化应用时最常遇到、也是影响最大的技术难题。能否有效解决高基数问题,往往决定了这种集成方案能否在大型系统中成功落地。
8. 生态系统工具:利用 eBPF 与 Prometheus
围绕 eBPF 与 Prometheus 的集成,已经涌现出一个不断发展的工具生态系统,涵盖了从底层库到集成解决方案的各个层面。以下是一些关键的工具和项目:
8.1. Cilium & Hubble
- 核心关注点: Kubernetes 环境下的网络连接、安全策略执行和可观测性。
- eBPF 应用: Cilium 的核心数据平面完全基于 eBPF 实现,用于高效的路由、负载均衡、网络策略实施以及深度的数据包可见性。
- Prometheus 集成: Cilium Agent、Operator 以及可选的 Envoy 代理都可以暴露自身的运行指标。更重要的是,其内置的可观测性组件 Hubble 可以将丰富的网络流信息(包括源/目标 Pod、命名空间、应用层协议信息如 HTTP/gRPC、网络策略判定结果、延迟、丢包等)导出为 Prometheus 指标。集成通常通过 Helm Chart 的参数(如
prometheus.enabled=true
,hubble.metrics.enabled=true
)启用,并需要配置 Prometheus 来抓取 Cilium 和 Hubble 暴露的/metrics
端点。
8.2. Falco
- 核心关注点: 云原生环境下的运行时安全,旨在检测异常行为和潜在的安全威胁。
- eBPF 应用: Falco 使用 eBPF(以及内核模块或现代 eBPF 探针)作为其主要的事件源之一,用于捕获系统调用等内核事件。
- Prometheus 集成: 从 0.38 版本开始,Falco 自身可以直接通过其内置的 Web 服务器暴露 Prometheus 指标,无需额外的 Exporter。这需要启用相关配置(
metrics.enabled: true
和webserver.prometheus_metrics_enabled: true
)。在此之前,需要使用一个名为falco-exporter
的独立组件(现已弃用),该组件通过 gRPC 从 Falco 读取事件并转换为指标。暴露的指标通常包括 Falco 自身的运行状况(如事件处理速率、资源消耗)以及触发的安全规则统计信息(按规则、优先级等维度)。
8.3. bpftrace
- 核心关注点: 提供一种高级追踪语言,用于编写和执行临时的 eBPF 程序,方便进行系统探索和性能分析。
- eBPF 应用: 作为 eBPF 程序的用户友好前端,简化了追踪脚本的编写和运行。
- Prometheus 集成: bpftrace 本身没有内置的 Prometheus Exporter。集成通常通过间接方式实现:
- 编写自定义的 Exporter,该 Exporter 负责执行 bpftrace 脚本,解析其输出,并将结果转换为 Prometheus 指标。
- 利用像 PCP (Performance Co-Pilot) 这样的工具集。PCP 包含一个 bpftrace PMDA(性能指标域代理),可以收集 bpftrace 脚本产生的数据,并通过
pmproxy
组件以 Prometheus 格式暴露出来。
8.4. 其他相关项目
- Pixie (已被 New Relic 收购): 一个 Kubernetes 可观测性平台,广泛使用 eBPF 进行自动插桩,收集应用指标和分布式追踪信息。它可能将其数据导出到 Prometheus 或提供自己的存储和查询后端。
- Grafana Beyla: Grafana Labs 推出的开源 eBPF 自动插桩工具,可以为多种语言(Go, C/C++, Rust, Python, Java 等)的应用自动生成符合 OpenTelemetry 和 Prometheus 格式的指标(如请求速率、延迟、错误率),无需修改应用代码。
- Polar Signals' kubezonnet: 一个开源项目,利用 eBPF(特别是 netfilter 钩子)来监控 Kubernetes 集群中的跨可用区(cross-zone)网络流量,并将结果以 Prometheus 指标和流日志的形式暴露出来,旨在帮助用户理解和优化云网络成本。
- OpenTelemetry eBPF Collector: OpenTelemetry 社区的一个项目,旨在利用 eBPF 进行网络数据收集,作为 OpenTelemetry Collector 的一部分。它通常包含一个
kernel-collector
组件用于捕获数据,和一个reducer
组件用于处理数据并将其转换为 OTel 格式,之后可以导出到包括 Prometheus 在内的各种后端。 - Pyroscope / Parca: 专注于持续性能剖析的工具,它们使用 eBPF 来高效地收集堆栈跟踪等剖析数据。虽然主要目标是剖析数据本身,但它们也可能暴露一些关于剖析过程或结果摘要的 Prometheus 指标。
- PCP (Performance Co-Pilot): 一个历史悠久且功能强大的系统性能分析框架。它拥有用于多种数据源的代理(PMDA),包括基于 bcc 和 bpftrace 的 eBPF 程序。PCP 可以通过
pmproxy
组件将其收集的所有指标(包括来自 eBPF 的)以 Prometheus 格式导出。
下表总结了部分关键的 eBPF 生态系统工具及其与 Prometheus 的集成方式:
表 1: 关键 eBPF 生态系统工具与 Prometheus 集成概览
工具名称 | 主要关注点 | eBPF 用途 | Prometheus 集成方法 | 关键指标示例 |
Cilium/Hubble | K8s 网络、安全、可观测性 | 核心数据平面、流监控、策略执行 | 内置 Exporter (通过 Helm 启用) | 网络流 (L3/L4/L7)、延迟、丢包、策略执行、DNS 查询、HTTP/gRPC 指标 |
Falco | 云原生运行时安全 | 系统调用/事件捕获 | 内置 Exporter (v0.38+,通过配置启用) | Falco 运行状况、事件速率、规则触发计数 (按优先级/规则) |
bpftrace | 高级追踪语言、临时分析 | 执行用户定义的追踪脚本 | 通过 PCP+pmproxy 或自定义 Exporter | 用户自定义指标 (取决于 bpftrace 脚本) |
Grafana Beyla | 应用自动插桩 (多语言) | 捕获应用级事件 (网络、系统调用) | 内置 Exporter (Prometheus & OTel 格式) | RED 指标 (请求速率、错误率、持续时间)、进程信息 |
kubezonnet | K8s 跨可用区网络流量监控 | Netfilter 钩子追踪网络包 | 内置 Exporter | Pod 间跨区流量总量、流日志 |
OTel eBPF Collector | 网络数据收集 (集成 OTel) | 捕获网络数据、进程信息 | 通过 OTel Collector 导出 (支持 Prometheus 格式) | 网络连接信息、进程指标 (作为 OTel 数据流的一部分) |
cloudflare/ebpf_exporter | 通用、可配置的自定义 eBPF 指标导出 | 执行用户提供的 eBPF 程序,读取 Maps | 自身即为 Exporter (需 YAML 配置和 eBPF 程序) | 用户自定义指标 (基于 Map 内容,如 IO 延迟直方图) |
digitalocean-labs/ebpf_exporter | 监控 eBPF 子系统自身 | 读取内核提供的 eBPF 资源信息 | 自身即为 Exporter | 已加载的 eBPF 程序/Map/Link 的元数据和统计信息 |
注:此表仅列出部分代表性工具,生态系统仍在快速发展中。
从上表可以看出,eBPF 与 Prometheus 的集成成熟度存在明显的梯度。像 Cilium 这样的项目,其核心功能就深度依赖 eBPF,并提供了成熟、文档完善的 Prometheus 集成方案。Falco 也已从依赖外部 Exporter 发展到内置支持。而像 bpftrace 这样的通用追踪工具,由于其目的更侧重于即时分析而非持续监控,通常需要借助 PCP 或自定义封装来实现与 Prometheus 的对接。通用的 Exporter 则将集成的复杂性主要交给了用户。这种从紧密集成、领域特定的解决方案到松散耦合、通用工具的谱系,反映了 eBPF 可观测性生态系统仍在不断发展和完善标准化的集成模式。
9. 结论与比较视角
9.1. 价值主张总结
eBPF 与 Prometheus 的结合为现代系统监控带来了革命性的进步。其核心价值在于:通过 eBPF 的低开销内核探测能力,获取前所未有的深度系统可见性,涵盖从底层内核事件到应用层行为的广泛范围;利用 Prometheus 成熟且广泛应用的指标收集、存储、查询和告警框架,将这些深度洞察整合到主流的云原生监控体系中。这种协同作用显著增强了网络分析能力、提升了安全审计的深度和实时性,并为性能诊断提供了更细粒度的依据。
9.2. 应对挑战
然而,要充分发挥这种组合的潜力,必须正视并妥善处理相关的挑战。这包括 eBPF 程序开发的固有复杂性、对内核知识的要求、潜在的性能影响、Exporter 的配置和维护负担、内核版本兼容性问题,以及尤为突出的 Prometheus 高基数管理难题。成功的部署和应用,离不开周密的规划、专业的技术知识以及对系统资源的合理评估。
9.3. 与替代方案的简要比较
将 eBPF+Prometheus 的方案与其他监控技术进行比较,可以更清晰地认识其独特性:
- vs. 传统内核模块 + 自定义 Exporter: eBPF 提供了更好的安全保障(通过验证器)和更便捷的部署方式(无需重启或重新编译内核),但其编程模型比内核模块有更多限制。内核模块灵活性更高,但风险也更大。
- vs. 用户空间代理/Sidecar (如 APM, Node Exporter): eBPF 通常具有更低的运行时开销(减少上下文切换和数据拷贝,直接访问内核数据)和更深入的内核事件可见性。用户空间代理可能更容易获得丰富的应用程序特定上下文(取决于插桩方式),并且通常具有更广泛的操作系统兼容性。OpenTelemetry 的许多组件在用户空间运行。
- vs. SNMP/NetFlow: 对于网络监控,基于 eBPF 的解决方案(尤其是通过 Cilium/Hubble 等工具)可以提供远比传统 SNMP 计数器或 NetFlow/sFlow 记录更丰富的上下文信息(如 Pod 名称、服务标签、L7 协议细节)和更低的延迟。
下表对这些方法进行了简要对比:
表 2: eBPF+Prometheus 与替代监控方法比较
方法 | 关键技术 | 可见性深度 | 性能开销 | 安全性 | 易用性/部署复杂度 | 主要用例示例 |
eBPF + Prometheus | eBPF, Prometheus Exporter | 非常深 (内核+应用关联) | 低 | 高 (验证器) | 中到高 (eBPF+Exporter 配置) | K8s 深度网络/安全监控, 细粒度 APD |
内核模块 + 自定义 Exporter | Kernel Module, Custom Code | 非常深 (内核) | 可变 (取决于实现) | 低 | 高 (内核开发, 风险) | 需要最大内核灵活性的场景 |
用户空间代理 (APM/Node Exporter) | Agent Library/Binary | 中到深 (应用/OS 指标) | 中到高 | 中 | 低到中 (标准部署) | 应用性能监控, 主机基础监控 |
SNMP/NetFlow | SNMP Protocol, Flow Export | 浅 (网络接口/流元数据) | 低 | 高 | 中 (设备配置) | 传统网络设备监控, 流量统计 |
9.4. 未来展望
eBPF 技术正处于高速发展期,其应用范围和深度预计将持续扩大。eBPF 基金会的成立、主流云厂商和科技公司的投入、以及向 Windows 等其他操作系统的扩展尝试,都预示着其广阔的前景。同时,旨在简化 eBPF 开发和使用的工具与抽象(如 CO-RE、高级语言绑定、集成平台)也在不断涌现。可以预见,未来 eBPF 数据源与监控后端(包括 Prometheus)之间的集成模式将更加成熟和标准化,可能会超越简单的 Exporter 模式,实现更紧密的耦合和更智能的数据处理。
eBPF 与 Prometheus 的结合,标志着向“内核感知”可观测性的重要转变。在这种新范式中,理解底层内核的行为不再是少数内核开发者的专利,而是成为有效监控复杂分布式应用(尤其是在 Kubernetes 等容器化环境中)不可或缺的一部分。传统监控往往将内核视为一个黑盒子,关注点主要在操作系统层面的聚合指标(如 Node Exporter)或应用内部的追踪(APM)。然而,Kubernetes 和微服务架构引入了大量在网络和进程层面发生的复杂交互。eBPF 恰好提供了深入观察这些由内核介导的交互(网络、系统调用等)的必要手段。Prometheus 则提供了大规模消费和分析这些数据的平台。像 Cilium 这样的工具明确地利用了这种结合来解决 Kubernetes 的挑战。这表明,由 eBPF 赋能、由 Prometheus 消费的深度内核洞察力,正从利基技术走向现代基础设施可观测性的核心。
10. 参考文献
项目与组织链接:
- eBPF 官方网站: eBPF - Introduction, Tutorials & Community Resources
- eBPF 官方文档: eBPF Docs
- Prometheus 官方网站: Prometheus - Monitoring system & time series database
- Prometheus 官方文档: Overview | Prometheus
- Cilium 项目: Cilium - Cloud Native, eBPF-based Networking, Observability, and Security (相关 GitHub: https://github.com/cilium/cilium)
- Falco 项目: Falco (相关 GitHub: https://github.com/falcosecurity/falco)
cloudflare/ebpf_exporter
GitHub: https://github.com/cloudflare/ebpf_exporterdigitalocean-labs/ebpf_exporter
GitHub: https://github.com/digitalocean-labs/ebpf_exporterjosecv/ebpf-userspace-exporter
Go Package: ebpf-userspace-exporter command - github.com/josecv/ebpf-userspace-exporter - Go Packagescilium/ebpf
Go Library: ebpf-go Documentation