2026年7月18日 1 分钟阅读

OBI 实战:不改业务代码,用 eBPF 为遗留服务补齐 OpenTelemetry 链路

tinyash 0 条评论

给一个运行多年的服务补可观测性,最难的往往不是搭 Collector 或存储后端,而是改代码:服务语言杂、镜像来自第三方、依赖版本冻结,甚至团队没有重新构建镜像的窗口。结果是告警只能告诉你「慢了」,却很难解释请求经过了哪里、数据库和缓存是否参与了故障。

OpenTelemetry eBPF Instrumentation(简称 OBI)提供了另一条路径:它在 Linux 主机上通过 eBPF 观察用户态进程和网络协议,向 OpenTelemetry 生态输出遥测数据。对 HTTP、gRPC、MySQL、PostgreSQL、Redis 等常见协议,这意味着可以先获得一层语言无关的调用观测,再决定哪些关键路径值得回到应用内做 SDK 埋点。

这不是「eBPF 能替代所有埋点」的承诺。它更适合回答一个明确问题:在不能立即改代码时,怎样先为一组陌生或遗留服务建立可验证的请求视图?

先确定边界:OBI 能看见什么,不能替你猜什么

OBI 是 OpenTelemetry 项目的开发中(v0)组件,仓库明确提示:小版本之间可能出现破坏性变化。因此生产评估要固定具体 release tag,不能把 latest 当成稳定接口。本文以截至写作时的 v0.10.0 release 为例。

它的支持矩阵列出 Linux amd64arm64 发行物,要求 Linux 5.8+ 内核并暴露 BTF 信息;对带相应 eBPF backport 与 BTF 的 RHEL 系环境,文档列出了 4.18+ 的例外。运行时需要 root,或为已启用功能授予相应 Linux capabilities。

协议支持也有边界。例如 HTTP/1.x 标注了上下文传播支持;HTTP/2 和 gRPC 的网络层协议观测可用,但上下文传播并非同样完整。对于在 OBI 启动前就已建立的长连接,gRPC 方法名、SQL prepared statement 的查询文本等字段也可能缺失。把这些限制写进验收标准,比看到几条 span 后直接扩大部署更稳妥。

第一步:下载前先锁定版本并校验工件

OBI 的发布页同时提供二进制、SHA256SUMS、CycloneDX SBOM 与 Sigstore bundle。对需要进入生产环境的 agent,至少应把版本固定并做哈希校验;更严格的流程还可以按项目 README 中的 cosign verify-blob 示例验证签名。

export VERSION=0.10.0
export ARCH=amd64
export RELEASE_TAG="v${VERSION}"
export BASE_URL="https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/releases/download/${RELEASE_TAG}"

wget "${BASE_URL}/obi-${RELEASE_TAG}-linux-${ARCH}.tar.gz"
wget "${BASE_URL}/SHA256SUMS"
sha256sum -c SHA256SUMS --ignore-missing

tar -xzf "obi-${RELEASE_TAG}-linux-${ARCH}.tar.gz"
sudo cp obi /usr/local/bin/
obi --version

这里的 --ignore-missing 很重要:它让 sha256sum 只验证当前目录中实际下载的文件。若校验失败,不要以「网络偶发问题」为由继续执行;应重新确认版本、架构和下载地址来自同一个 release。OBI 的 standalone 文档还说明,发行包带有 k8s-cache、许可证和第三方 notice;从 v0.6.0 起 Java agent 已嵌入 obi,不需要另装 JAR。

第二步:用一个隔离实验验证“看到了请求”

官方 Docker 示例使用一个简单的 HTTPS 服务,并让 OBI 在 host PID namespace 中观察目标进程。下面命令将服务内部的 8443 映射到宿主机 18443,然后把捕获到的 trace 直接打印到 OBI 标准输出:

export VERSION=v0.9.0

docker run -p 18443:8443 --name goblog mariomac/goblog:dev

docker run --rm \
  -e OTEL_EBPF_OPEN_PORT=8443 \
  -e OTEL_EBPF_TRACE_PRINTER=text \
  --pid=host \
  --privileged \
  otel/ebpf-instrument:${VERSION}

访问 https://localhost:18443 并产生几次请求后,终端应出现包含状态码、方法、路径和耗时的 trace 输出。这个阶段只验证两件事:OBI 能否附着到目标工作负载,以及你关心的协议字段是否可见。验证通过后,再根据配置选项把 traces 和 metrics 导出到已有的 OpenTelemetry endpoint,或接入 Prometheus 抓取链路。

不要把 --privileged 原样复制到生产。官方文档把它定义为快速运行方式,并说明也可尝试使用 SYS_ADMIN capability;但不同容器环境中 capability 是否足够,需要以实际功能和安全文档为准。较好的上线顺序是:在单个非关键节点验证内核、BTF、协议字段和资源开销,再按最小权限原则收敛权限范围。

从“有数据”到“能排障”的三个实践

把 OBI 作为发现层,而不是唯一真相。 先用它识别高错误率或高延迟的服务边界,再为真正需要业务语义的流程补 SDK span。网络层能告诉你一次 PostgreSQL 调用慢,却不知道订单状态机为何走到了那条分支。

把启动时机纳入变更计划。 已有连接可能缺字段,因而部署后最好滚动重启目标服务或明确记录连接建立时间;否则不同实例的数据完整度不一致,容易误判为采集器故障。

将工件校验纳入平台流程。 OBI 本身具有高权限观察能力,恰恰更不该跳过其供应链校验。固定 tag、校验 checksum、保留 SBOM,能让一次“快速补观测”不会变成新的运行时风险。

OBI 的价值不在于消灭应用埋点,而在于给平台团队一个低侵入的起点:先建立跨语言、跨镜像的共同观察面,再把有限的改造预算投入最值得深挖的业务路径。

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。