• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

运维人不得不了解的eBPF入门指南新手建议收藏

linux 搞代码 4年前 (2022-03-03) 58次浏览 已收录 0个评论
文章目录[隐藏]

eBPF(Extended Berkeley Packet Filter)的外围是驻留在 kernel 的高效虚拟机。最后的目标是高效网络过滤框架,前身是BPF,所以咱们先理解下BPF

BPF

框架


上图是BPF的地位和框架,须要留神的是kernel和user应用了buffer来传输数据,防止频繁上下文切换。BPF虚拟机十分简洁,由累加器、索引寄存器、存储、隐式程序计数器组成。

示例

接下来咱们看一下示例,过滤所有ip报文,能够应用 tcpdump -d ip 查看:

(000) ldh      [12]                             // 链路层第12字节的数据加载到寄存器,ethertype字段
(001) jeq      #0x800           jt 2    jf 3    // 比拟寄存器的ethertype字段是否为IP类型,true跳到2,false跳到3
(002) ret      #65535                           // 返回true
(003) ret      #0                               // 返回0

BPF只应用了4条虚拟机指令,就能提供十分有用的IP报文过滤。

tcpdump -d tcp

(000) ldh      [12]                             // 链路层第12字节的数据(2字节)加载到寄存器,ethertype字段
(001) jeq      #0x86dd          jt 2    jf 7    // 判断是否为IPv6类型,true跳到2,false跳到7
(002) ldb      [20]                             // 链路层第20字节的数据(1字节)加载到寄存器,IPv6的next header字段
(003) jeq      #0x6             jt 10    jf 4    // 判断是否为TCP,true跳到10,false跳到4
(004) jeq      #0x2c            jt 5    jf 11   // 可能是IPv6分片标记,true跳到5,false跳到11
(005) ldb      [54]                             // 我编不上来了...
(006) jeq      #0x6             jt 10    jf 11   // 判断是否为TCP,true跳到10,false跳到11
(007) jeq      #0x800           jt 8    jf 11   // 判断是否为IP类型,true跳到8,false跳到11
(008) ldb      [23]                             // 链路层第23字节的数据(1字节)加载到寄存器,next proto字段
(009) jeq      #0x6             jt 10    jf 11   // 判断是否为TCP,true跳到10,false跳到11
(010) ret      #65535                           // 返回true
(011) ret      #0                               // 返回0

以上是freebsd的BPF,Linux中应该不叫这个,叫LSF,本人看吧。

eBPF

eBPF初识

Linux kernel 3.18版本开始蕴含了eBPF,绝对于BPF做了一些重要改良,首先是效率,这要归功于JIB编译eBPF代码;其次是利用范畴,从网络报文扩大到个别事件处理;最初不再应用socket,应用map进行高效的数据存储。

依据以上的改良,内核开发人员在不到两年半的事件,做出了包含网络监控、限速和系统监控。

目前eBPF能够合成为三个过程:

  • 以字节码的模式创立eBPF的程序。编写C代码,将LLVM编译成驻留在ELF文件中的eBPF字节码。
  • 将程序加载到内核中,并创立必要的eBPF-maps。eBPF具备用作socket filter,kprobe处理器,流量管制调度,流量管制操作,tracepoint解决,eXpress Data
    Path(XDP),性能监测,cgroup限度,轻量级tunnel的程序类型。
  • 将加载的程序attach到零碎中。依据不同的程序类型attach到不同的内核零碎中。程序运行的时候,启动状态并且开始过滤,剖析或者捕捉信息。

2016年10月的NetDev 1.2大会上,Netronome的Jakub Kicinski和Nic Viljoen发表了题目为“eBPF / XDP硬件卸载到SmartNIC”。Nic Viljoen在其中介绍了Netronome SmartNIC上每个FPC每秒达到300万个数据包,每个SmartNIC有72到120个FPC,可能最大反对eBPF吞吐量4.3 Tbps!(实践上)

eBPF入口

接下来咱们以内核版本4.14版本为例进行查看。

bpf的零碎调用

kernel/bpf/syscall.c

bpf零碎调用的头文件

include/uapi/linux/bpf.h

入口函数

int bpf(int cmd, union bpf_attr *attr, unsigned int size);

kernel/bpf/syscall.c中的宏定义开展。

eBPF命令

Linux零碎的BPF零碎调用有10个命令,其中man page中列出了6个:

  • BPF_PROG_LOAD 验证并且加载eBPF程序,返回一个新的文件描述符。
  • BPF_MAP_CREATE 创立map并且返回指向map的文件描述符
  • BPF_MAP_LOOKUP_ELEM 通过key从指定的map中查找元素,并且返回value值
  • BPF_MAP_UPDATE_ELEM 在指定的map中创立或者更新元素(key/value 配对)
  • BPF_MAP_DELETE_ELEM 通过key从指定的map中找到元素并且删除
  • BPF_MAP_GET_NEXT_KEY 通过key从指定的map中找到元素,并且返回下个key值

以上的命令能够分为两大类,加载eBPF程序和eBPF-maps操作。eBPF-maps操作有很大的自主性,用于创立eBPF-maps,从中查找、更新和删除元素,遍历eBPF-maps(BPF_MAP_GET_NEXT_KEY)

接下来列一下剩下的4个命令,在代码中能够看到:

  • BPF_OBJ_PIN 4.4版本新加的,属于持久性eBPF。有了这个,eBPF-maps和eBPF程序能够放入/sys/fs/bpf
  • BPF_OBJ_GET同上,在这之前,没有工具能创立eBPF程序,并且完结,因为会毁坏filter,而文件系统能够在创立他们的程序退出后仍然保留eBPF-maps和eBPF程序
  • BPF_PROG_ATTACH 4.10版本中增加的,将eBPF程序attach到cgroup,这样实用于container
  • BPF_PROG_DETACH 同上。

eBPF-map 类型

Linux零碎的BPF零碎调用有10个命令,其中man page中列出了6个:

BPF_PROG_LOAD 验证并且加载eBPF程序,返回一个新的文件描述符。

BPF_MAP_CREATE 创立map并且返回指向map的文件描述符

BPF_MAP_LOOKUP_ELEM 通过key从指定的map中查找元素,并且返回value值

BPF_MAP_UPDATE_ELEM 在指定的map中创立或者更新元素(key/value 配对)

BPF_MAP_DELETE_ELEM 通过key从指定的map中找到元素并且删除

BPF_MAP_GET_NEXT_KEY 通过key从指定的map中找到元素,并且返回下个key值

以上的命令能够分为两大类,加载eBPF程序和eBPF-maps操作。eBPF-maps操作有很大 的自主性,用于创立eBPF-maps,从中查找、更新和删除元素,遍历eBPF-maps(BPF_MAP_GET_NEXT_KEY)

接下来列一下剩下的4个命令,在代码中能够看到:

  • BPF_OBJ_PIN 4.4版本新加的,属于持久性eBPF。有了这个,eBPF-maps和eBPF程序能够放入/sys/fs/bpf
  • BPF_OBJ_GET同上,在这之前,没有工具能创立eBPF程序,并且完结,因为会毁坏filter,而文件系统能够在创立他们的程序退出后仍然保留eBPF-maps和eBPF程序
  • BPF_PROG_ATTACH 4.10版本中增加的,将eBPF程序attach到cgroup,这样实用于container
  • BPF_PROG_DETACH 同上。

eBPF-map 类型

BPF_MAP_TYPE_UNSPEC
  • BPF_MAP_TYPE_HASH eBPF-maps hash表,是次要用的前两种形式之一
  • BPF_MAP_TYPE_ARRAY 和下面相似,除了索引像数组一样
  • BPF_MAP_TYPE_PROG_ARRAY将加载的eBPF程序的文件描述符保留其值,罕用的是应用数字辨认不同的eBPF程序类型,也能够从一个给定key值的eBPF-maps找到eBPF程序,并且跳转到程序中去
  • BPF_MAP_TYPE_PERF_EVENT_ARRAY配合perf工具,CPU性能计数器,tracepoints,kprobes和uprobes。能够查看门路samples/bpf/下的tracex6_kern.c,tracex6_user.c,tracex6_kern.c,tracex6_user.c
  • BPF_MAP_TYPE_PERCPU_HASH 和BPF_MAP_TYPE_HASH一样,除了是为每个CPU创立
  • BPF_MAP_TYPE_PERCPU_ARRAY 和BPF_MAP_TYPE_ARRAY一样,除了是为每个CPU创立

BPF_MAP_TYPE_STACK_TRACE 用于存储stack-traces

BPF_MAP_TYPE_CGROUP_ARRAY 查看skb的croup归属

BPF_MAP_TYPE_LRU_HASH
BPF_MAP_TYPE_LRU_PERCPU_HASH
  • BPF_MAP_TYPE_LPM_TRIE 最业余的用法,LPM(Longest Prefix Match)的一种trie
  • BPF_MAP_TYPE_ARRAY_OF_MAPS 可能是针对每个port的
  • BPF_MAP_TYPE_HASH_OF_MAPS 可能是针对每个port的
  • BPF_MAP_TYPE_DEVMAP 可能是定向报文到dev的
  • BPF_MAP_TYPE_SOCKMAP 可能是连贯socket的

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:运维人不得不了解的eBPF入门指南新手建议收藏

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址