1. 简介

BPF全称是「Berkeley Packet Filter」,翻译过来是「伯克利包过滤器」,顾名思义,它是在伯克利大学诞生的,1992年Steven McCanne 和 Van Jacobson 写了一篇《The BSD Packet Filter: A New Architecture for User-level Packet Capture》论文 ,第一次提出了BPF技术,在文中,作者描述了他们如何在 Unix 内核实现网络数据包过滤,这种新的技术比当时最先进的数据包过滤技术快 20 倍。

下图为BPF概览,来自上面的论文:

image.png

BPF 在数据包过滤上引入了两大革新:

一个新的虚拟机 (VM) 设计,可以有效地,

  • 工作在基于寄存器结构的 CPU 之上;
  • 应用程序使用缓存只复制与过滤数据包相关的数据,不会复制数据包的所有信息,最大程度地减少BPF 处理的数据,提高处理效率

为什么需要BPF
很多程序,例如网络监控器,都是作为用户级进程运行的。为了分析只在内核空间运行的数据,它们必须将这些数据从内核空间复制到用户空间的内存中去,并进行上下文切换。这与直接在内核空间分析这些数据相比,导致了巨大的性能开销。
随着近年来网络速度和流量井喷式增长,一些应用程序必须处理大量的数据(如音频、视频流媒体数据)。要在用户空间监控分析那么多的流量数据已经不可行,因而BPF应运而生。

BPF技术的工具和平台
BCC、Cilium、Falco、bpftrace、kubectl-trace、腾讯云IPVS-BPF模式

2. BPF能力说明

2.1 BPF Hooks

即BPF钩子,也就是在内核中,哪些地方可以加载BPF程序,Linux内核中已经有了近10种的钩子,如下所示:

  • kernel functions (kprobes)
  • userspace functions (uprobes)
  • system calls
  • fentry/fexit
  • Tracepoints
  • network devices (tc/xdp)
  • network routes
  • TCP congestion algorithms
  • sockets (data level)

2.2 BPF Map

BPF程序本身只有指令,不会包含实际数据及其状态,BPF Map可以在存储数据状态、统计信息和指标等信息; BPF Map有很多类型常用的就是Hash和Array类型,如下所示:

  • Hash tables, Arrays
  • LRU (Least Recently Used)
  • Ring Buffer
  • Stack Trace
  • LPM (Longest Prefix match)

补充说明:

  • BPF Map是可以被用户空间访问并操作的
  • BPF Map是可以与BPF程序分离的,即当创建一个BPF Map的BPF程序运行结束后,该BPF Map还能存在,而不是随着程序一起消亡
    可以通过BPF Map特性,实现在不同程序之间共享信息,在收集统计信息或指标等场景下使用

2.3 BPF Helper Function

即BPF辅助函数,是面向开发者的,提供操作BPF程序和BPF Map的工具类函数。由于内核本身会有不定期更新迭代,如果直接调用内核模块,就会出现兼容问题,通过定义和维护BPF辅助函数,由BPF辅助函数来去面对后端的内核函数的变化,对开发者透明,形成稳定API接口。任何一种与操作系统内核的交互都是通过BPF辅助函数来完成的,由于这些都是稳定的API,所以BPF程序可以跨内核版本进行移植。

2.4 限制

为了保证内核的处理安全和及时响应,内核对于BPF 技术也给予了诸多限制,如下:

  • 程序不能调用任意的内核参数,只限于内核模块中列出的 BPF Helper 函数,函数支持列表也随着内核的演进在不断增加
  • 程序不允许包含无法到达的指令,防止加载无效代码,延迟程序的终止
  • 程序中循环次数限制且必须在有限时间内结束
  • 堆栈大小被限制在 MAXBPFSTACK,截止到内核 Linux 5.8 版本,被设置为 512。目前没有计划增加这个限制,解决方法是改用 BPF Map,它的大小是无限的。
  • 字节码大小最初被限制为 4096 条指令,截止到内核 Linux 5.8 版本, 当前已将放宽至 100 万指令( BPF_COMPLEXITY_LIMIT_INSNS),对于无权限的BPF程序,仍然保留4096条限制 ( BPF_MAXINSNS )

3. 安装部署

3.1 内核版本

BPF 需要较新的 Linux kernel 支持。 因此首先要确保你的内核版本足够新,至少要在 4.1 以上

# uname -r
4.20.13-1.el7.elrepo.x86_64

3.2 运行bcc镜像

docker run -it --rm \
  --privileged \
  -v /lib/modules:/lib/modules:ro \
  -v /usr/src:/usr/src:ro \
  -v /etc/localtime:/etc/localtime:ro \
  --workdir /usr/share/bcc/tools \
  zlim/bcc

吕晨曦
4 声望0 粉丝

« 上一篇
Pod删除流程
下一篇 »
kubernets cfs

引用和评论

0 条评论