lyft|入门即享受!coolbpf 硬核提升 BPF 开发效率

lyft|入门即享受!coolbpf 硬核提升 BPF 开发效率

文章图片

lyft|入门即享受!coolbpf 硬核提升 BPF 开发效率

文章图片

lyft|入门即享受!coolbpf 硬核提升 BPF 开发效率

文章图片

lyft|入门即享受!coolbpf 硬核提升 BPF 开发效率

文章图片

lyft|入门即享受!coolbpf 硬核提升 BPF 开发效率

文章图片


编者按:BPF 技术还在如火如荼的发展着 , 本文先通过对 BPF 知识的介绍 , 带领大家入门 BPF , 然后介绍 coolbpf 的远程编译(原名 LCC , LibbpfCompilerCollection) , 意为酷玩 BPF , 目标把复杂的 BPF 开发和编译过程简化 , 本文还会以一个示例来体验 coolbpf 的享受式开发 。
一、 引言 要完成一个 BPF 二进制程序的开发 , 需要搭建开发编译环境 , 要关注目标系统的内核版本情况 , 需要掌握从 BPF 内核态到用户态程序的编写 , 以及如何加载、绑定至对应的 HOOK 点等待事件触发 , 最后再对输出的日志及数据进行处理 。
这几个过程对于一个刚接触 BPF 的同学会感觉相当繁琐 。 本文先通过对 BPF 知识的介绍 , 带领大家入门BPF , 然后介绍 coolbpf 的远程编译(原名 LCC , LibbpfCompilerCollection ,意为酷玩 BPF , 目标把复杂的 BPF 开发和编译过程简化) , 以一个示例来体验 coolbpf 的享受式开发 。
二、 BPF入门 【lyft|入门即享受!coolbpf 硬核提升 BPF 开发效率】BPF 最早在 1992 年被提出 , 当时叫伯克利包过滤器(Berkely Packet Filter , 一般称为cBPF) , 号称比当时最先进的数据包过滤技术快 20 倍 , 主要应用场景在 tcpdump、seccomp 。
2014年 , Alexei Starovoitov 对 BPF 进行彻底地改造 , 提出 Extended Berkeley Packet Filter (eBPF) 。 eBPF 指令更接近硬件的 ISA , 便于提升性能 , 提供了可基于系统或程序事件高效安全执行特定代码的通用能力 , 通用能力的使用者不再局限于内核开发者 。 其使用场景不再仅仅是网络分析 , 可以基于 eBPF 开发性能分析、系统追踪、网络优化等多种类型的工具和平台 。 我们通常不加区分 , 把 cBPF 和 eBPF 都称之为 BPF 。
2.1 BPF 知识点总结
大家都在谈 BPF , 介绍BPF的文章也很多 , 这里先总结 BPF 的知识点 , 最后我们从最基础的 BPF 指令架构及 map 和 prog type 去介绍如何快速入门 。
risc指令集:包含 11 个 64 位寄存器 (R0 ~ R10) 。maps:BPF 程序之间或内核及用户态间数据交互 。prog type:BPF 程序类型用来确定程序功能以及程序 attach 到什么位置 。helper functions:通过辅助函数访问内核数据 , 如访问 task、pid 等 。jit:将 BPF 程序的字节码转换成目标机的机器码 。object pinning:提供 BPF 文件系统 , 延长 map 和 prog 的生命周期 。tail call:一个BPF程序可以调用另一个 BPF 程序 , 并且调用完成后不用返回到原来的程序 。hardening:保护 BPF 程序和其二进制程序不被破坏(设置成只读) 。 2.2 BPF 发展概况 BPF 经过几十年的发展 , 已经从原来单一的功能用途 , 到如今遍布各个领域的应用 , 包括云原生、企业服务器、安全系统等都在运用这一技术 , 服务生产和生活 。 下图是 BPF 技术的发展史(图源:https://zhuanlan.zhihu.com/p/444454862) 。

随着越来越多的特性被合入到 Linux 内核社区 , BPF 支持的功能因为这些特性加持 , 已经越来越丰富 。

2.3 BPF 和内核模块对比
BPF 的优势是灵活、安全 。 在没有引入 BPF 之前 , 如果我们想要实现一些跟踪诊断的功能 , 可以使用 tracefs/debugfs 中导出的文件系统接口 , 或者编写内核模块插入到内核中运行 。 前者的功能较为固定 , 无法灵活地实现对数据的过滤;后者虽然灵活 , 但容易导致内核 crash , 不够安全 。 ftrace 和 kernel module 给我们很大的自由去抓取内核的一些信息 , 但是却存在不少弊端 。