3. 流量可视化基础:网络数据包在内核中的路径、eBPF挂载点选择策略
要实现节点池的流量可视化,首先需要理解网络数据包在Linux内核中的完整旅程。eBPF技术之所以强大,是因为它能在数据包路径的关键节点上“挂载”观测程序,从而以极低的开销捕获流量元数据。本章将深入剖析数据包的内核路径,并对比XDP、TC、Socket Filter三大挂载点的适用场景与选择策略。
3.1 网络数据包在内核中的路径
一个数据包从网卡到达用户态应用,需要经过多个内核子系统。下图展示了标准路径上的关键阶段与eBPF挂载点位置:
数据包从网卡接收后,依次经过以下关键阶段:
- 网卡驱动层:数据包通过DMA写入内存环形缓冲区,触发硬中断。
- XDP(eXpress Data Path):在驱动层之后、协议栈之前执行,是eBPF最早介入点。
- 内核协议栈:进行IP路由、TCP/UDP解包、连接跟踪等处理。
- TC(Traffic Control)Ingress:协议栈处理前,可对入站流量进行整形或过滤。
- TC Egress:协议栈处理后、出站前,可对出站流量进行控制。
- Socket Filter:在socket层,数据包交付给用户态应用前,可进行过滤或观测。
3.2 eBPF挂载点选择策略
不同的挂载点决定了eBPF程序能获取的数据粒度、性能开销以及操作能力。下表对比了三大核心挂载点的关键差异:
| 特性 | XDP | TC (Ingress/Egress) | Socket Filter |
|---|---|---|---|
| 介入时机 | 驱动层,协议栈之前 | 协议栈前后 | Socket层,交付用户态前 |
| 性能开销 | 极低(无协议栈开销) | 低(需经过协议栈部分处理) | 中等(需完整协议栈处理) |
| 可操作动作 | 丢弃、重定向、透传 | 丢弃、重定向、整形、镜像 | 过滤、复制、统计 |
| 数据可见性 | 原始L2/L3帧 | sk_buff结构(含L4信息) | 已解析的socket数据 |
| 适用场景 | DDoS防御、负载均衡、高速抓包 | 流量镜像、QoS、容器网络策略 | 应用层监控、协议分析、审计 |
| 编程接口 | BPF_PROG_TYPE_XDP | BPF_PROG_TYPE_SCHED_CLS | BPF_PROG_TYPE_SOCKET_FILTER |
3.3 挂载点选择决策流程
在实际的节点池巡检场景中,选择挂载点需要根据观测目标和性能要求进行权衡。以下决策树可以帮助快速定位:
3.4 实战:在节点池中部署TC Ingress观测点
对于大多数节点池巡检场景,TC Ingress 是最佳平衡点。它既能获取完整的L4元数据(源IP、目的IP、端口、协议),又不会像Socket Filter那样增加协议栈尾部延迟。以下是一个挂载TC Ingress eBPF程序的示例:
// tc_ingress_kern.c - 挂载到 TC Ingress 的 eBPF 程序
#include <linux/bpf.h>
#include <linux/pkt_cls.h>
#include <bpf/bpf_helpers.h>
SEC("classifier")
int tc_ingress_func(struct __sk_buff *skb) {
// 提取 L3/L4 元数据
__u32 src_ip = skb->remote_ip4;
__u32 dst_ip = skb->local_ip4;
__u16 src_port = skb->remote_port;
__u16 dst_port = skb->local_port;
__u8 protocol = skb->protocol;
// 将元数据发送到 perf ring buffer 或 map
// ... (此处省略具体输出逻辑)
return TC_ACT_OK; // 放行数据包
}
char _license[] SEC("license") = "GPL";
# 加载 TC Ingress eBPF 程序到 eth0
tc qdisc add dev eth0 clsact
tc filter add dev eth0 ingress bpf da obj tc_ingress_kern.o sec classifier
# 验证挂载状态
tc filter show dev eth0 ingress
最佳实践:在节点池中,建议为每个节点的物理网卡和容器veth对分别挂载TC Ingress程序。物理网卡捕获南北向流量,veth对捕获东西向流量,从而实现全量流量可视化。
3.5 挂载点选择避坑指南
- XDP 不支持虚拟网卡:XDP需要原生驱动支持,在veth、tun等虚拟设备上无法使用。容器场景下,东西向流量需依赖TC。
- Socket Filter 无法捕获被丢弃的包:如果数据包在协议栈中被iptables或策略路由丢弃,Socket Filter将无法感知。此时应使用XDP或TC。
- TC Egress 的流量顺序:出站流量在TC Egress阶段已经过协议栈完整处理,适合做流量整形和镜像,但不适合做原始包捕获。
- 性能与数据完整性的权衡:XDP性能最好但只能看到L2/L3头部;TC可看到L4;Socket Filter可看到应用层数据。根据巡检需求选择合适粒度。
核心结论:节点池流量可视化的挂载点选择应遵循“先TC Ingress,不足再XDP,需要应用层再Socket Filter”的原则。TC Ingress在绝大多数场景下提供了性能与数据完整性的最佳平衡。