eBPF 示例教程 0:核心概念与工具简介
这是一个全面的 eBPF 开发教程的第一部分,旨在通过实用的 eBPF 开发指导您从初学者到高级用户。它涵盖了基本概念、实际代码示例以及在现代系统中的应用。我们将不再专注于传统工具如 BCC,而是使用现代框架如 libbpf
、Cilium
、libbpf-rs
和 eunomia-bpf,并提供 C
、Go
和 Rust
的示例。
本教程的主要目标是提供清晰简洁的 eBPF 工具示例(起步只需 20 行代码!),帮助开发者快速掌握基本的 eBPF 开发技术。每个示例都是独立的,可以在目录结构中找到,每个目录代表一个独立的 eBPF 工具。您还可以访问我们的教程代码仓库 https://github.com/eunomia-bpf/bpf-developer-tutorial 或网站 https://eunomia.dev/tutorials/ 获取更多示例和完整的教程源代码。
eBPF 简介:安全高效的内核扩展
eBPF(扩展的 Berkeley Packet Filter)是一项突破性的技术,允许开发者在内核空间中安全高效地运行小型程序。与传统方法需要修改内核源代码或加载新模块不同,eBPF 使得动态定制和优化网络行为成为可能,且不会中断系统操作。这种灵活性和高效性使 eBPF 成为克服传统网络栈限制的关键技术。
eBPF 的强大之处是什么?
- 直接内核交互:eBPF 程序在内核中执行,与系统级事件如网络包、系统调用或追踪点交互。
- 安全执行:eBPF 通过验证器在程序运行前检查其逻辑,防止潜在的内核崩溃或安全漏洞。
- 最低开销:eBPF 通过使用即时编译器(JIT),将 eBPF 字节码转换为针对特定架构的优化机器码,实现近原生执行速度。
eBPF:过去、现在与未来
过去:可编程网络的变革
eBPF 于 2014 年推出,彻底改变了开发者处理网络的方式,允许小型可编程内核空间应用程序实时处理数据包。通过钩住关键内核点,eBPF 使得在网络包到达时应用自定义逻辑成为可能,从而提高了效率和灵活性。这使得组织能够在不需要自定义驱动程序或修改内核的情况下定制网络行为,为云原生和数据中心环境创造了理想的解决方案。
现在:满足现代计算需求的多功能框架
eBPF 已发展为一个多功能框架,超越了其最初的网络用途,现在涵盖了可观测性、追踪、安全性,甚至系统资源管理。eBPF 程序可以动态钩住内核事件,赋予开发者精确控制系统行为和性能优化的能力,而无需修改内核或重启系统。这使得 eBPF 成为系统管理员和开发者监控、优化和保护环境的必备工具。
以下是 eBPF 目前广泛应用的一些关键领域:
-
网络:eBPF 提供内核中实时、高速的数据包过滤和处理,允许创建自定义协议解析器和网络策略,无需新驱动程序或系统重启。这在云和数据中心环境中实现了高效的网络管理。
-
可观测性:eBPF 使开发者能够通过收集自定义指标和执行内核级数据聚合来深入了解系统行为。通过利用内核追踪点和函数调用,eBPF 有助于识别性能问题和定位难以发现的错误。
-
追踪与分析:eBPF 提供强大的追踪和分析能力,通过附加到内核函数、追踪点甚至用户空间探针,使开发者能够深入了解系统和应用程序的行为,从而优化性能和解决复杂的系统问题。
-
安全:eBPF 在实时安全监控中发挥重要作用。它能够深入检查系统调用、网络流量和其他内核活动,帮助执行动态安全策略和检测异常行为,为基础设施提供高效的保护。
-
调度器优化:eBPF 越来越多地用于增强 CPU 调度,能够监控 CPU 负载并优化任务在核心之间的分配。这可以更有效地利用 CPU 资源,提高系统响应能力。
-
HID(人机接口设备)驱动增强:开发者使用 eBPF 优化键盘、鼠标和触摸屏等设备的 HID 驱动程序。通过为处理输入事件添加自定义逻辑,eBPF 提高了对延迟敏感应用的响应速度。
各行业组织已大规模采用 eBPF:
- Google:使用 eBPF 进行安全审计、数据包处理、实时性能监控以及优化其庞大基础设施的 CPU 调度。
- Netflix:利用 eBPF 进行网络流量分析,确保流媒体服务的高可用性和性能。
- Android:应用 eBPF 优化网络使用、功耗和资源分配,提升数百万设备的性能和电池寿命。
- S&P Global:通过 Cilium 使用 eBPF 管理跨多个云和本地系统的网络,确保可扩展性和安全性。
- Shopify:与 Falco 一起实施 eBPF 进行入侵检测,增强其电子商务平台的安全性。
- Cloudflare:使用 eBPF 进行网络可观测性、安全监控和性能优化,保护全球数百万网站。
eBPF 能够动态调整系统行为并扩展到用户空间,使其成为现代计算不可或缺的技术。无论是优化网络流量、提升安全性,还是增强系统性能,eBPF 都能帮助开发者高效、安全地应对实时需求。
除了其内核模式运行时,eBPF 还可以扩展到用户空间。例如,bpftime 是一个用户空间 eBPF 运行时,允许在用户空间应用中进行高性能追踪、性能分析和插件支持。这种 eBPF 向用户空间的扩展有助于在各种超越内核级任务的用例中提高灵活性和性能。
未来:eBPF 的扩展潜力
展望未来,预计 eBPF 将成为操作系统更为重要的一部分。重点将放在提升其灵活性、模块化和易用性上,使其能够应用于更广泛的场景。内存管理、并发机制的创新以及与用户空间应用的更好集成已在路上。已经有项目在编译 Linux 内核的关键部分到 BPF 指令集,这可能彻底改变内核开发和分析的方式。
动态栈、更好的用户空间可观测性工具(例如快速 Uprobes 和特定语言的栈行走器)以及更安全的程序终止机制等进展将继续增强 eBPF 的可靠性并扩展其使用场景。此外,新工具和库将简化 eBPF 开发,降低内核和应用开发者的入门门槛。
开始学习教程
本教程提供实用的 eBPF 开发实践,涵盖从初级到高级的主题。我们专注于在可观测性、网络和安全等领域的动手示例,使用 libbpf
、libbpf-rs
和 eunomia-bpf
等框架,并提供 C、Go 和 Rust 的示例。
本教程适合谁?
- 开发者 希望实现自定义内核解决方案。
- 系统管理员 旨在提升性能和安全性。
- 技术爱好者 探索前沿的内核技术。
你将学到什么?
- 核心概念:eBPF 基础知识及其与 Linux 内核的集成。
- 实用技能:编写和部署 eBPF 程序。
- 高级主题:探索 eBPF 在安全、追踪和未来创新方面的应用。
目录
-
eBPF 简介
基本概念和入门所需的工具。 -
初学者示例
简单的程序,如“Hello World”及使用 kprobe 和 uprobe 进行基础追踪。 -
可观测性
侧重于使用 eBPF 监控网络流量、文件操作和进程行为的示例。 -
网络
侧重于修改和优化网络流量的示例,如 XDP、TC 和 socket。 -
安全
用于隐藏进程和文件、发送信号杀死进程以及跟踪进程事件以增强安全性的程序。 -
高级用例
涉及性能分析、调度器优化和用户空间 eBPF(如 bpftime)的复杂示例。 -
深入主题
探索 eBPF 在 Android 上的应用、使用 eBPF 进行网络加速以及通过系统调用修改来保护系统。
如何使用 eBPF 编程
从头编写 eBPF 程序可能较为复杂。为简化这一过程,LLVM 于 2015 年引入了将高级语言代码编译为 eBPF 字节码的能力。自那时起,eBPF 社区构建了像 libbpf
这样的库来管理这些程序。这些库帮助将 eBPF 字节码加载到内核中并执行基本任务。Linux 内核源代码中 samples/bpf/
目录包含了众多 eBPF 示例。
典型的 eBPF 程序包含两个部分:内核空间代码(*_kern.c
)和用户空间代码(*_user.c
)。内核空间代码定义逻辑,而用户空间代码负责加载和与内核交互。然而,像 libbpf-bootstrap
和 Go eBPF 库这样的工具简化了这一过程,允许一次性编译和更容易的开发。
eBPF 开发工具
- BCC:一个基于 Python 的工具链,简化了 eBPF 程序的编写、编译和加载。它提供了许多预构建的追踪工具,但在依赖和兼容性方面存在一些限制。
- eBPF Go 库:一个 Go 库,解耦了获取 eBPF 字节码的过程与加载和管理 eBPF 程序的过程。
- libbpf-bootstrap:基于
libbpf
的现代脚手架,提供了高效的工作流用于编写 eBPF 程序,提供简单的一次性编译过程以生成可重用的字节码。 - eunomia-bpf:一个用于编写仅包含内核空间代码的 eBPF 程序的工具链。它通过动态加载 eBPF 程序简化了 eBPF 程序的开发。
这些工具有助于减少开发 eBPF 程序的复杂性,使开发者更容易优化系统性能、安全性和可观测性。
学习 eBPF 开发的一些技巧
本文不会提供更详细的 eBPF 原理介绍,但以下是一个学习计划和参考资料,可能对您有帮助:
eBPF 简介(5-7 小时)
- 使用 Google 或其他搜索引擎搜索:eBPF
- 询问类似 ChatGPT 的工具:什么是 eBPF?
推荐:
- 阅读 eBPF 介绍:https://ebpf.io/(30 分钟)
- 简要了解 eBPF 内核相关文档:https://docs.ebpf.io/(了解技术细节的查询来源,30 分钟)
回答三个问题:
- 了解 eBPF 是什么?我们为什么需要它?难道不能使用内核模块吗?
- 它有哪些功能?它在 Linux 内核中能做什么?eBPF 程序和助手函数有哪些类型(不需要全部了解,但需要知道在哪里查找)?
- 它能用于哪些场景?例如,可以在哪些情况下使用?网络、安全、可观测性?
理解如何开发 eBPF 程序(10-15 小时)
了解并尝试 eBPF 开发框架:
- bpftrace 教程:https://eunomia.dev/tutorials/bpftrace-tutorial/(尝试,1 小时)
- 使用 BCC 开发各种工具的示例:https://github.com/iovisor/bcc/blob/master/docs/tutorial_bcc_python_developer.md(运行,3-4 小时)
- libbpf 的一些示例:https://github.com/libbpf/libbpf-bootstrap(运行任何有趣的示例并阅读源代码,2 小时)
- 教程:https://github.com/eunomia-bpf/bpf-developer-tutorial(阅读第 1-10 部分,3-4 小时)
其他开发框架:Go 或 Rust 语言,请自行搜索和尝试(0-2 小时)
如果有问题或想了解的内容,无论是否与本项目相关,都可以在该项目的讨论区开始讨论。
回答一些问题并尝试一些实验(2-5 小时):
- 如何开发最简单的 eBPF 程序?
- 如何使用 eBPF 追踪内核功能或函数?有很多方法,提供相应的代码示例;
- 用户模式和内核模式之间的通信解决方案有哪些?如何将信息从用户模式发送到内核模式?如何将信息从内核模式传递到用户模式?提供代码示例;
- 编写您自己的 eBPF 程序以实现某个功能;
- 在 eBPF 程序的整个生命周期中,用户模式和内核模式分别做了什么?
参考资料
- eBPF 介绍:https://ebpf.io/
- BPF 编译器集合(BCC):https://github.com/iovisor/bcc
- eunomia-bpf:https://github.com/eunomia-bpf/eunomia-bpf
您还可以访问我们的教程代码仓库 https://github.com/eunomia-bpf/bpf-developer-tutorial 或网站 https://eunomia.dev/tutorials/ 获取更多示例和完整的教程源代码。所有内容均为开源。我们将继续分享更多关于 eBPF 开发实践的内容,帮助您更好地理解和掌握 eBPF 技术。