首页 > 其他分享 >什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术

什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术

时间:2022-12-26 12:36:12浏览次数:71  
标签:bpf eBPF 抖动 BPF 编译 内核 Coolbpf

近日,在 ​​2022 云栖大会龙蜥峰会 eBPF & Linux 稳定性专场​​上,来自 eBPF 技术探索 SIG Maintainer 的毛文安分享了《Coolbpf 的应用实践》技术演讲,以下为本次演讲内容:  


什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_重定位


一、为什么要支持可移植?



什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_加载_02



随着 BPF 技术的发展,开发一个 BPF 程序变得越来越简单,尽管 BPF 提升了便利性,但 BPF 也一直在追求另一个方面: 可移植性 。BPF 可移植性被定义为成功编写并通过内核验证的一个 BPF 程序,能运行在不同内核版本。



进行 BPF 的移植有两个挑战:

1. 不同内核版本数据的内存布局不同。



2. 内核类型和数据结构不断变化,结构体字段可能被移除或重命名。



BPF CO-RE (Compile Once - Run Everywhere) 是实现可移植性的一个手段。

为了支持 CORE,提供了以下组件:



  • BTF:描述内核镜像,获取内核及BPF程序类型和代码的关键信息
  • Clang 释放 bpf 程序重定位信息到.btf 段
  • Libbpf CO-RE 根据.btf 段重定位 bpf 程序



需要进行重定位的信息主要有三类:



1. 结构体相关重定位, 这部分和BTF息息相关。 Clang通过__builtin_preserve_access_index()记录成员偏移量。



2.  map fd 、全局变量(data、bss、rodata)、extern 的 变量重定位 ,主要依赖于 ELF 的重定位机制,来更新 eBPF 指令的 imm 字段。






3. 子函数重定位, 是为了将 eBPF 程序调用的子函数同主函数放在一起,便于一起加载到内核。



什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_头文件_03



使用 libbpf 进行 BPF CORE 的开发步骤如下:

1.   生成带所有内核类型的头文件 vmlinux.h,通过 bpftool 生成。



2.  使用 Clang (版本10 或更新版本) 将 BPF 程序的源代码编译为 .o 对象文件;



3.  从编译好的 BPF 对象文件中生成 BPF skeleton 头文件 bpftool gen 命令生成;



4. 在用户空间代码中包含生成的 BPF skeleton 头文件;



5. 编译用户空间代码,则嵌入 BPF 对象代码无需发布单独的文件。



大致有如下的函数调用:



<name>__open() : 创建并打开 BPF 应用,之后可以设置 skel->rodata 变量。



<name>__load() : 初始化,加载和校验 BPF 应用部分。



<name>__attach() : 附加所有可以自动附加的 BPF 程序。有事件和网络运行报文到达时,会触发运行 bpf 程序。



<name>__destroy(): 分离所有的 BPF 程序并使用其使用的所有资源。



什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_重定位_04



eBPF 程序的主要开发方式有三种,它们各有优缺点,见下:



1、内核自带示例代码: 基于内核 samples/bpf 示例代码,无 CORE。该方式没有任何基于第三方的开源项目,资源占用量低。但缺点是需要自己完全重新搭建工程,效率较低,且版本兼容性较差。



2、BPF CORE: 基于 libbpf 自己编写的 bpf_core_read 代码,开发机生成对应目标机的二进制程序。该方式不依赖在环境中部署 Clang/LLVM ,资源占用少。但是需要搭建编译工程,部分代码相对固定,无法动态配置。



3、BCC: 基于应用最广的开源项目,开发效率较高。但是每一次运行都要执行  Clang/LLVM 编译,存在内存、CPU 等资源的争抢;目标环境依赖对应内核头文件。



二、Coolbpf 的功能和架构



什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_头文件_05



Coolbpf 提供了远程编译 (云编译 )。其中 远程编译 指运行程序的目标机器与编译程序不在同一个机器上,能够解决资源占用问题;提供了本地编译和基础库封装,方便用户调用基础库进行编写;提供了低版本内核的支持;提供了 BTF 的自动生成和发布,用户无需手动适配,下载即可直接使用;提供了自动化测试以及支持 Python/Go/Rust 等高级语言进行应用开发。



Coolbpf 天然支持 BPF 的 CORE 能力,它解决了编译和资源消耗的问题,同时,前面介绍的复杂的 libbpf 开发步骤完全被简化了。用户只需要专注自己的功能开发,不用关注环境搭建和冗余代码开发。

什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_重定位_06


Coolbpf 提供了标准化的 bpf 编译服务 。首先将 bpf.c 提交到远程编译服务器时,服务器会根据的内核版本针对不同的语言返回点 bpf.so 或 bpf.o 为高级的应用程序提供服务。因此在你的高级语言代码中,只需加载 bpf.so 即可运行程序,无需再手动触发 Libbpf 的 open()、load()、attach()等函数,而是由高级语言程序的 init()自动完成,这样用户可以快速搭建和部署工程,只需专注于数据输出之后的处理。



什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_头文件_07






Coolbpf 还支持在没有 eBPF 特性的低内核版本上,通过我们提供的 eBPF 驱动,帮助它安全的在低版本上运行。我们将高版本上 eBPF verifier 校验部分实现在一个驱动里,它会进行各种安全校验,保证 eBPF 对比于内核模块的安全性。另外,我们把原来基于 libbpf 的调用都转换为 IOCTL 的系统调用。



之前支持的 helper 函数、创建 map 、加载 program 都会转化成低版本上的 kprobe  或 tracepoint 的实现,另外还支持 perf event 和 jit。这样就使得同一个用户程序,加载这样一个驱动,就能不修改 eBPF 程序代码而安全的运行在低版本内核上。



三、Coolbpf 的网络应用实践



什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_加载_08



Raptor 是基于 Coolbpf 的系统可观测工具,能够运行在低版本内核如 alios、CentOS 3.10 等。它可以作为一个 SDK,提供给第三方使用,进行数据采集。



什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_加载_09






在这个网络应用观测中,通过监控系统调用中的数据交互、请求和回复等信息,来确定交互的数据内容和五元组等信息,通过 map 的交互方式发送给用户态,做到了无侵入的方式做观测,最终呈现比如流量统计、请求时延等观测结果。



什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_加载_10

我们来看一个具体的问题,了解 Coolbpf 是如何发现收包阶段的网络抖动问题。我们知道网络收包分为两个阶段:



阶段 1: OS 通过软中断将数据包送到应用的收包队列并通知进程,完成协议栈的收包工作。



阶段 2: 应用得到通知后从收包队列取数据。



我们在 Coolbpf 里写一段 BPF 程序,只需监控两个 tracepoint:tcp_probe,tcp_rcv_space_adjust 就能查询到阶段 2 的延迟问题。



什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术_重定位_11



在这个案例中,某业务应用收包慢,发现内核侧已经收到了 tcp 包,但是应用侧将近 1s 后才收到。



观测方法: 部署 eBPF agent,发现阶段 2“收包延迟时间”将近 1 秒。



确定原因:每次发生延迟时间都在某时刻的大致 42 秒处,怀疑跟业务某定时任务相关造成应用自身延时,最终排查到业务有某个任务会定时收集 jvm 的参数,对该业务有 stop 的操作。

解决方法: 停掉该任务后,消除了抖动问题。

关于龙蜥峰会 eBPF & Linux 稳定性专场课件获取方式:


【PPT 课件获取】:关注微信公众号(OpenAnolis),回复“ 龙蜥课件 ” 即可获取。


【视频回放】:视频回放可前往龙蜥官网(或阅读原文直达)​https://openanolis.cn/video​ 查看。 


—— 完 ——



标签:bpf,eBPF,抖动,BPF,编译,内核,Coolbpf
From: https://blog.51cto.com/u_15308345/5968733

相关文章

  • 如何快速有效的定位应用抖动问题?| 龙蜥技术
    编者按:在服务器系统运行中,常见的问题包括服务器宕机、系统夯机、应用运行错误、性能抖动等,其中抖动问题是非常典型的容易出现且很难分析解决的问题。本文通过深入理解Linu......
  • 加载第三方编译安装库
    转:https://blog.csdn.net/oceanstudy123/article/details/121656238加载动态库,以下方法,一般用于处理cannotopensharedobjectfile:Nosuchfileordirectory。   ......
  • fatal error C1010: 在查找预编译头时遇到意外的文件结尾
    错误描述:fatalerrorC1010:在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include"stdafx.h"”?错误分析:    此错误发生的原因是编译器在寻找预......
  • 预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
    vs2010的mfc项目中编译c语言出现错误:"...预编译头文件来自编译器的早期版本,或者预编译头为C++而在C中使用它(或相反)" 解决方法:建工程时建立空项目 或者在项目......
  • 使用NDK编译 libyuv
    官方源码:http://code.google.com/p/libyuv/简介:libyuvisanopensourceprojectthatincludesYUVscalingandconversionfunctionality.ScaleYUVtoprepare......
  • 编译FFmpeg成一个SO库
    编译环境MacOSXCapitan10.11.3NDK-r10e(64-bit)FFmpeg3.0简介在看完了第一篇Android最简单的基于FFmpeg的例子(一)—编译FFmpeg类库的基础上再看这一篇,在......
  • 【踩坑】Debian编译安装Podman和Prometheus-podman-exporter
    这个月一直在折腾Grafana,中途遇到了各种各样的问题这两天折腾得差不多了,才有空把遇到的问题写出来一方面做个记录,另一方面也当给想要折腾的小伙伴们踩踩坑估计最近......
  • 源码编译安装httpd
     1.基础环境准备1.1创建一个系统用户 [root@node2~]#useradd-r-M-s/sbin/nologinapache [root@node2~]#idapache uid=299(apache)gid=299(apache)gro......
  • httpd编译安装
    httpd编译安装基础环境准备[root@liuquanyu~]#dnf-yinstallgccgcc-c++makewgetLastmetadataexpirationcheck:2:28:48agoonTue13Dec202206:32:26PM......
  • 配置编译BusyBox
    获取源码$wget-chttp://www.busybox.net/downloads/busybox-1.23.2.tar.bz2解压并进入源码目录$tar-jxvfbusybox-1.23.2.tar.bz2$cdbusybox-1.23.2/配置$makemen......