eBPF + OpenTelemetry 到底是怎么实现零侵入可观测的?
📖 摘要:2026 年可观测性已从"埋点三支柱"演进到"语义可观测 + 零侵入采集"。本文拆解 eBPF 如何在不改一行业务代码的前提下,从内核捕获网络与系统调用,再通过 OpenTelemetry 的 OTLP 协议统一成 traces/metrics/logs,并以一个 K8s 微服务为例给出可运行配置。读完你将理解零侵入可观测的底层机制与落地路径。
🏷️ 关键词:eBPF,OpenTelemetry,可观测性,零侵入,OTLP
目录
- 一、背景与痛点
- 二、核心原理
- 2.1 传统埋点的代价
- 2.2 eBPF 在内核里"看"世界
- 2.3 OpenTelemetry 统一遥测
- 三、实战落地
- 3.1 用 Cilium 拿 L7 网络可见性
- 3.2 OTel Collector 收口
- 3.3 一条 trace 长什么样
- 四、踩坑与优化
- 五、总结
一、背景与痛点
某团队的订单服务(下称 order_service)跑在 K8s 上,偶尔 p99 延迟飙到 3 秒,但业务代码里没有任何埋点,谁也讲不清延迟发生在哪一跳。传统解法要改代码接 SDK,可 order_service 是第三方依赖,动不了。这就是 2026 年"零侵入可观测"要解决的问题:不改业务代码,也要看清调用链。
二、核心原理
2.1 传统埋点的代价
SDK 埋点的链路是:业务代码 → OTel SDK → Collector → 后端。它信息丰富、可控,代价是要改源码,且要在每个服务、每个框架里做对。对 legacy 服务或闭源依赖,这条路走不通。
2.2 eBPF 在内核里"看"世界
eBPF 是一段跑在 Linux 内核的沙箱程序,能挂载到系统调用、网络协议栈的钩子上,观测进程做了什么,而不关心它为什么做。例如捕获 TCP 建连、HTTP 请求行、gRPC 方法名——全程零业务代码改动。
// 简化的 eBPF 钩子:在 TCP 发送时记录目标端口(示意)
SEC("kprobe/tcp_sendmsg")
int trace_tcp_send(struct pt_regs *ctx) {
bpf_trace_printk("tcp send event\\\\n"); // 真实场景写入 BPF map
return 0;
}
工具如 Cilium、Pixie、Parca 用 eBPF 给出 per-pod 网络 I/O、TCP 重传率、连接池效率——对 GPU 节点常被超卖的 AI 负载尤其有价值。
2.3 OpenTelemetry 统一遥测
eBPF 解决"采得到",OpenTelemetry(OTel)解决"采得统一"。它定义了一套** vendor-neutral 的数据模型 + OTLP 线协议**,把 traces/metrics/logs 汇到同一个 Collector,再路由到任意后端。
# OTel Collector:接收 eBPF 与 SDK 两路信号,统一导出
receivers:
otlp:
protocols: { grpc: {}, http: {} }
exporters:
prometheus: { endpoint: "0.0.0.0:9090" }
loki: { endpoint: "http://loki:3100/loki/api/v1/push" }
service:
pipelines:
traces: { receivers: [otlp], exporters: [tempo] }
metrics: { receivers: [otlp], exporters: [prometheus] }
三、实战落地
3.1 用 Cilium 拿 L7 网络可见性
把 Cilium 设为 CNI 后,它用 eBPF 在节点上透明捕获 HTTP/gRPC,无需改 order_service 一行业务代码。
# 安装 Cilium(启用 L7 可见性)
helm install cilium cilium/cilium –version 1.16 \\
–set kubeProxyReplacement=true \\
–set hubble.relay.enabled=true
3.2 OTel Collector 收口
SDK 埋点的服务走 OTLP 上报,eBPF(如 Cilium Hubble → OTel 桥)也转成 OTLP,两路在 Collector 汇合。65% 的用户已在生产跑 10+ 个 Collector。
3.3 一条 trace 长什么样
端到端请求在 OTel 里是一个 span 树:
GET /checkout ── order_service (span A)
├── db_query (span B, child)
└── payment_api (span C, child, 跨进程)
eBPF 能补上 order_service 内部看不到的网络层 span(如到 payment_api 的 TCP 重传),SDK 则补上业务层语义。两者互补:SDK 看"为什么",eBPF 看"做了什么"。
四、踩坑与优化
- 坑一:eBPF 视角粗。 它看到系统调用与网络,看不到推理过程。对策是 SDK + eBPF 双轨,别指望单一方案。
- 坑二:采样失控账单爆炸。 2026 年有厂商按 trace 计费(约 $10/百万 trace),高扇出系统 span 数爆炸。对策是尾部采样(tail-based sampling),只保留异常链路全量。
- 坑三:内核版本兼容。 用 eBPF CO-RE(Compile Once, Run Everywhere)编译一次跨内核运行,避开版本碎片化。
- 坑四:PII 泄漏。 遥测可能含用户数据,按 NIS2/DORA 做多区域过滤与保留策略。
五、总结
零侵入可观测的本质是把观测点从"业务代码里"移到"内核与协议层":eBPF 负责不改代码也能采,OTel 负责采来之后统一成一个可关联的真相。2026 年的建议很清晰——先标准化(OTel),再智能化(AI 分析);从 eBPF 起步,但架构上留好接 SDK 深度的口子。
觉得有用点个赞/收藏,评论区聊聊你家的可观测性栈。






