eBPF 虚拟机是如何工作的

简介: 【2月更文挑战第3天】

eBPF 是一个运行在内核中的虚拟机,很多人在初次接触它时,会把它跟系统虚拟化(比如 kvm)中的虚拟机弄混。其实,虽然都被称为“虚拟机”,系统虚拟化和 eBPF 虚拟机还是有着本质不同的。


系统虚拟化基于 x86 或 arm64 等通用指令集,这些指令集足以完成完整计算机的所有功能。而为了确保在内核中安全地执行,eBPF 只提供了非常有限的指令集。这些指令集可用于完成一部分内核的功能,但却远不足以模拟完整的计算机。为了更高效地与内核进行交互,eBPF 指令还有意采用了 C 调用约定,其提供的辅助函数可以在 C 语言中直接调用,极大地方便了 eBPF 程序的开发。


eBPF 在内核中的运行时主要由  5  个模块组成:

image.png

  • 第一个模块是  eBPF 辅助函数。它提供了一系列用于 eBPF 程序与内核其他模块进行交互的函数。这些函数并不是任意一个 eBPF 程序都可以调用的,具体可用的函数集由 BPF 程序类型决定。
  • 第二个模块是  eBPF 验证器。它用于确保 eBPF 程序的安全。验证器会将待执行的指令创建为一个有向无环图(DAG),确保程序中不包含不可达指令;接着再模拟指令的执行过程,确保不会执行无效指令。
  • 第三个模块是由  11 个 64 位寄存器、一个程序计数器和一个 512 字节的栈组成的存储模块。这个模块用于控制 eBPF 程序的执行。其中,R0 寄存器用于存储函数调用和 eBPF 程序的返回值,这意味着函数调用最多只能有一个返回值;R1-R5 寄存器用于函数调用的参数,因此函数调用的参数最多不能超过 5 个;而 R10 则是一个只读寄存器,用于从栈中读取数据。
  • 第四个模块是即时编译器,它将 eBPF 字节码编译成本地机器指令,以便更高效地在内核中执行。
  • 第五个模块是  BPF 映射(map),它用于提供大块的存储。这些存储可被用户空间程序用来进行访问,进而控制 eBPF 程序的运行状态。


eBPF 程序是什么时候执行的,查看到 BCC 的执行过程,首先,打开一个终端,执行下面的命令:

# -ebpf表示只跟踪bpf系统调用
sudo strace -v -f -ebpf ./hello.py

稍等一会,会看到如下的输出:

bpf(BPF_PROG_LOAD,
    {
        prog_type=BPF_PROG_TYPE_KPROBE,
        insn_cnt=13,
        insns=[
            {code=BPF_ALU64|BPF_K|BPF_MOV, dst_reg=BPF_REG_1, src_reg=BPF_REG_0, off=0, imm=0x21},
            {code=BPF_STX|BPF_H|BPF_MEM, dst_reg=BPF_REG_10, src_reg=BPF_REG_1, off=-4, imm=0},
            {code=BPF_ALU64|BPF_K|BPF_MOV, dst_reg=BPF_REG_1, src_reg=BPF_REG_0, off=0, imm=0x646c726f},
            {code=BPF_STX|BPF_W|BPF_MEM, dst_reg=BPF_REG_10, src_reg=BPF_REG_1, off=-8, imm=0},
            {code=BPF_LD|BPF_DW|BPF_IMM, dst_reg=BPF_REG_1, src_reg=BPF_REG_0, off=0, imm=0x6c6c6548},
            {code=BPF_LD|BPF_W|BPF_IMM, dst_reg=BPF_REG_0, src_reg=BPF_REG_0, off=0, imm=0x57202c6f},
            {code=BPF_STX|BPF_DW|BPF_MEM, dst_reg=BPF_REG_10, src_reg=BPF_REG_1, off=-16, imm=0},
            {code=BPF_ALU64|BPF_X|BPF_MOV, dst_reg=BPF_REG_1, src_reg=BPF_REG_10, off=0, imm=0},
            {code=BPF_ALU64|BPF_K|BPF_ADD, dst_reg=BPF_REG_1, src_reg=BPF_REG_0, off=0, imm=0xfffffff0},
            {code=BPF_ALU64|BPF_K|BPF_MOV, dst_reg=BPF_REG_2, src_reg=BPF_REG_0, off=0, imm=0xe},
            {code=BPF_JMP|BPF_K|BPF_CALL, dst_reg=BPF_REG_0, src_reg=BPF_REG_0, off=0, imm=0x6},
            {code=BPF_ALU64|BPF_K|BPF_MOV, dst_reg=BPF_REG_0, src_reg=BPF_REG_0, off=0, imm=0},
            {code=BPF_JMP|BPF_K|BPF_EXIT, dst_reg=BPF_REG_0, src_reg=BPF_REG_0, off=0, imm=0}
        ],
        prog_name="hello_world",
        ...
    },
    128) = 4

这些参数看起来很复杂,但实际上,如果查询  bpf 系统调用的格式(执行  man bpf 命令),就可以发现,它实际上只需要三个参数:

int bpf(int cmd, union bpf_attr *attr, unsigned int size);


对应前面的 strace 输出结果,这三个参数的具体含义如下。


第一个参数是  BPF_PROG_LOAD , 表示加载 BPF 程序。


第二个参数是  bpf_attr  类型的结构体,表示 BPF 程序的属性。其中,有几个需要你留意的参数,比如:

  • prog_type  表示 BPF 程序的类型,这儿是  BPF_PROG_TYPE_KPROBE ,跟我们 Python 代码中的  attach_kprobe  一致;
  • insn_cnt  (instructions count) 表示指令条数;
  • insns  (instructions) 包含了具体的每一条指令,这儿的 13 条指令跟我们前面  bpftool prog dump  的结果是一致的;
  • prog_name  则表示 BPF 程序的名字,即  hello_world 。


第三个参数 128 表示属性的大小。

相关文章
|
索引 存储 数据库
数据库设计规范
基于阿里数据库设计规范扩展而来
52220 4
|
网络协议 应用服务中间件 网络安全
|
安全 算法 网络安全
一篇文章让你彻底弄懂SSL/TLS协议
一篇文章让你彻底弄懂SSL/TLS协议
一篇文章让你彻底弄懂SSL/TLS协议
|
2月前
|
人工智能 安全
还在用 Codex 开xhigh 拉满跑?夯错了小老弟
Codex 的 `xhigh` 并非万能钥匙:它专为深度研究、安全审计等极难任务设计,耗时耗资高。日常开发用 `medium` 更稳,轻任务选 `low`,复杂逻辑才升 `high`。真正该拉满的,是人的判断力,而非模型推理档位。(239字)
还在用 Codex 开xhigh 拉满跑?夯错了小老弟
|
2月前
|
人工智能 弹性计算 Serverless
2026 年企业 AI Agent 落地:从 Demo 到生产的四个关键跨越
本文剖析AI Agent从Demo到生产落地的四大关键跨越:长时任务支持、多Agent协同、GPU弹性伸缩与全链路可观测性,并结合Google ADK、Anthropic MCP等新协议,给出务实解法与平台选型建议。
1703 0
|
6月前
|
Web App开发 人工智能 运维
怎么让Gemini操作Chrome浏览器,真相让老金无语。。。
接前两天的Gemini in Chrome文章。 Chrome现在内置了Gemini。 能当浏览器助手。 帮你整理网页信息。 还能用Nano Banana画图。
|
6月前
|
存储 弹性计算 缓存
阿里云服务器最便宜多少钱?轻量应用服务器38元,云服务器99元(附购买教程)
阿里云服务器受用户青睐,价格降低后更具吸引力,其中轻量应用服务器仅需38元/年,云服务器最低99元/年。38元轻量服务器配置为2核2G,适合个人建站;99元云服务器为经济型e实例,2核2G配置,适合个人开发者、初创企业、小型网站等;另有199元/年的通用算力型u1实例,适合中小型企业网站、中型Web应用等。用户可根据需求在阿里云活动页面选择并购买,享受稳定可靠的云服务。
|
iOS开发 MacOS Windows
硬盘变卡疑似坏道?教你快速检测坏道的方法
怎么判断是不是硬盘出了问题?有没有简单实用的方法来检测硬盘坏道?今天这篇文章就来教你几种快速检测坏道的方法,推荐几款靠谱工具,普通用户也能轻松上手。
|
人工智能 搜索推荐 数据可视化
Manus:或将成为AI Agent领域的标杆
随着人工智能技术的飞速发展,AI Agent(智能体)作为人工智能领域的重要分支,正逐渐从概念走向现实,并在各行各业展现出巨大的应用潜力。在众多AI Agent产品中,Manus以其独特的技术优势和市场表现,有望成为该领域的标杆。作为资深AI工程师,本文将深入探讨Manus的背景知识、主要业务场景、底层原理、功能的优缺点,并尝试使用Java搭建一个属于自己的Manus助手,以期为AI Agent技术的发展和应用提供参考。
13839 19
|
Linux 测试技术 数据库
解决django与sqlite3不兼容报SQLite 3.9.0 or later is required (found 3.8.2)错的问题
解决django与sqlite3不兼容报SQLite 3.9.0 or later is required (found 3.8.2)错的问题
999 2

热门文章

最新文章