【2023周报】week23 eBPF学习

news2024/11/27 18:00:32

week23

eBPF学习

如何调试eBPF程序?

bpf SystemCall

[bpf(2) - Linux manual page (man7.org)](https://man7.org/linux/man-pages/man2/bpf.2.html)

[bpf-helpers(7) - Linux manual page (man7.org)](https://man7.org/linux/man-pages/man7/bpf-helpers.7.html)

用户态eBPF程序与内核交互的唯一路径是bpf系统调用:

#include <linux/bpf.h>

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

BPF 系统调用接受三个参数:

  • cmd ,代表操作命令,比如BPF_PROG_LOAD就是加载eBPF程序.
  • attr,代表 bpf_attr 类型的 eBPF 属性指针,不同类型的操作命令需要传入不同的属性参数.
  • size ,代表属性的大小。

bpf系统调用看似简单,但是包括了bpf的所有功能。在内核5.15中,第一个参数cmd支持37个宏定义命令([bpf.h - include/uapi/linux/bpf.h - Linux source code (v5.15) - Bootlin](https://elixir.bootlin.com/linux/v5.15/source/include/uapi/linux/bpf.h#L838)),包括map的创建、增删改查;加载eBPF程序。。。

在内核文档中的示例:

int bpf_prog_load(enum bpf_prog_type type,
                  const struct bpf_insn *insns, int insn_cnt,
                  const char *license) {
  union bpf_attr attr = {
    .prog_type = type,
    .insns = ptr_to_u64(insns),
    .insn_cnt = insn_cnt,
    .license = ptr_to_u64(license),
    .log_buf = ptr_to_u64(bpf_log_buf),
    .log_size = LOG_BUF_SIZE,
    .log_level = 1,
  };

  return bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
}

//---------------
int
  bpf_create_map(enum bpf_map_type map_type,
                 unsigned int key_size,
                 unsigned int value_size,
                 unsigned int max_entries)
{
  union bpf_attr attr = {.map_type = map_type,
                         .key_size = key_size,
                         .value_size = value_size,
                         .max_entries = max_entries};

  return bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
}

可以看出,bpf程序在用户空间使用的bpf_prog_load(),bpf_create_map()都是bpf()系统调用的封装。

strace追踪bpf系统调用

strace常用来跟踪进程执行时的系统调用和接收所接收的信号。strace可以跟踪到一个进程产生的系统调用,包括 参数,返回值,执行消耗的时间。

通过参数-ebpf,能够过滤出bpf系统调用:

tzx@tzx:~/ebpf_monitor/libbpf/src$ sudo strace -ebpf ./network_monitor 
...
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=2, insns=0xfffff5ee6d18, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(0, 0, 0), prog_flags=0, prog_name="", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS, prog_btf_fd=0, func_info_rec_size=0, func_info=NULL, func_info_cnt=0, line_info_rec_size=0, line_info=NULL, line_info_cnt=0, attach_btf_id=0, attach_prog_fd=0}, 116) = 8
...
bpf(BPF_BTF_LOAD, {btf="\237\353\1\0\30\0\0\0\0\0\0\0\20\0\0\0\20\0\0\0\5\0\0\0\1\0\0\0\0\0\0\1"..., btf_log_buf=NULL, btf_size=45, btf_log_size=0, btf_log_level=0}, 32) = 8
...
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_RINGBUF, key_size=0, value_size=0, max_entries=4096, map_flags=0, inner_map_fd=0, map_name="ringbuf", map_ifindex=0, btf_fd=8, btf_key_type_id=0, btf_value_type_id=0, btf_vmlinux_value_type_id=0, map_extra=0}, 72) = 9
libbpf: map 'ringbuf': created successfully, fd=9
...
load success.
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=9, info_len=88 => 80, info=0xfffff5ee6fd0}}, 16) = 0
^Cstrace: Process 31846 detached

利用strace追踪bpf系统调用,能够捕获到被追踪的eBPF程序进行了哪些bpf系统调用,还能看到具体的参数值以及返回值(文件描述符,可以用于上下文分析)。

bpftool

bpftool是一个用于操作和调试 BPF 程序的命令行工具。它可以用于列出、加载、卸载和查询 BPF 程序、映射和事件等。其源码位于内核源码中:[bpftool « bpf « tools - kernel/git/bpf/bpf-next.git - BPF next kernel tree](https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/tools/bpf/bpftool)

常用的 bpftool 命令:

  • bpftool prog show:列出所有 BPF 程序
  • bpftool map show:列出所有 BPF map
  • bpftool event show:列出所有 BPF 事件
  • bpftool prog load:加载一个 BPF 程序
  • bpftool prog unload:卸载一个 BPF 程序

在调试 BPF 程序时:

  • bpftool prog dump type <prog_type>:显示指定类型的所有 BPF 程序的汇编代码
  • bpftool prog tracelog <prog_id>:跟踪指定的 BPF 程序的执行并显示其输出
  • bpftool map dump id <map_id>:显示指定map的内容,以json格式输出
  • bpftool map update name <map_name> key 0xc1 0xc2 value 0xa1 0xa2:直接操作map

Kindling学习

[Kindling - eBPF-based Cloud Native Monitoring tool (harmonycloud.cn)](http://kindling.harmonycloud.cn/)

[网易伏羲私有云基于eBPF的云原生网络可观测性探索与实践_开源_石钟浩_InfoQ精选文章](https://www.infoq.cn/article/2U1Hj6PwavlgjAsEdSCU)

近期在思考eBPF性能监控程序的开发的架构问题:

  • 如何选择合适的eBPF程序开发框架
  • 如何屏蔽其他组件对系统性能的影响

遂阅读了国内互联网公司对eBPF在APM方面的应用。“kindling是一款基于 eBPF 的云原生可观测性开源工具,旨在帮助用户更好、更快地定界(triage)云原生系统故障。通过 kindling,用户可以快速定界问题类型,比如是应用代码问题还是基础设施问题。如果是代码问题,可以借助 APM(Application Performance Monitoring 应用性能监控)监控进一步排查问题;如果是基础设施问题,那么通过分析来自内核的相关监控指标,定位故障点。”

博客(发布日期2023-03-14)以及官方文档中展示的kindling架构:

在这里插入图片描述

img

通过架构图,可以得出:

  • 与eBPF核心无关的用户态程序由Golang开发。
  • eBPF核心程序使用C/C++进行开发。
  • 在node中所做的工作仅为监控事件数据的采集、解析,最后将数据投递到可观测分析平台。
  • 可观测分析平台作为一个独立的组件,数据到达的第一站为Data Receiver,后面流向Kafka、Analyzer、ES…等组件,最后由web前端进行展示。

通过阅读源码以及文档,学习真实项目中如何写eBPF程序:

  • eBPF开发库选型

    • [website/content/en/blogs/development/ebpf-library/index.md at cd681ab70628f51bd150c382959030d726e2e30f · KindlingProject/website (github.com)](https://github.com/KindlingProject/website/blob/cd681ab70628f51bd150c382959030d726e2e30f/content/en/blogs/development/ebpf-library/index.md)
    • 文章发布于2022.11,当时有几种选择:再创造一个eBPF的基础设施;libbcc;cilium-ebpf(纯Golang实现);Falco-libs(纯c语言的实现)…
    • 为何选择Falco-libs?:低内核版本支持;事件信息丰富(自动补全事件分类、上下文、线程名称)。
    • 做出了哪些改造:支持了kprobe。
    • 未来:随着内核版本3.x的逐渐淘汰,有理由选择更优的libbcc;cilium-ebpf。
  • drivers程序源码阅读:

    • [agent-libs/driver at kindling-dev · KindlingProject/agent-libs (github.com)](https://github.com/KindlingProject/agent-libs/tree/kindling-dev/driver)

    • forked from [falcosecurity/libs](https://github.com/falcosecurity/libs)

    • driver/bpf/maps.h文件中,定义了全局所有的map,包括perf_mapcpu_records等等。

    • perf_map的提交操作被封装在了driver/bpf/ring_helpers.hpush_evt_frame函数中

      //https://github.com/KindlingProject/agent-libs/blob/e6f73c5fa3e37073cf811a42782cc40591a422f6/driver/bpf/maps.h#L24
      struct bpf_map_def __bpf_section("maps") perf_map = {
      	.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
      	.key_size = sizeof(u32),
      	.value_size = sizeof(u32),
      	.max_entries = 0,
      };
      
      //https://github.com/KindlingProject/agent-libs/blob/e6f73c5fa3e37073cf811a42782cc40591a422f6/driver/bpf/ring_helpers.h#L45C6-L45C6
      static __always_inline int push_evt_frame(void *ctx,
      					  struct filler_data *data)
      {
      ...
      	int res = bpf_perf_event_output(ctx,
      					&perf_map,
      					BPF_F_CURRENT_CPU,
      					data->buf,
      					((data->state->tail_ctx.len - 1) & SCRATCH_SIZE_MAX) + 1);//perf_map的唯一操作
      ...
      	if (res == -ENOENT || res == -EOPNOTSUPP) {
      ...
      		bpf_printk("detected hotplug event, cpu=%d\n", state->hotplug_cpu);
      	}
      ...
      	return PPM_SUCCESS;
      }
      //https://github.com/KindlingProject/agent-libs/blob/e6f73c5fa3e37073cf811a42782cc40591a422f6/driver/bpf/fillers.h#L5185C37-L5185C37
      static __always_inline int bpf_cpu_analysis(void *ctx, u32 tid)
      {
          struct filler_data data;
          int res;
          res = init_filler_data(ctx, &data, false);
      ...
          if (res == PPM_SUCCESS)
              res = push_evt_frame(ctx, &data);//在逻辑函数中调用push_event
      ...
          return 0;
      }
      
    • 通过map的梳理,能够看出:1. 整个内核态的eBPF程序较为复杂,所有组件协作对外提供一套完整的功能。2.各模块有较为独立的封装,除了map模块,还有filler等一系列功能模块。

总结:

  • why eBPF?
    • “The libpcap way of analyzing the flows in the Kubernetes environment is too expensive for the CPU and network. The eBPF way of data capture cost much less than libpcap. eBPF is the most popular technology to track the Linux kernel where the virtual network, built by veth-pair and iptables, works. So eBPF is a proper technique to be used for tracking how the kernel responds to application requests.”
    • 性能损耗、流行性(生态好)、对Linux Kernel network模块契合度高…
  • 管理、处理数据的用户态程序使用Golang是最优解。
    • docker、k8s均使用Golang开发,契合云原生环境。
    • 用户态Go程序满足的是上层可观测需求的开发,其他两个部分实现的是内核需求的开发。这样不同领域的人可以用自己擅长的语言开发自己关注的内容,同时探针也有较好的松耦合特性。
  • 与eBPF核心相关的程序还是需要用libbpf实现。
    • 内核是由C语言开发的,内核态的eBPF程序必须要用C实现。
    • BCC工具适合快速验证功能,其动态编译运行(运行时需要内核头文件、llvm)的特点不适合生产环境。
  • 自己如何开发具有完善功能的eBPF程序
    • 可行性验证使用BCC,bpftrace等工具,正式实现使用libbpf、ebpf-go等库。
    • 考虑内核态的程序的可维护性,需要将各功能抽象独立成独立的模块。
    • 掌握makefile的书写,如何编译ebpf程序。

后续在开发自己的ebpf程序时,需要注意以上问题。

uapi

[uapi - include/uapi - Linux source code (v5.15) - Bootlin](https://elixir.bootlin.com/linux/v5.15/source/include/uapi)

在Linux内核中,userspace api是一组函数和系统调用,用于在用户空间(userspace)和内核空间(kernelspace)之间进行通信。通过这些api,用户空间的程序可以请求内核执行某些操作,例如读取或写入文件、创建或删除进程等。

内核源码中的/include/uapi/路径下。当内核被编译时,uapi头文件会被放置在/usr/include目录或其他指定的目录中,以便用户空间程序可以包含它们。

例如,编写一个C程序来使用open()和read()系统调用,可以包含以下头文件:

#include <fcntl.h>
#include <unistd.h>

这些头文件实际上是从内核源代码中的uapi目录中提取出来的。在编译时,编译器将查找这些头文件,并将它们包含在最终的可执行文件中。
在这里插入图片描述

通过diff命令比较/usr/src/linux-headers-5.15.0-76/include/uapi/linux/bpf.h&/usr/include/linux/bpf.h可以看出,两头文件除了开头结尾的预防式声明宏定义不同,其他都一样。而后者就是在编写eBPF程序时使用的<linux/bpf.h>头文件。

通过查阅资料,uapi路径是linux Kernel3.7中引入的:一个是解决 Linux Kernel 里的交叉引用;另外一个就是方便用户态的开发者,可以简单的查看 uapi 里的代码变化来确定 Linux Kernel 是否改变了系统 API。

在BCC中,有很多地方引入了uapi路径下的头文件:

在这里插入图片描述

由BCC的安装、使用指南可知,BCC的运行依赖于内核头文件。

# BCC官方文档中展示如何安装bcc工具
sudo apt-get install bpfcc-tools linux-headers-$(uname -r)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/793689.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python基本语法之符号使用

好久没有和小伙伴们更新python了&#xff0c;我对于此感到抱歉以后有时间尽量多更新 目录 一. 标识符 A.定义&#xff1a; B.使用特点 C.Python标识符&#xff0c;进一步探讨以下几个方面的详细内容&#xff1a; 1. 规则和约定&#xff1a; 2. 有效的标识符示例&#xff1…

【LeetCode每日一题】——剑指 Offer II 027.回文链表

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【题目进阶】八【题目注意】九【解题思路】十【时间频度】十一【代码实现】十二【提交结果】 一【题目类别】 栈 二【题目难度】 简单 三【题目编号】 剑指 Offer II 02…

3.1flex布局

参考链接 MDN 核心组成 容器 容器指定元素item的布局方式 元素 元素自定义自身的宽度大小

高数笔记02:导数、微分、中值定理

图源&#xff1a;文心一言 本文是我学习高等数学第二、三章导数、微分、中值定理的一些笔记和心得&#xff0c;希望可以与考研路上的小伙伴一起努力上岸~~&#x1f95d;&#x1f95d; 第1版&#xff1a;查资料、画导图、归纳题型~&#x1f9e9;&#x1f9e9; 参考用书1&…

Tomcat修改端口号

网上的教程都比较老&#xff0c;今天用tomcat9.0记录一下 conf文件夹下server.xml文件 刚开始改了打红叉的地方&#xff0c;发现没用&#xff0c;改了上面那行

SpringBoot整合第三方 Druid、MybatisPlus、Mybatis

整合第三方技术 整合JUnit Respostory 注解&#xff1a;数据类 1、导入测试对应的starter 2、测试类使用 SpringBootTest 修饰 3、使用自动装配的形式添加要测试的对象 classes的属性 其实主要找的是SpringBootApplication中的SpringBootConfiguration这个注解。也就是配置…

【Axure高保真原型】标准金额格式输入框

今天和大家分享标准金额格式输入框的原型模板&#xff0c;在输入框里输入数字后&#xff0c;会自动将对应的数字转为标准金额格式输入&#xff0c;自动添加千分位&#xff0c;例如输入2000&#xff0c;输入内容为2,000.00。具体效果可以观看下方视频或者打开预览地址体验 【原…

三星发布新智能手表:旋转边框回归,Galaxy Watch6 系列震撼来袭

今晚&#xff0c;三星发布了最新的Galaxy Watch6系列智能手表&#xff0c;其中包括Galaxy Watch6和Watch6 Classic两款。Watch6 Classic再次引入了三星手表所独有的旋转边框特色。这两款手表提供多种尺寸和支持LTE的版本&#xff0c;同时还搭载了内置的eSIM模块&#xff0c;为用…

Cookie简介

Cookie使用场景 在接口测试过程中&#xff0c; 很多情况下&#xff0c;需要发送的请求附带cookies&#xff0c;才能返回正常的结果。所以在使用pythonrequests进行接口自动化测试也是同理&#xff0c; 需要在构造接口测试用例时加入cookie。 传递Cookie的两种方式&#xff1a…

TortoiseSVN-1.14.5.29465-x64-svn-1.14.2的安装包以及汉化包

TortoiseSVN-1.14.5.29465-x64-svn-1.14.2的安装包以及汉化包 为了存一手这个安装包 CSDN资源地址&#xff0c;0积分 https://download.csdn.net/download/lu6545311/88085035 包内内容&#xff0c;一个安装包&#xff0c;一个汉化包 如果你想在你的编辑器&#xff0c;比如v…

Span-based Named Entity Recognitionby Generating and Compressing Information

原文链接&#xff1a;https://aclanthology.org/2023.eacl-main.146.pdf EACL 2023 介绍 对于information bottleneck (IB) principle信息瓶颈原理&#xff0c;要么使用生成模型&#xff0c;要么使用信息压缩模型来提高在目标任务上的性能&#xff0c;因此作者将这两种模型进行…

SpringMVC框架搭建

SpringMVC框架搭建 快速开启SpringMVC&#x1f680;&#x1f680; 步骤 1、新建模块 2、引入相关依赖 <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.1</version> &…

科大讯飞-旋转机械故障诊断挑战赛2023-测试【1】

引言 旋转机械故障诊断挑战赛是一项旨在提高旋转机械故障检测和识别能力的竞赛活动。旋转机械是工业生产中广泛应用的设备&#xff0c;其运行状态直接影响着生产效率和安全性。然而&#xff0c;由于各种原因&#xff0c;旋转机械可能会出现不同类型的故障&#xff0c;如轴承损坏…

玩转Python 秒懂python

解析器&#xff1a; 数据结构&#xff1a; 变量运算&#xff1a; 文件处理&#xff1a; 输入输出&#xff1a; 异常处理&#xff1a; 函数模块&#xff1a; 面向对象&#xff1a; 多线程&#xff1a; 三方库&#xff1a;

菜鸡shader:L13 渐隐渐显的UV动画

文章目录 SD部分Shader代码部分 呃呃&#xff0c;这是目前我学习庄懂AP01课程的最后一节了&#xff0c;我看了一下21集之后的内容是关于LightingMap&#xff0c;目前感觉还用不到&#xff0c;加上之前参与过一个项目里面也有用到LightingMap&#xff0c;也算了解过&#xff0c;…

多模态自监督学习 + 下游任务介绍

自监督学习 意义 经过海量无标签数据的学习后可以习得一个强大的特征提取器&#xff0c;在面对新的任务&#xff0c;尤其是医疗影像等小样本任务时,也能提取到较好的特征。 常见用途 相对位置预测:预测一张图像中随机选择的两个图像块之间的相对位置 图像修复:预测一张图像…

项目管理的最佳选择:最简单的项目管理系统

作为一名项目经理&#xff0c;你是否曾经或正面临过这些麻烦&#xff1a;你一上班就开始了解项目计划的完成情况和工作进展情况。在检查和填补工作空白的同时&#xff0c;你必须面对各种报告和清单。仅仅找到各种材料和文件就需要很多时间。不仅如此&#xff0c;我们还需要出身…

git拉取项目报错:fatal: remote error: Service not enabled

一般是git地址错误&#xff0c;如果是原本就有的项目&#xff0c;看看是不是代码库移动到其他地方了&#xff0c;这个库已经被删除了

辐射定标高精度积分球均匀光源

近一二十年&#xff0c;在环境科学、太阳物理、大气物理、气候学及气象学等研究的推动下&#xff0c;高精度太阳/大气定量光谱遥感技术发展十分迅速。空间定量光谱遥感数据的获取精度很大程度上取决于遥感仪器的定标精度。所谓遥感仪器定标&#xff0c;即指建立仪器输出电信号与…

ADS仿真低噪声放大器学习笔记

ADS仿真低噪声放大器 设计要求&#xff1a; 工作频率&#xff1a;2.4~2.5GHz ISM频段 噪声系数&#xff1a;NF < 0.7 增益&#xff1a;Gain > 15 输入驻波输出驻波&#xff1a;&#xff1c;1.5 这里重点是ADS操作流程 1. 安装晶体管的库文件 1、 下载ATF54143晶体管的…