您现在的位置是:首页 > 文章详情

BPF开发: 从Hello World开始

日期:2024-01-31点击:57

Part 1 概述

1. 背景

BPF技术被列为近些年Linux内核领域最火热的新领域之一。它成功的给Linux内核赋予了少量的动态可编程性,可以在Linux内核运行时,实时修改内核的行为,但不需要重新编译和重启内核。据此,BPF在Linux世界中:

  • 网络
  • 可观测性
  • 安全

三大领域大放异彩,学习好BPF技术,对于Linux内核和应用开发者来说,是一件非常有意义的事情。

2. 什么是BPF?

BPF在Linux内核中,被实现为一个非常精简的虚拟机,具有几乎性能无损的执行效率。我们可以用类似C语言的语法,编写代码,编译成可以在BPF虚拟机中运行的汇编代码,实现其强大的逻辑处理能力。

今天,我们将从 Hello World 开始,带您进入 BPF 的世界。

3. 开始BPF

按照计算机程序设计语言学习的传统,我们从经典的Hello World程序开始我们的eBPF开发之旅。首先简单对比下标准C程序和eBPF程序的异同。

C语言程序

# HelloWorld.c

#include <stdio.h>  int main() { printf("HelloWorld\n"); return 0; }

# C语言的编译与运行

eBPF程序

# HelloWorld.bpf.c

#include <linux/bpf.h> #include <bpf/bpf_helpers.h>  int helloworld(void *ctx) { bpf_printk("Hello world!\n"); return 0; }

# eBPF程序的编译与运行

eBPF的编译、加载、运行比标准C程序要麻烦一些。接下来会一步一步介绍全流程。

Part 2 开发环境

我们使用vagrant + virtualbox +Ubuntu22.04组建我们的开发环境。注意,只支持X86的CPU(Windows, Linux或Mac)。苹果M芯片不支持。

保存虚拟机描述文件Vagrantfile:

Vagrant.configure('2') do |config| config.vm.define 'bpf' do |bpf| bpf.vm.provider 'virtualbox' do |vb| vb.gui = false vb.memory = '4096' vb.cpus = 2 end bpf.vm.synced_folder '.', '/vagrant', disabled: true bpf.vm.box = 'bento/ubuntu-22.04' bpf.vm.network 'private_network', type: 'dhcp' bpf.vm.provision 'shell', inline: <<-SHELL set -x set -e apt-get install -y linux-tools-generic linux-tools-$(uname -r) gcc-multilib clang libbpf0 libbpf-dev SHELL end end

一些常用命令:

  • vagrant up: 启动虚拟机
  • vagrant halt: 关闭虚拟机电源
  • vagrant detroy: 销毁虚拟机
  • vagrant ssh: 登入虚拟机

Part 3 开始开发


以上文提到的HelloWorld.bpf.c为例子。

1. 编译eBPF

生成eBPF字节码,并带有调试信息:

clang -target bpf -Wall -O2 -g -c HelloWorld.bpf.c -o HelloWorld.o

查看eBPF编译后的字节码:

llvm-objdump -d -r -S --print-imm-hex HelloWorld.o
root@vagrant:~# llvm-objdump -d -r -S --print-imm-hex HelloWorld.o HelloWorld.o: file format elf64-bpf Disassembly of section .text: 0000000000000000 <helloworld>: ; { 0: b7 01 00 00 0a 00 00 00 r1 = 0xa ; bpf_printk("Hello world!\n"); 1: 6b 1a fc ff 00 00 00 00 *(u16*)(r10 - 0x4) = r1 2: b7 01 00 00 72 6c 64 21 r1 = 0x21646c72 3: 63 1a f8 ff 00 00 00 00 *(u32*)(r10 - 0x8) = r1 4: 18 01 00 00 48 65 6c 6c 00 00 00 00 6f 20 77 6f r1 = 0x6f77206f6c6c6548 ll 6: 7b 1a f0 ff 00 00 00 00 *(u64*)(r10 - 0x10) = r1 7: bf a1 00 00 00 00 00 00 r1 = r10 8: 07 01 00 00 f0 ff ff ff r1 += -0x10 ; bpf_printk("Hello world!\n"); 9: b7 02 00 00 0e 00 00 00 r2 = 0xe 10: 85 00 00 00 06 00 00 00 call 0x6 ; return 0; 11: b7 00 00 00 00 00 00 00 r0 = 0x0 12: 95 00 00 00 00 00 00 00 exit

这一坨eBPF汇编代码,感兴趣的同学可以参考eBPF Instruction Set Specification, v1.0[link:https://docs.kernel.org/bpf/standardization/instruction-set.html]

2. 运行BPF

流程

Linux内核中支持eBPF的事件很多。挂载eBPF程序后,需要等待事件异步触发才能看到效果。

加载eBPF字节码

Linux内核官方工具bpftool帮我们封装了对eBPF字节码各种操作。本文我们用它来挂载和调试eBPF。

# 在内核生成eBPF文件结构

eBPF在Linux内核以特殊文件形式存在,如果进程退出了则会自动销毁。为了让eBPF程序独立于进程持久存在于Linux内核中,内核提供了bpf文件系统,可以把eBPF程序pin在其中。Ubuntu 22.04默认挂载了bpf文件系统,位于/sys/fs/bpf,可以直接使用。

现在的eBPF字节码只是一段单纯的代码,要把它传入内核,还需要指定该eBPF字节码的类型,可以通过bpftool feature列出内核支持的所有eBPF类型:

 ... Scanning eBPF program types... eBPF program_type socket_filter is available eBPF program_type kprobe is available eBPF program_type sched_cls is available eBPF program_type sched_act is available eBPF program_type tracepoint is available eBPF program_type xdp is available eBPF program_type perf_event is available eBPF program_type cgroup_skb is available eBPF program_type cgroup_sock is available eBPF program_type lwt_in is available eBPF program_type lwt_out is available ...

HelloWorld.bpf.c是一个"万能"的eBPF程序,因为它仅仅输出"HelloWorld",因此,它可以指定为任何eBPF程序类型,这里我们选用raw_tracepoint。

bpftool prog load HelloWorld.o /sys/fs/bpf/HelloWorld type raw_tracepoint

现在可以在/sys/fs/bpf/中看到:

root@vagrant:~# ls /sys/fs/bpf/HelloWorld /sys/fs/bpf/HelloWorld

或者:

root@vagrant:~# bpftool prog show pinned /sys/fs/bpf/HelloWorld 353: raw_tracepoint name helloworld tag fc3c56cde923df12 gpl loaded_at 2023-03-11T01:59:48+0000 uid 0 xlated 104B jited 71B memlock 4096B btf_id 118

这说明我们的eBPF程序已经成功加载到内核中。

#把内核中的eBPF程序挂载到事件上

正常情况下,我们会把eBPF挂载到特定事件上,然后等待事件异步触发时,再执行eBPF程序。

本文我们为了方便,选择最简单的,用于调试和测试用的接口:BPF_PROG_TEST_RUN,也叫BPF_PROG_RUN,

他们是完全等价的。这个接口可以直接同步执行eBPF程序,而不需要挂载到事件上再等待事件异步发生。

BPF_PROG_TEST_RUN只支持有限的eBPF程序类型:

BPF_PROG_TYPE_SOCKET_FILTER BPF_PROG_TYPE_SCHED_CLS BPF_PROG_TYPE_SCHED_ACT BPF_PROG_TYPE_XDP BPF_PROG_TYPE_SK_LOOKUP BPF_PROG_TYPE_CGROUP_SKB BPF_PROG_TYPE_LWT_IN BPF_PROG_TYPE_LWT_OUT BPF_PROG_TYPE_LWT_XMIT BPF_PROG_TYPE_LWT_SEG6LOCAL BPF_PROG_TYPE_FLOW_DISSECTOR BPF_PROG_TYPE_STRUCT_OPS BPF_PROG_TYPE_RAW_TRACEPOINT BPF_PROG_TYPE_SYSCALL

上文我们把eBPF字节码指定为raw_tracepoint,正好满足该接口的要求。

利用bpftool使用BPF_PROG_TEST_RUN接口来运行它(参数如何设置,之后会有专题分析,这里不要修改bpftool参数):

bpftool prog run pinned /sys/fs/bpf/HelloWorld repeat 0

查看输出结果:

root@vagrant:~# cat /sys/kernel/debug/tracing/trace # tracer: nop # # entries-in-buffer/entries-written: 1/1 #P:4 # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / _-=> migrate-disable # |||| / delay # TASK-PID CPU# ||||| TIMESTAMP FUNCTION # | | | ||||| | | bpftool-39498 [001] d.... 979047.864950: bpf_trace_printk: Hello world!

OK,我们现在成功的执行了第一个最简单的BPF程序。

Part 4 BPF in MatrixOne

MatrixOne作为我司主打数据库产品,未来在MatrixOne中将全面使用BPF技术,用于增强数据库集群的性能,稳定性和安全性。

网络

MatrixOne作为云原生数据库,运行在标准的Kubernetes集群中,网络是其最重要的基础设施之一。我们将利用BPF技术,减少Linux内核网络协议栈的开销,实现MatrixOne的网络性能优化。

可观测性

我们将在自带的可观测性组件中,利用BPF实时采集和分析数据库运行时的各种指标,用于自动化分析和故障诊断。同时,我们将提供一系列BPF工具,用于SRE人工分析和调优MatrixOne。

安全性

我们将在附属的安全组件中,提供基于BPF得关键操作监控和禁止操作,用于实时检测和防御数据库的安全威胁。

关于MatrixOne

MatrixOne 是一款基于云原生技术,可同时在公有云和私有云部署的多模数据库。该产品使用存算分离、读写分离、冷热分离的原创技术架构,能够在一套存储和计算系统下同时支持事务、分析、流、时序和向量等多种负载,并能够实时、按需的隔离或共享存储和计算资源。云原生数据库MatrixOne能够帮助用户大幅简化日益复杂的IT架构,提供极简、极灵活、高性价比和高性能的数据服务。

MatrixOne企业版和MatrixOne云服务自发布以来,已经在互联网、金融、能源、制造、教育、医疗等多个行业得到应用。得益于其独特的架构设计,用户可以降低多达70%的硬件和运维成本,增加3-5倍的开发效率,同时更加灵活的响应市场需求变化和更加高效的抓住创新机会。在相同硬件投入时,MatrixOne可获得数倍以上的性能提升。

MatrixOne秉持开源开放、生态共建的理念,核心代码全部开源,全面兼容MySQL协议,并与合作伙伴打造了多个端到端解决方案,大幅降低用户的迁移和使用成本,也帮助用户避免了供应商锁定风险。

关键词:超融合数据库、多模数据库、云原生数据库、国产数据库

MatrixOrigin 官网:新一代超融合异构开源数据库-矩阵起源(深圳)信息科技有限公司 MatrixOne

Github 仓库:GitHub - matrixorigin/matrixone: Hyperconverged cloud-edge native database

原文链接:https://my.oschina.net/u/5472636/blog/10994059
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章