eBPF 网络观测:不用改代码也能看到推理服务间的网络延迟

发布时间:2026/7/15 21:59:31
eBPF 网络观测:不用改代码也能看到推理服务间的网络延迟 eBPF 网络观测不用改代码也能看到推理服务间的网络延迟一、背景与问题AI 推理服务的架构正在向多服务协作演进请求先到 Gateway再调 Tokenizer 服务做预处理再调推理服务执行模型可能还调 Embedding 服务做辅助检索。这些服务间的 gRPC/HTTP 调用网络延迟是不可忽视的组成部分。传统方式要在每个服务里手动埋点才能测量服务间延迟。这意味着改代码、重新构建、重新部署、重新验证。对于已经在生产运行的服务这个流程的成本和风险都不低。更现实的情况是你接手了一个推理服务集群想了解服务间的网络延迟分布但服务代码不是你写的或者你没有权限改。eBPF 的价值就在这里它在内核层拦截网络事件TCP 连接、数据包收发不需要修改任何应用代码就能采集网络延迟数据。从内核角度看不管应用用的是 HTTP、gRPC 还是原始 TCP最终都是 socket 操作eBPF 都能拦截。二、eBPF 网络观测原理flowchart TB subgraph 应用层 G[Gateway Service] T[Tokenizer Service] I[Inference Service] end subgraph 内核层 E[eBPF Programs] E -- TC[TCP Connect Hook] E -- SR[Send/Recv Hook] E -- RT[Retransmit Hook] end TC -- M[Metrics: connect_latency_ms] SR -- M2[Metrics: rtt_ms] RT -- M3[Metrics: retransmit_count] M -- P[Prometheus Exporter] M2 -- P M3 -- P style E fill:#d32f2f,color:#fff style TC fill:#e53935,color:#fff style SR fill:#f44336,color:#fff style RT fill:#ef5350,color:#fffeBPF 网络观测的三层拦截点Hook 点拦截事件采集指标tcp_connectTCP SYN 发送→SYN-ACK 收到连接建立延迟tcp_sendmsg / tcp_recvmsg数据包发送/接收RTT往返延迟tcp_retransmit重传事件重传次数连接建立延迟反映服务端是否快速响应新连接gRPC 连接池是否健康。RTT 反映网络本身的延迟。重传次数反映网络质量丢包率。三个指标组合可以判断网络延迟问题出在哪连接建立慢说明服务端有问题RTT 高说明网络本身有问题重传多说明网络质量差。三、实现方案3.1 使用 Pixie 快速部署Pixie 是基于 eBPF 的 K8s 可观测平台开箱即用不需要自己写 eBPF 程序。部署步骤# 安装 Pixie CLI px install # 验证部署 px run demo # 查看推理服务间的网络延迟 px run px/network_flows --namespace aiPixie 自动采集所有 Pod 的 TCP 流量数据包括连接延迟、RTT、吞吐量。数据存储在 Pixie 的内存数据库中Vizier支持实时查询但保留时间有限通常几小时。长期存储需要导出到 Prometheus。3.2 使用 Parca 自定义 eBPF Program如果需要更细粒度的控制用 Parca 作为 eBPF metrics exporter// eBPF program: tcp_connect_latency SEC(kprobe/tcp_connect) int tcp_connect(struct pt_regs *ctx) { struct sock *sk (struct sock *)PT_REGS_PARM1(ctx); u64 ts bpf_ktime_get_ns(); // 记录连接发起时间 struct connect_event event {}; event.ts ts; event.sport sk-__sport; event.dport sk-__dport; bpf_map_update_elem(connect_start, sk, event, BPF_ANY); return 0; } SEC(kprobe/tcp_finish_connect) int tcp_finish(struct pt_regs *ctx) { struct sock *sk (struct sock *)PT_REGS_PARM1(ctx); u64 ts bpf_ktime_get_ns(); struct connect_event *start bpf_map_lookup_elem(connect_start, sk); if (!start) return 0; u64 latency_ns ts - start-ts; // 输出指标 struct metric_event m {}; m.latency_ns latency_ns; m.sport start-sport; m.dport start-dport; bpf_perf_event_output(ctx, metrics, BPF_F_CURRENT_CPU, m, sizeof(m)); bpf_map_delete_elem(connect_start, sk); return 0; }这个 eBPF 程序在tcp_connectSYN 发送和tcp_finish_connect连接建立完成两个内核函数上挂 kprobe计算连接建立延迟。输出的 metric 通过 Perf Event Buffer 传到用户态的 Parca agent再转换为 Prometheus 指标格式。3.3 服务间延迟拓扑图基于 eBPF 采集的数据可以自动生成服务间延迟拓扑graph LR G[Gateway] --|connect: 2msbrRTT: 15ms| T[Tokenizer] T --|connect: 1msbrRTT: 8ms| I[Inference] G --|connect: 3msbrRTT: 20ms| I I --|connect: 5msbrRTT: 25ms| E[Embedding] style G fill:#1565c0,color:#fff style T fill:#1976d2,color:#fff style I fill:#1e88e5,color:#fff style E fill:#2196f3,color:#fff这个拓扑图不是手绘的是基于 eBPF 数据自动生成的。每条边的延迟数据来自实际的 TCP 连接统计不是估算值。当 Gateway→Inference 的 RTT 从 20ms 突增到 200ms 时拓扑图上这条边会标红问题定位一目了然。四、生产实践与踩坑eBPF 的内核版本要求。kprobe类型的 eBPF 程序需要 Linux 4.1BTFBPF Type Format支持需要 5.2。推理服务的 GPU 节点通常跑较新的内核5.10没问题但一些老旧的 CPU 节点可能还在 4.x 内核上需要检查。Pixie 的部署脚本会自动检测内核版本并选择兼容的 eBPF program。性能影响。eBPF 程序在内核态执行每个 TCP 事件都会触发 hook。在 QPS 1000 的推理服务上每秒可能触发数万次 hook。实测数据显示eBPF hook 增加的 CPU 开销在 0.5-2% 范围内对推理服务的 GPU 计算无影响GPU 不参与 TCP 处理。但如果 CPU 节点已经很紧张80% 利用率2% 的额外开销需要评估。数据量和采样。eBPF 捕获每个 TCP 事件数据量可能很大。生产环境需要采样或聚合不在每个连接上输出一个 metric而是在 5 秒窗口内聚合计算 P50/P95/P99 延迟每个 (src_pod, dst_pod) 组合输出一个聚合 metric。这把数据量从每秒数万条降到每秒几十条。和分布式追踪的配合。eBPF 网络数据是基础设施层的视角分布式追踪是应用层的视角。两者互补eBPF 告诉你Gateway→Inference 的 RTT 是 200ms追踪告诉你这个 200ms 里排队花了 50ms、预处理花了 30ms、推理花了 120ms。eBPF 定位网络问题追踪定位应用问题。安全合规。eBPF 可以拦截所有网络数据这在安全审计层面是敏感的。确保 eBPF 程序只采集延迟统计不采集 payload 内容不读 TCP 数据包的 body。上面的示例程序只记录时间戳和端口不读数据内容符合安全要求。五、总结eBPF 网络观测的核心价值不改代码、不重新部署、不侵入应用直接从内核层采集服务间网络延迟。对于多服务协作的推理架构这层观测是必需的——应用层埋点只能看到自己发起的调用eBPF 能看到所有 TCP 流量的全局视图。三个关键实践优先用 Pixie 快速部署开箱即用的 eBPF 观测平台不需要自己写内核代码适合快速验证。聚合输出而非逐事件输出5 秒窗口内按 (src, dst) 聚合延迟分布控制数据量。eBPF 和追踪配合eBPF 定位网络层问题追踪定位应用层问题两者互补而非替代。基础设施不需要漂亮话。eBPF 的价值不是酷炫的内核技术是在不改代码的前提下获取你本来获取不到的网络延迟数据。能获取到就能做判断获取不到就只能猜测。