InfoQ|eBPF 在网易轻舟云原生的应用实践


eBPF 是 Linux 内核近几年最为引人注目的特性之一 , 通过一个内核内置的字节码虚拟机 , 完成数据包过滤、调用栈跟踪、耗时统计、热点分析等等高级功能 , 是 Linux 系统和 Linux 应用的功能 / 性能分析利器 。 本文将介绍 eBPF 的技术特点 , 及 eBPF 在网易杭研轻舟系统探测和网络性能优化方面的应用 。1. 技术浅析—eBPF 好在哪里 eBPF 是 Linux Kernel 3.15 中引入的全新设计 , 将原先的 BPF 发展成一个指令集更复杂、应用范围更广的“内核虚拟机” 。
eBPF 支持在用户态将 C 语言编写的一小段“内核代码”注入到内核中运行 , 注入时要先用 llvm 编译得到使用 BPF 指令集的 ELF 文件 , 然后从 ELF 文件中解析出可以注入内核的部分 , 最后用 bpf_load_program 方法完成注入 。 用户态程序和注入到内核中的程序通过共用一个位于内核中的 eBPF MAP 实现通信 。 为了防止注入的代码导致内核崩溃 , eBPF 会对注入的代码进行严格检查 , 拒绝不合格的代码的注入 。
InfoQ|eBPF 在网易轻舟云原生的应用实践
本文插图
1.1 eBPF 的技术优势 eBPF 具备一些非常棒的特性 , 使得我们在内核层面的监控变得更加便捷、高效 , 并且非常安全:

  • 平台无关 , 由 JIT 负责将 BPF 代码翻译成最终的处理器指令;
  • 内核无关 , 辅助函数(Helper functions)使得 BPF 能够通过一组内核定义的函数调用(Function call)来从内核中查询数据 , 或者将数据推送到内核 。 不同类型的 BPF 程序能够使用的辅助函数可能是不同的;
  • 安全检查 , 和内核模块不同 , BPF 程序会被一个位于内核中的校验器(in-kernel verifier)进行校验 , 以确保它们不会造成内核崩溃、程序永远能够终止等;
  • 方便升级 , 对于网络场景(例如 TC 和 XDP) , BPF 程序可以在无需重启内核、系统服务或容器的情况下实现原子更新 , 并且不会导致网络中断;
  • 通信方式 , eBPF MAP , 跟 Ftrace 提供的 ring buffer 相比就是数据常驻内存 , 不会读取之后就消失;
    - 事件驱动 , BPF 程序在内核中的执行总是事件驱动的;
1.2 eBPF 和其他 trace 工具的对比 在 eBPF 出现之前 , Linux 已经存在多种成熟的 trace 机制和相应的上层工具:
InfoQ|eBPF 在网易轻舟云原生的应用实践
本文插图
如上图所示 , eBPF 借助 perf_event 和 trace_event 几乎支持对目前所有已知 trace 功能的支持 , 唯一与传统 trace 工具不同的是 , attach 到每个探测点的 probe 函数是运行在 JIT 虚拟机上的 eBPF 程序 , 具备上面提到平台无关、内核无关、安全等一系列更优的特性 。
2 热点追踪—eBPF 有哪些应用场景 eBPF 应用主要分为两个场景 , 一是系统探测、二是网络方面性能优化(包括数据面传输和规则匹配等场景) 。
2.1 在系统探测方面 在国外 , Google 已经开始用 BPF 做 profiling , 找出在分布式系统中应用消耗多少 CPU 。 而且 , 他们也开始将 BPF 的使用范围扩展到流量优化和网络安全 。
在国内 , 字节跳动利用 eBPF 技术开发了一款名为 sysprobe 的监控工具 , 用来定位分析线上业务的性能瓶颈等 。
基于 eBPF 开源的探测工具推荐两个:
  1. BCC 是 eBPF 的一个外围工具集 , 使得 “编写 BPF 代码 - 编译成字节码 - 注入内核 - 获取结果 - 展示” 整个过程更加便捷 。 此外 BCC 项目还有一个非常丰富的探测工具集合 。
  2. Bpftrace 可以理解为是 eBPF 的高级追踪语言 , 动态的翻译这些语言 , 生成 eBPF 后端程序并通过 BCC 工具实现和 Linux BPF 系统进行交互 。


    推荐阅读