您的浏览器禁用了JavaScript(一种计算机语言,用以实现您与网页的交互),请解除该禁用,或者联系我们。[龙蜥社区&浪潮信息]:2023年eBPF技术实践白皮书 - 发现报告

2023年eBPF技术实践白皮书

AI智能总结
查看更多
2023年eBPF技术实践白皮书

编写说明 编写单位:浪潮电子信息产业股份有限公司、阿里云计算有限公司 参编组织:龙蜥社区 编写组成员:苏志远、吴栋、方浩、王传国、梁媛、黄吉旺、毛文安、程书意、甄鹏、李宏伟、彭彬彬 前言 eBPF的诞生是BPF技术的一个转折点,使得BPF不再仅限于网络栈,而是成为内核的一个顶级子系统。在内核发展的同时,eBPF繁荣的生态也进一步促进了eBPF技术的蓬勃发展。随着内核的复杂性不断增加,eBPF以安全、稳定、零侵入、方便的内核可编程性等特点成为实现内核定制与功能多样性的最佳选择,为内核提供了应对未来挑战的基础。 本白皮书重点介绍eBPF技术的概念、技术实践以及发展趋势。本书首先梳理了eBPF的架构和重要技术原理,然后分析了eBPF在多种典型应用场景的使用方案,并进一步对eBPF技术的发展趋势做了探讨。 目录 eBPF简介..................................................................................................................6eBPF技术介绍..........................................................................................................72.1eBPF架构.......................................................................................................72.1.1eBPF加载过程...................................................................................82.1.2JIT编译..............................................................................................92.1.3挂载与执行......................................................................................102.2eBPF常见的开发框架.................................................................................172.2.1BCC...................................................................................................172.2.2bpfTrace...........................................................................................182.2.3libbpf.................................................................................................182.2.4libbpf-bootstrap..............................................................................192.2.5cilium-ebpf.......................................................................................192.2.6Coolbpf.............................................................................................19eBPF的应用场景与实践........................................................................................233.1基于eBPF的系统诊断...............................................................................23 3.1.1系统诊断面临挑战..........................................................................23 3.1.2基于eBPF的系统诊断方案...........................................................28 3.2基于eBPF的虚拟化IO全链路时延监测................................................34 3.2.1虚拟化IO全路径分析主要面临的挑战.......................................34 3.2.2基于bpftrace虚拟化IO路径追踪解决方案...............................36 3.3基于eBPF的网络性能优化.......................................................................41 3.3.1Linux网络性能优化面临的技术挑战............................................41 3.3.2基于eBPF的Linux内核网络性能优化解决方案.......................44 3.4基于eBPF的主机安全...............................................................................53 3.4.1传统解决方案面临挑战..................................................................53 3.4.2基于eBPF的新一代主机安全解决方案.......................................54 挑战与展望.............................................................................................................63 eBPF简介 eBPF是一项起源于Linux内核的革命性技术,可以在特权上下文中(如操作系统内核)运行沙盒程序。它可以安全有效地扩展内核的功能,并且不需要更改内核源代码或加载内核模块。 内核因具有监督和控制整个系统的特权,一直是实现可观察性、安全性和网络功能的理想场所。同时,由于对稳定性和安全性的高要求,内核发展相对缓慢,与内核之外实现的功能相比,创新速度较慢。 eBPF从根本上改变了上述情况,它允许在内核中运行沙箱程序,即通过运行eBPF程序向正在运行中的操作系统添加额外的功能,并通过验证引擎和即时编译器保证安全性和执行效率,由此衍生出了一系列的产品和项目,涉及下一代网络、可观察性和安全技术。 如今,eBPF在多种应用场景中起到重要作用:在现代数据中心和云原生环境中提供高性能网络和负载均衡,以低开销提取细粒度的安全可观察性数据,帮助应用程序开发人员跟踪应用程序的运行状态,高效进行性能故障定位,保证应用程序和容器运行时安全等。 eBPF引领的创新才刚刚开始,一切皆有可能。 eBPF技术介绍 2.1eBPF架构 eBPF包括用户空间程序和内核程序两部分,用户空间程序负责加载BPF字节码至内核,内核中的BPF程序负责在内核中执行特定事件,用户空间程序与内核BPF程序可以使用map结构实现双向通信,这为内核中运行的BPF程序提供了更加灵活的控制。eBPF的工作逻辑如下: 1、eBPF Program通过LLVM/Clang编译成eBPF定义的字节码; 2、通过系统调用bpf()将字节码指令传入内核中; 3、由Verifier检验字节码的安全性、合规性; 4、在确认字节码程序的安全性后,JITCompiler会将其转换成可以在当前系统运行的机器码; 5、根据程序类型的不同,把可运行机器码挂载到内核不同的位置/HOOK点; 6、等待触发执行,其中不同的程序类型、不同的HOOK点的触发时机是不相同的;并且在eBPF程序运行过程中,用户空间可通过eBPF map与内核进行双向通信; 2.1.1eBPF加载过程 编译得到的BPF字节码文件,经过字节码读取、重定位和Verifier等过程,加载到内核中。 1、字节码读取 通常eBPF字节码文件都是ELF格式,各section中保存着字节码所有的信息,包括字节码指令、map定义、BTF信息,以及需要重定位的变量和函数等;eBPF加载时,依照ELF格式读取字节码文件,把各种信息按照一定的格式保存起来。 2、重定位 重定位是指在编译、加载的过程中把字节码中一些临时数据以更准确的信息进行替换,比如用map句柄替换map索引,用map地址替换map句柄。经过多轮重定位,可以确保eBPF程序在内核中运行所需数据的正确性和完整性。需要重定位的对象有:map、函数调用、Helper函数调用、字段、Extern内核符号和kconfig。 重定位操作主要分为2类: 1)BPF基础设施提供了一组有限的“稳定接口”,通过convert_ctx_access对CTX进行转换,实现内核版本升级时的稳定性和兼容性。 2)CO-RE采用(BTF)非硬编码的形式对成员在结构中的偏移位置进行描述,解决不同版本之间的差异性问题。 3、Verifier Verifier是一个静态代码安全检查器,用于检查eBPF程序的安全性,保证eBPF程序不会破坏内核,影响内核的稳定性。 安全检查主要分成两个阶段。 第一个阶段检查函数的深度和指令数,通过使用深度优先遍历,来检查是否为有向无环图(DAG)。 第二个阶段检查每条bytecode指令,根据指令的分类(class),检查其操作寄存器的读写属性、内存访问是否越界、BPF_CALL是否符合接口协议等。 指针的安全性检查在第二个阶段实现,每次把指针加载到寄存器时都会进行指针类型的判定,根据指针类型定义确定读写属性和大小,实现针对指针操作的安全性检查;未识别的指针类型不允许解引用。 2.1.2JIT编译 执行字节码是一个模拟CPU执行机器码的过程,在运行时需要先把指令依次翻译成机器码之后才能运行,所以比机器码的执行效率低很多。JIT(Just In Time)的 中文意思是即时编译,主要为了解决虚拟机运行中间码时效率不高的问题。 JIT编译在执行前先把中间码编译成对应的机器码并缓存起来,从而运行时能够直接执行机器码,这样就解决了每次执行都需要进行中间码解析的问题,如下图所示: 2.1.3挂载与执行 eBPF在内核提供了大量的挂载点,算上kprobe挂载点,几乎可以在内核代码的任意函数挂载一段eBPF程序。不同eBPF程序类型的挂载点各不相同,挂载点是根据设计与需求提前在内核指定位置通过提前嵌入代码实现的,初始时函数指针是空,挂载eBPF程序后,对指针赋值,指向eBPF内核程序。 为了安全性,挂载eBPF程序需要root权限或CAP_BPF capability,不过目前也有设计允许非root权限帐号载入eBPF程