技术博客

阅读约 4 分钟

OpenTelemetry 社区太强大了,DataBuff 也可以吃上它的 eBPF 链路了

OpenTelemetry 的 OBI 用 DaemonSet + eBPF 旁路采 HTTP 链路,业务 Pod 不动;推到 DataBuff 即可在 UI 看服务、拓扑和 Trace。含 K8s 实测 YAML 与验收截图。

OpenTelemetry 社区把 eBPF 链路采集做成了 OBI(OpenTelemetry eBPF Instrumentation)。K8s 里在每个节点旁路跑一份 DaemonSet,用 eBPF 看本机服务之间的 HTTP 调用,拼成链路推出去;业务 Pod 维持原样。Docker 镜像一般是 otel/ebpf-instrument,项目地址:github.com/open-telemetry/opentelemetry-ebpf-instrumentation

链路推到哪看?DataBuff 是开源 APM / 可观测平台,在 UI 里看服务、拓扑和调用链。OBI 把采到的链路推到 DataBuff 就行。项目地址:github.com/databufflabs/databuff

一份 DaemonSet,每台主机各一个采集 Pod
ns obi · 业务 Pod 不改、不塞探针 · 采集 Pod 用 eBPF 看本机 HTTP → 推到 DataBuff

下面按步骤来。还没有 DataBuff 的先做第 1 步;后面改 YAML 时记清楚业务命名空间上报地址就行。

第 1 步 · 安装 DataBuff
curl -fsSL https://databuff.ai/databuff/ai-apm-k8s-install.sh | bash
kubectl -n databuff get pods

Pod 都 Running,UI 能打开就行。

第 2 步 · 确认业务节点内核能跑 eBPF

各业务节点上分别检查:

uname -r
ls /sys/kernel/btf/vmlinux

内核建议 5.8+,且第二条能列出文件。缺 BTF 的节点上,采集 Pod 会起不来或采不到。

第 3 步 · 镜像(能出网可跳过)

镜像用 otel/ebpf-instrument:latest(实测 latest 可用;生产请钉版本)。集群能出网可跳过;离线则先 pull 再传到各节点 load。

第 4 步 · apply DaemonSet

下面 YAML 一次 apply,改两处占位符:YOUR_APP_NAMESPACE → 业务命名空间;YOUR_DATABUFF_HOSTai-apm-ingest.databuff.svchostPID / privileged 是为了看见宿主机进程并挂 eBPF。

# 完整 YAML 见 github.com/databufflabs/databuff 文档或文末 OBI 示例
# 关键配置:
#   discovery.instrument.k8s_namespace: YOUR_APP_NAMESPACE
#   ebpf.context_propagation: headers
#   otel_traces_export.endpoint: http://YOUR_DATABUFF_HOST:4318
kubectl apply -f obi.yaml
kubectl -n obi get ds,pods -o wide

看输出:DESIRED / READY 等于节点数,每个 pod/obi-* Running。

DaemonSet obi 运行效果
图 2 · 实测 READY 5/5
第 5 步 · 日志确认盯上了业务进程
kubectl -n obi logs -l app=obi --tail=80 | grep -iE "instrumenting|process|error" | head -30

instrumenting process 即可。没有就查命名空间占位符和业务是否在跑。

第 6 步 · 打流量
for i in $(seq 1 80); do
  curl -sS -m 2 "http://业务地址/" >/dev/null || true
  sleep 0.2
done

打一两分钟,再进 DataBuff 看服务和链路。

第 7 步 · DataBuff 核对

打开应用性能 → 服务,搜应用名;再点开拓扑和链路详情。

服务列表
图 3 · 服务列表能搜到应用名
全局拓扑
图 4 · 拓扑有调用连线
链路列表
图 5 · 打流时间窗内有新链路
Trace 详情
图 6 · 瀑布图:methodA9 串到多服务 methodB9(含 DB)
eBPF 和 Agent,怎么选
方案更适合
eBPF + DaemonSet(本文)不想注入、不想重启;先看 HTTP 调用;多语言混部先铺一层
语言 Agent(如 javaagent)Dubbo、慢 SQL、方法栈;内核不够 5.8+/BTF

短板也要摆出来,别当银弹:

  • 不支持 Dubbo。OBI 主要吃 HTTP / gRPC 这类协议边界;Dubbo RPC 目前采不到,要看调用还得上语言 Agent。
  • 看不到方法栈、业务自定义 Span——它在节点外侧旁路观测,进不了你的代码细节。
  • 采集 Pod 必须 privileged;节点内核建议 5.8+,还要有 BTF。

这次先铺 OBI;Dubbo、方法栈这类缺口,再补 Agent。

OBI 大致怎么工作的

它不进业务代码。每个节点上的 DaemonSet 用 eBPF 盯住本机 HTTP,在用户态拼成 Span,再推到 DataBuff。和 javaagent 的差别也在这里:Agent 在进程里插桩;OBI 在节点边上旁路看,多语言一份 DaemonSet 就能铺一层。

多服务怎么串成一条链

靠上下文传递。YAML 已配 context_propagation: headers。业务不改代码;读和写都在节点外侧的 HTTP 报文上:

  • ① 读 Header · 看入站 — 请求进节点时扫 Traceparent:,有就挂上游 traceId/spanId,没有就新生成。
  • ② 本机关联 — 出站 HTTP 靠线程、socket 等线索对上刚才的入站。
  • ③ 写 Header · 写出站 — sockmap sk_msg 在请求行后面挤进本跳 Traceparent,下一跳入站再被读到。

HTTPS 改不了 HTTP 头,上游另有 TCP Option 路径;本文开的是 headers,对明文 HTTP 就是上面这套。