eBPF学习笔记1

按照惯例,第一篇先来个概览,做一些基础知识的铺垫。

目前这个技术领域还相对较“新”,本人也刚刚开始摸索学习,有错误的地方还请大佬们多多指正。

什么是eBPF?

eBPF由BPF(Berkeley Packet Filter)扩展而来,提供了一种在内核事件和用户程序事件发生时安全注入代码的机制,使得非内核开发人员也可以对内核进行控制,无需修改内核源码和重新编译内核就可以扩展内核的功能。(简单类比的话,就类似未成年人可以在有限的范围内安全的做一些成年人才能做的事了)

之前想对内核做点什么,需要编写内核模块后编译进去,一个不小心就把内核搞崩了。而eBPF则通过即时编译器(JIT),保证只有经过验证的、安全的eBFP指令才会被内核执行。

为什么需要eBPF?

从业界的角度看,最主要的因素还是对性能的追求。比如,小规模的k8s使用iptables就可以搞定容器网络通信,但随着规模的增大iptables性能问题越发明显,然后就有了IPVS模式。虽然IPVS和iptables都是基于Netfilter,但由于IPVS使用哈希表而iptables使用规则链表,导致前者的性能高于后者。然后随着集群规模的再次扩大,对性能有了更高的要求,于是乎eBPF就成了目前进一步提高性能的技术方案:

The aforementioned KubeCon Talk performed specific measurements on iptables as a bottleneck for Kubernetes service forwarding and noted that throughput degraded by ~30% with 5,000 services deployed, and by 80% with 10,000 services (a 6X performance difference). Likewise, rule updates at 5,000 services took 11 minutes, ages in a world of continuous delivery.

Thanks to the flexibility of BPF, Cilium performs this same operation with O(1) average runtime behavior using a simple BPF map based hash table, meaning the lookup latency at 10,000 or even 20,000 services is constant. Likewise, updates to these BPF maps from userspace are highly-efficient, meaning that even with 20,000+ services, the time to update a forwarding rule is microseconds, not hours.

For these reasons, Facebook has recently presented their use of BPF and XDP for load-balancing in a public talk to replace IPVS after measuring an almost 10x performance increase.

如何使用eBPF?

大神的博客有非常详细的说明,从易到难依次是使用:

  1. bpftrace,大神重点推荐这个,这个是一种简单的语言来调用eBPF强大的能力。
  2. bcc,第二推荐这个,既提供了一堆开箱即用的工具,也提供了方便python、go等语言集成使用的框架。
  3. 纯C语言开发,大神的表格里只写了一个单词,“DIFFICULT”……

image

后面的系列笔记将围绕这里来展开。

使用eBPF时应该注意?

  • 不能随意调用内核函数,只能调用API中定义的辅助函数。
  • 栈空间最多只有512字节,如果需要更大存储则需要借助映射存储。
  • 内核5.2之前,字节码最多支持4096条指令,5.2后这个限制变成了100万条。
  • 程序必须通过验证器验证后才能执行。

下图说明了eBPF程序的执行过程: image

各个内核支持的特性可以参考 这里

eBPF的应用领域?

目前运用在故障诊断、网络优化、安全控制、性能监控这几个领域的比较多,下面的图来自 官网

image

eBPF的优缺点?

优点

  1. 由于直接运行在内核态,所以高效是最大的一个优点。
  2. 安全稳定。eBPF程序首先经过LLVM转换成BPF字节码后,通过bpf系统调用交给内核执行,字节码需要通过校验才会交给JIT执行。

缺点

  1. 目前来看,还是有一定的门槛。虽然使用BCC、bpftrace写个小工具相对简单,但想要更进一步,还是需要对操作系统原理、内核主要模块有一定的了解。
  2. 目前来看,由于不同的内核版本之前的差别,会导致某个内核版本上编写的eBPF程序没法在另一个内核版本上完美运行。不过随着CO-RE(Compile Once – Run Everywhere)的完善,这个问题迟早会被解决。

推荐阅读

  • 官网
  • ebpf-2021峰会,视频需要科学上网。
  • ebpf-2020峰会,视频需要科学上网。
  • BCC,BCC工具集。
  • bpftrace,目前还是短平快的语言,用来写简单的BPF程序。
  • libbpf,上面提到的CO-RE,可以看看这个库。
  • cilium,基于eBPF的容器网络插件。
  • BPF夜读,这个名字我起的,是一群台湾的小伙伴互相分享的读书心得,可惜只到前8章。
  • 《BPF Performance tools》(中译本:《BPF之巅》),截至2022.2.2有2本BPF相关的书,就看这本,当作工具书。
  • brendangregg大神的博客,上面书的作者,大神级人物,博客里好多高质量文章。
  • BPF Internals,大神关于bpf内部原理的讲解。
  • 《eBPF核心技术与实战》,极客时间倪朋飞大神的课程。
  • 绕过conntrack,使用eBPF增强 IPVS优化K8s网络性能,来自腾讯云的一篇分享,关于使用eBPF+IPVS后性能提升的相关指标。