1. eBPF
1.1 介绍
eBPF 全称 extended Berkeley Packet Filter,被认为是一项革命性技术,它能在Linux内核中运行沙盒程序(sandbox programs)无需修改内核源代码或编写内核模块就能基于现有的抽象层来实现更加智能、功能更加丰富的基础设施软件,而不会增加系统的复杂度,也不会牺牲执行效率和安全性。
eBPF催生了一种全新的软件开发方式,基于这种方式,我们不仅能对内核进行编程,甚至还能编写跨多个子系统的处理逻辑,使得这些传统上完全独立的子系统可以用一套逻辑来处理。
eBPF可以观测和理解所有的系统调用并在packet层和socket层审视所有的网络操作。以前,系统调用过滤、网络层过滤和进程上下文跟踪是在完全独立的系统中完成的,eBPF统一了可观测性和各层面的控制能力,使上下文更加丰富,控制力更加精细,从而可以创造出更加安全的系统。
eBPF的可编程性和高性能使得所有的网络包处理需求得到满足。无需离开内核中的包处理上下文,就能添加额外的协议解析器或任何转发逻辑,满足不断变化的需求。高性能的JIT编译器使eBPF程序几乎能达到与原生编译的内核态代码一样的执行性能。
1.2 工作流程
eBPF控制流程
- 使用LLVM或GCC等工具,将程序编写成eBPF目标文件
- 使用TC等加载程序,将eBPF目标文件加载至内核,并将eBPF处理挂接到指定hook上
- 内核使用Verifier验证器验证eBPF目标文件,保证其在执行过程中内核的安全性;通过JIT(Just-In-Time)编译器,将其转为内核可执行的本地指令
- 用户态进程可通过bpf bcc对eBPF Maps进行数据的写入或读取
数据处理流程
- 数据到达内核进行处理
- 发现有hook挂接待处理,调用相应的eBPF回调处理
3、4. 读取或写入eBPF Maps
5、6. 返回内核流程继续处理
2. 负载均衡网关使用eBPF
eBPF可以安全高效地在内核对网络包进行处理,因此在负载均衡网关需要支持vxlan网络时,采用eBPF对发往后端服务器的报文进行处理,保证vxlan网络的连通性。
负载均衡网关与后端服务器之间使用vxlan网络连接,每个后端服务器都有其对应的宿主机,vxlan报文的外层目的IP地址即为后端服务器所在宿主机的IP地址,为保证从负载均衡网关发向后端服务器的报文能顺利到达,需要使用eBPF修改vxlan报文的外层目的IP地址为服务器所在宿主机的IP地址,且修改vxlan报文的内层目的MAC地址为服务器MAC地址。若不进行修改则vxlan外层目的IP地址为vxlan接口上配置的固定地址,内层目的MAC地址为网关的MAC地址,不做额外处理则无法实现网络的连通性。
具体处理流程
eBPF控制流程
- 使用LLVM clang,将包含有报文修改和eBPF Maps定义的bpf.c编译成pktmangle.o
- 使用TC加载程序,将o加载至内核,并挂接到egress hook点上
- 内核使用Verifier验证器验证o,保证其在执行过程中内核的安全性;通过JIT(Just-In-Time)编译器,将其转为内核可执行的本地指令
- 用户态agent进程在配置后端服务器时通过bpf bcc对eBPF Maps进行数据的写入,key为后端服务器IP地址(vxlan报文内层目的IP地址)和vni(vxlan对应的vni),value为后端服务器所在宿主机IP地址(vxlan报文外层目的IP地址)和后端服务器MAC地址(vxlan报文内层目的MAC地址)
数据处理流程
- 数据到达内核进行处理
- 发现是报文发送阶段egress有hook挂接待处理,调用相应的eBPF处理
3、4. 根据key(vxlan报文内层目的IP地址和vni)查eBPF Maps中的value
- 用取到的value修改vxlan报文外层目的IP地址和内层目的MAC地址
- 返回内核流程继续处理
本文第一部分简单介绍了eBPF及其工作流程,第二部分介绍了负载均衡网关是如何利用eBPF实现目的IP地址转换从而支持VXLAN网络的,希望通过本文可以让更多的人了解eBPF,为涉及到Linux内核的方案设计多一个选择。