eBPF技术介绍

news/2024/10/20 16:00:46/

前言

eBPF起源于linux内核,它可以以砂箱程序运行在操作系统内核的特权上下文,高效,安全,易于扩展而不需要修改内核源码或者加载内核模块。

操作系统一直是实现观测,安全和网络功能的最理想的地方,因为内核的特权可以查看和控制整个系统。同时,一个操作系统的内核也是很难进化的,因为核心处理的角色,稳定性和安全方面都是高需求的。所以相对于应用而言,操作系统级的创新是很难的。

而eBPF改变了这一情况。通过允许在操作系统中运行沙盒程序,应用程序开发人员可以运行eBPF程序,在运行时为操作系统添加额外的功能。然后,操作系统保证了安全性和执行效率,就好像是在实时(JIT)编译器和验证引擎的帮助下进行本机编译一样。这导致了一波基于eBPF的项目,涵盖了广泛的用例,包括下一代网络、可观察性和安全功能。

 如今,eBPF被广泛用于驱动各种各样的用例:在现代数据中心和云原生环境中提供高性能网络和负载平衡,以低开销提取细粒度的安全可观测性数据,帮助应用程序开发人员跟踪应用程序,为性能故障排除提供见解,预防性应用程序和容器运行时安全强制,等等。可能性是无限的,eBPF正在解锁的创新才刚刚开始。

底层概念与架构

Hook概述

eBPF程序是事件驱动的,当内核或应用程序 通过某个挂接点 时 运行。

预定义的挂钩包括:系统调用函数进入/退出内核跟踪点网络事件其他一些。

 如果不存在用于特定需求的预定义挂钩,则可以创建内核探针(kprobe)或用户探针(uprobe),以将eBPF程序连接到内核或用户应用程序中的几乎任何位置。

eBPF程序是如何编写的?

在很多情况下,eBPF不是直接使用,而是通过项目( Cilium, bcc, or bpftrace)间接使用提供了在eBPF之上的抽象,不需要直接编写程序,而是提供了指定基于意图的定义的能力,然后使用eBPF实现这些定义。如果不存在更高级别的抽象,则需要直接编写程序。Linux 内核期望 eBPF 程序以字节码的形式加载。虽然当然可以直接编写字节码,但更常见的开发实践是利用编译器套件,例如LLVM将伪 C 代码编译为 eBPF 字节码。

当确定了所需的钩子后,可以使用 bpf 系统调用将 eBPF 程序加载到 Linux 内核中。这通常使用可用的 eBPF 库来完成。当程序加载到 Linux 内核中时,它会在附加到请求的钩子之前经过两个步骤:Verification和JIT

Verification:

是确保eBPF程序安全的关键环节,验证包括:

  • 加载 eBPF 程序的进程具有所需的功能(权限)。除非启用了非特权 eBPF,否则只有特权进程才能加载 eBPF 程序。
  • 该程序不会崩溃或以其他方式损坏系统。
  • 程序总是运行到完成(即程序不会永远处于循环中,从而阻止进一步的处理)。

JIT:

是确保程序性能的关键之一

即时 (JIT) 编译步骤将程序的通用字节码转换为特定于机器的指令集,以优化程序的执行速度。这使得 eBPF 程序的运行效率与本机编译的内核代码或作为内核模块加载的代码一样高效。

 Map:

eBPF 程序的一个重要方面是共享收集的信息和存储状态的能力。为此,eBPF程序可以利用eBPF映射的概念在广泛的数据结构中存储和检索数据。eBPF 映射可以从 eBPF 程序访问,也可以通过系统调用从用户空间中的应用程序访问。

以下是支持的映射类型的不完整列表,以便了解数据结构的多样性。对于各种映射类型,共享和每 CPU 变体都可用。

  • 哈希表、数组
  • LRU(最近最少使用)
  • 环形缓冲器
  • 堆栈跟踪
  • LPM(最长前缀匹配)
  • ...

Helper

eBPF 程序不能调用任意内核函数。允许这样做会将 eBPF 程序绑定到特定的内核版本,并使程序的兼容性复杂化。相反,eBPF 程序可以将函数调用到帮助程序函数中,这是内核提供的众所周知且稳定的 API。

可用的帮助程序调用集在不断发展。可用的帮助程序调用示例:

  • 生成随机数
  • 获取当前时间和日期
  • eBPF 地图访问
  • 获取进程/c组上下文
  • 操作网络数据包和转发逻辑

Tail & Function Calls

eBPF 程序可以用尾部和函数调用的概念组合。函数调用允许在 eBPF 程序中定义和调用函数。尾部调用可以调用和执行另一个 eBPF 程序并替换执行上下文,类似于 execve() 系统调用对常规进程的操作方式。

eBPF对Linux内核的影响

现在让我们回到eBPF。为了理解 eBPF 对 Linux 内核的可编程性影响,它有助于对 Linux 内核的架构以及它如何与应用程序和硬件交互有一个高层次的了解。

Linux 内核的主要目的是抽象硬件或虚拟硬件,并提供一致的 API(系统调用),允许应用程序运行和共享资源。为了实现这一目标,需要维护一组广泛的子系统和层来分配这些职责。每个子系统通常允许进行某种级别的配置,以满足用户的不同需求。如果无法配置所需的行为,则需要更改内核,从历史上看,留下两个选项:

 使用 eBPF,可以使用一个新选项,允许重新编程 Linux 内核的行为,而无需更改内核源代码或加载内核模块。在许多方面,这与JavaScript和其他脚本语言如何解锁系统的发展非常相似,这些系统已经变得难以改变或成本高昂。


http://www.ppmy.cn/news/53861.html

相关文章

带你了解vue3组合式api基本写法

本文的目的,是为了让已经有 Vue2 开发经验的 人 ,快速掌握 Vue3 的写法。 因此, 本篇假定你已经掌握 Vue 的核心内容 ,只为你介绍编写 Vue3 代码,需要了解的内容。 一、Vue3 里 script 的三种写法 首先,Vue…

Linux crontab计划任务和at一次性计划任务

文章目录 一、crontab常用命令二、计划任务书写格式例子:问题1:每月1,10,22号的4:45重启network服务问题2:每周六周日的1:10重启network服务问题3:每天18:00至23:00之间每隔30分钟重…

appuploader 常规使用登录方法

转载:登录appuploader 登录appuploader 常规使用登录方法 双击appuploader.exe 启动appuploader 点击底部的未登录,弹出登录框 在登录框内输入apple开发者账号 如果没有apple开发者账号,只是普通的apple账号,请勾选上未支付688…

基于JavaSpringboot+vue国风汉服文化交流宣传系统

基于JavaSpringbootvue国风汉服文化交流宣传系统 博主介绍:5年java开发经验,专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 文章目…

不停机修复mysql主从数据同步错误导致服务器磁盘占满问题

事情的现象: 线上生产环境mysql服务器采用主从结构。突然告警从库服务器磁盘占用高。经过磁盘空间检查,主要是/mysql/data目录使用100%(直接占满了),进入目录后发现被文件slave-relay-bin.*系列文件占满了。常理数据不…

React18开发总结(完善中)

遇到这样一个问题,初始化时用户登陆后需要获取到用户信息,但是发现获取用户信息这个接口触发了2次,这是不应该的,于是我查阅了一下资料,把自己的笔记记录下来。 还有就是使用mobx遇到的控制台警告问题,也一…

计算机组成原理---第 6 章总线系统

一、总线的概念和结构形态 总线的基本概念 ⑴概述 总线是构成计算机系统的互联机构,是多个系统功能部件之间进行数据传送的公共通路。 ⑵ 分类 总线的分类方式有很多:如被分为外部总线和内部总线、系统总线和非系统总线、片内总线和PCB板级总线、串行总…

【Unity3D插件】Embedded Browser嵌入式浏览器插件使用教程

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 好久没有介绍插件了,今天分享一款比较好用的嵌入式…