系列综述:
💞目的:本系列是个人整理为了学习ebpf机制
的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
🥰来源:材料主要源于–知乎ebpf专栏文章
–进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证。
🤭结语:如果有帮到你的地方,就点个赞和关注一下呗,谢谢🎈🎄🌷!!!
请先收藏!!!,后续继续完善和扩充👍(●’◡’●)
前言(欲扬先抑) 【eBPG官方纪录片】
- eBPF提升内核的能效是目标,它要发挥的是瑞士军刀的作用,如果只是为了eBPF而eBPF,那它就是狗皮膏药,你只是为了把它贴到身体的某个地方而已,并且你也会一直找这样的地方,找准机会就贴上去。另一句意思相同的话,大概是如果你有个锤子,那么眼里什么都是钉子
- eBPF应该慎用,其会增加系统的复杂度,从而导致故障概率的提升
- 现在底层主要的工作是通过语言或编译器来确保加载到内核中程序的正确性,类似Rust正在做的事情
- 验证器诞生的原因:不能相信用户空间加载到内核的东西,否则可能导致崩溃
- 核心目标:更好的帮助用户在内核中的创新
一、eBPF介绍
简介
- eBPF概述
- 背景:eBPF(extended Berkeley Packet Filter)是一种扩展的伯克利包过滤器,由原来的网络过滤器BPF 演进成的一个可插拔可编程的内核模块eBPF,可基于此开发性能分析工具、软件定义网络等诸多场景。
- 定义:
- 核心定义:处于内核中的一个高效与灵活的
虚拟机组件
,以一种安全的方式在许多内核 hook 点
执行字节码
。 - BPF之巅定义:
安全地
在用户态或内核态应用程序
发生时运行一小段程序
的机制,从而使得内核可编程
- 核心定义:处于内核中的一个高效与灵活的
- 组成
- 指令集:采用虚拟指令集规范,由linux内核BPF运行时模块执行,可将eBPF看作虚拟机的实现
- 存储对象:
- 辅助函数
- 作用
- 内核可编程:eBPF不需要重新编译内核,并实现动态注入内核运行并随时卸载
- 嵌入内核:直接与内核进行交互,避免了用户态和内核态的切换开销
- 内核监控:追踪内核中的各种事件或资源使用情况,从而进行调试或性能优化
- 安全加载:通过Verifier验证器和其他安全检查,以及helper API的能力限制,实现安全的加载到内核
- 功能直达:绕过内核中非必要的子系统,直接进行数据包的处理和转发
- 特点
- 事件驱动:类似JavaScript
- bpf_helpers:eBPF 程序不能调用任意的内核参数,只限于内核模块中列出的 BPF Helper API函数
- 有界循环:eBPF 程序中循环次数限制且必须在有限时间内结束,防止系统运行出现死锁
- 一旦进入内核,eBPF便拥有了上帝视角,既可以监控内核,也可以管窥用户态程序。并且eBPF技术提供的一系列工具(Verifier)可以检测eBPF的代码安全,避免恶意程序进入到内核态中执行。
- eBPF的组成
- 用户态程序:负责加载 BPF 字节码至内核,如需要也会负责读取内核回传的统计信息或者事件详情
- 内核态BPF字节码程序: 负责在内核中执行特定事件,如需要也会将执行的结果通过 maps 或者 perf-event 事件发送至用户空间
- 其中用户空间程序与内核 BPF 字节码程序可以使用
map 结构
实现双向通信
- eBPF的执行流程
- 用户态
- 编译:使用 LLVM 或 GCC 工具将编写的
eBPF 程序
编译成eBPF 字节码
- 加载:调用 bpf()系统调用把 eBPF 字节码加载到内核。
- 编译:使用 LLVM 或 GCC 工具将编写的
- 内核态
- Verfier验证与JIT编译:内核使用
验证器
验证字节码安全性,通过JIT(Just In Time)将 eBPF 字节码编译成机器码(Native Code) - Kernel Helper API:内核会根据eBPF功能将机器码挂载到内核对应的Hook,当运行到某个Hook就会执行对应的eBPF程序
- Verfier验证与JIT编译:内核使用
- 用户态
- eBPF中用户态与内核态的通信方式
- maps方式:将
数据
存储在内核键值对
数据结构中,数据由内核eBPF字节码程序更新,并共享给用户态程序进行周期性查询 - perf-event方式:可用于捕获内核中的多种
软硬件事件
,并将这些事件实时
发送给用户空间程序
- maps方式:将
- eBPF应用实践
- cilium: 将eBPF技术应用于Kubernetes中,提供高性能网络和安全功能。
- Falco: 基于eBPF技术的云原生安全运行时,用于在Kubernetes环境中检测威胁。
- Katran: 使用eBPF实现的高性能四层负载均衡器,用于处理网络流量。
- pixie: 一种可观察性工具,使用eBPF技术提供对Kubernetes应用程序的详细监控和调试能力。
eBPF特性
- eBPF中的Hook
- 定义:hook是指内核中特定函数(事件)的发生,包括系统调用、函数进入/退出、网络事件等
- 原理:
- tracepoint机制:基于
内核标记点tracepoint
来追踪内核中的特定事件 - kprobes机制:可以在
内核函数的入口或出口
处插入Hook - uprobes机制:可以在
用户空间函数的入口或出口
处插入Hook
- tracepoint机制:基于
- eBPF的Verification
- 过程:每一个 eBPF 程序加载到内核前,都要经过 Verification来保证 eBPF 程序的安全性
- 加载对象:除非节点开启了
unpriviledged 特性
,否则只有高特权级的程序
才能够加载 eBPF 程序