eBPF技术介绍

最近在看cilium和calico关于eBPF功能,发现有许多不理解的地方,比如概念原理等,因此花费了一定的时间进行了学习和整理,翻了不少文档和博客,最后发现还是cilium社区的这篇文章讲解的最通透,希望后来人可以静下心来把这篇文章慢慢读下来并理解。开始方向错了,其实主要两条线,一个是基于llvm的c语言编写eBPF程序,涉及到一些宏,段定义,maps定义,btf等,llvm按照一定规范为我们编译和生成elf格式的文件,另一个是iproute2/bpftool等加载器将eBPF程序加载到内核,加载工具会读取elf中的各种段信息,将其加载到内核中,此处也会涉及段名称的约定,加载工具与编译器对于btf之间的约定。明白这两块之后再看内核提供的相关辅助函数和不同的map就可以做一些特定功能的bpf程序开发了。 简介 BPF(Berkeley Packet Filter ),中文翻译为伯克利包过滤器,是类 Unix 系统上数据链路层的一种原始接口,提供原始链路层封包的收发。1992 年,Steven McCanne 和 Van Jacobson 写了一篇名为《BSD数据包过滤:一种新的用户级包捕获架构》的论文。在文中,作者描述了他们如何在 Unix 内核实现网络数据包过滤,这种新的技术比当时最先进的数据包过滤技术快 20 倍。BPF 在数据包过滤上引入了两大革新: 一个新的虚拟机 (VM) 设计,可以有效地工作在基于寄存器结构的 CPU 之上; 应用程序使用缓存只复制与过滤数据包相关的数据,不会复制数据包的所有信息。这样可以最大程度地减少BPF 处理的数据; 由于这些巨大的改进,所有的 Unix 系统都选择采用 BPF 作为网络数据包过滤技术,直到今天,许多 Unix 内核的派生系统中(包括 Linux 内核)仍使用该实现。 2014 年初,Alexei Starovoitov 实现了 eBPF(extended Berkeley Packet Filter)。经过重新设计,eBPF 演进为一个通用执行引擎,可基于此开发性能分析工具、网络数据包过滤、系统调用过滤,系统观测和分析等诸多场景。eBPF 最早出现在 3.18 内核中,此后原来的 BPF 就被称为经典 BPF,缩写 cBPF(classic BPF),cBPF 现在已经基本废弃。现在,Linux 内核只运行 eBPF,内核会将加载的 cBPF 字节码透明地转换成 eBPF 再执行。 eBPF 新的设计针对现代硬件进行了优化,所以 eBPF 生成的指令集比旧的 BPF 解释器生成的机器码执行得更快。扩展版本也增加了虚拟机中的寄存器数量,将原有的 2 个 32 位寄存器增加到 10…