数据结构论坛

首页 » 分类 » 问答 » 深入浅出eBPF你要了解的7个核心问题
TUhjnbcbe - 2025/1/25 21:22:00

过去一年,ARMS基于eBPF技术打造了Kubernetes监控,提供多语言无侵入的应用性能,系统性能,网络性能观测能力,验证了eBPF技术的有效性。eBPF技术和生态发展很好,未来前景广大,作为该技术的实践者,本文目标是通过回答7个核心问题介绍eBPF技术本身,为大家解开eBPF的面纱。

eBPF是什么?

eBPF是一个能够在内核运行沙箱程序的技术,提供了一种在内核事件和用户程序事件发生时安全注入代码的机制,使得非内核开发人员也可以对内核进行控制。随着内核的发展,eBPF逐步从最初的数据包过滤扩展到了网络、内核、安全、跟踪等,而且它的功能特性还在快速发展中,早期的BPF被称为经典BPF,简称cBPF,正是这种功能扩展,使得现在的BPF被称为扩展BPF,简称eBPF。

eBPF的应用场景是什么?

网络优化

eBPF兼具高性能和高可扩展特性,使得其成为网络方案中网络包处理的优选方案:

高性能

JIT编译器提供近乎内核本地代码的执行效率。

高可扩展

在内核的上下文里,可以快速地增加协议解析和路由策略。

故障诊断

eBPF通过kprobe,tracepoints跟踪机制兼具内核和用户的跟踪能力,这种端到端的跟踪能力可以快速进行故障诊断,与此同时eBPF支持以更加高效的方式透出profiling的统计数据,而不需要像传统系统需要将大量的采样数据透出,使得持续地实时profiling成为可能。

安全控制

eBPF可以看到所有系统调用,所有网络数据包和socket网络操作,一体化结合进程上下文跟踪,网络操作级别过滤,系统调用过滤,可以更好地提供安全控制。

性能监控

相比于传统的系统监控组件比如sar,只能提供静态的counters和gauges,eBPF支持可编程地动态收集和边缘计算聚合自定义的指标和事件,极大地提升了性能监控的效率和想象空间。

eBPF为什么会出现?

eBPF的出现本质上是为了解决内核迭代速度慢和系统需求快速变化的矛盾,在eBPF领域常用的一个例子是eBPF相对于LinuxKernel类似于Javascript相对于HTML,突出的是可编程性。一般来说可编程性的支持通常会带来一些新的问题,比如内核模块其实也是为了解决这个问题,但是他没有提供很好的边界,导致内核模块会影响内核本身的稳定性,在不同的内核版本需要做适配等。eBPF采用以下策略,使得其成为一种安全高效地内核可编程技术:

安全

eBPF程序必须被验证器校验通过后才能执行,且不能包含无法到达的指令;eBPF程序不能随意调用内核函数,只能调用在API中定义的辅助函数;eBPF程序栈空间最多只有字节,想要更大的存储,就必须要借助映射存储。

高效

借助即时编译器(JIT),且因为eBPF指令依然运行在内核中,无需向用户态复制数据,大大提高了事件处理的效率。

标准

通过BPFHelpers,BTF,PERFMAP提供标准的接口和数据模型供开发者使用。

功能强大

eBPF不仅扩展了寄存器的数量,引入了全新的BPF映射存储,还在4.x内核中将原本单一的数据包过滤事件逐步扩展到了内核态函数、用户态函数、跟踪点、性能事件(perf_events)以及安全控制等领域。

eBPF怎么用?

5个步骤

1、使用C语言开发一个eBPF程序;

即插桩点触发事件时要调用的eBPF沙箱程序,该程序会在内核态运行。

2、借助LLVM把eBPF程序编译成BPF字节码;

eBPF程序编译成BPF字节码,用于后续在eBPF虚拟机内验证并运行。

3、通过bpf系统调用,把BPF字节码提交给内核;

在用户态通过bpf系统,将BPF字节码加载到内核。

4、内核验证并运行BPF字节码,并把相应的状态保存到BPF映射中;

内核验证BPF字节码安全,并且确保对应事件发生时调用正确的eBPF程序,如果有状态需要保存,则写入对应BPF映射中,比如监控数据就可以写到BPF映射中。

5、用户程序通过BPF映射查询BPF字节码的运行状态。

用户态通过查询BPF映射的内容,获取字节码运行的状态,比如获取抓取到的监控数据。

一个完整的eBPF程序,通常包含用户态和内核态两部分:用户态程序需要通过BPF系统调用跟内核进行交互,进而完成eBPF程序加载、事件挂载以及映射创建和更新等任务;而在内核态中,eBPF程序也不能任意调用内核函数,而是需要通过BPF辅助函数完成所需的任务。尤其是在访问内存地址的时候,必须要借助bpf_probe_ad系列函数读取内存数据,以确保内存的安全和高效访问。在eBPF程序需要大块存储时,我们还需要根据应用场景,引入特定类型的BPF映射,并借助它向用户空间的程序提供运行状态的数据。

eBPF程序分类和使用场景

bpftoolfeatuprobe

gpprogram_type

以上命令可以查看系统支持的eBPF程序类型,一般有如下类型:

eBPFprogram_typesocket_filterisavailableeBPFprogram_typekprobeisavailableeBPFprogram_typesched_clsisavailableeBPFprogram_typesched_actisavailableeBPFprogram_typetracepointisavailableeBPFprogram_typexdpisavailableeBPFprogram_typeperf_eventisavailableeBPFprogram_typecgroup_skbisavailableeBPFprogram_typecgroup_sockisavailableeBPFprogram_typelwt_inisavailableeBPFprogram_typelwt_outisavailableeBPFprogram_typelwt_xmitisavailableeBPFprogram_typesock_opsisavailableeBPFprogram_typesk_skbisavailableeBPFprogram_typecgroup_deviceisavailableeBPFprogram_typesk_msgisavailableeBPFprogram_typeraw_tracepointisavailableeBPFprogram_typecgroup_sock_addrisavailableeBPFprogram_typelwt_seg6localisavailableeBPFprogram_typelirc_mode2isNOTavailableeBPFprogram_typesk_useportisavailableeBPFprogram_typeflow_dissectorisavailableeBPFprogram_typecgroup_sysctlisavailableeBPFprogram_typeraw_tracepoint_writableisavailableeBPFprogram_typecgroup_sockoptisavailableeBPFprogram_typetracingisavailableeBPFprogram_typestruct_opsisavailableeBPFprogram_typeextisavailableeBPFprogram_typelsmisavailable

具体可参考

1
查看完整版本: 深入浅出eBPF你要了解的7个核心问题