观测云核心技术解密:eBPF Tracing 实现原理

2024-09-04 05:52

本文主要是介绍观测云核心技术解密:eBPF Tracing 实现原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

eBPF 是一种强大的内核技术,允许在内核中安全地执行自定义代码。通过 eBPF,开发者可以在不修改内核源码的情况下,对内核功能进行扩展和监控。eBPF Tracing 利用这一技术,对系统调用、内核函数等进行跟踪,从而实现对应用行为的深入洞察。

与传统的监控方式相比,eBPF Tracing 具有以下优势:

  • 无侵入性:无需修改应用代码即可进行监控。
  • 高性能:在内核层面执行,减少了对应用性能的影响。
  • 细粒度:可以精确到单个系统调用或内核函数的监控。

eBPF(网络)链路实现

实现由三部分构成:

  1. eBPF 探针程序
  2. 解析来自 BPF Map 的网络请求数据、线程(协程)跟踪与 eBPF Span 生成
  3. 链接来自所有节点的汇总 eBPF Span (以下简称 eSpan) 生成链路

eBPF 探针程序

eBPF 探针用于获取程序读写 socket fd 的网络数据,并通过 BPF Map 发送给用户空间的程序进行协议解析。

Linux syscall 函数触发时 eBPF 探针将读取 buf 参数的内容写入 BPF Map,参考 syscall 如下:

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
...

写入 BPF Map 的数据将记录触发的 syscall 函数及时间、TCP 连接信息、线程/协程信息以及 Linux syscall 的 buf 参数的部分 payload,以下为结构体:

struct network_data
{struct{__u64 ts;                        // 函数调用开始时间__u64 ts_tail;                   // 函数调用结束时间__u64 tid_utid;                  // 内核线程、用户线程 id__u8 comm[KERNEL_TASK_COMM_LEN]; // task commstruct{__u64 sk;      // sock addr__u32 ktime;   // kernel time__u32 prandom; // random number} uni_id;          // 该网络连接的唯一标识 idstruct{__be32 saddr[4]; // src(proc self) ip address; Use the last element to store the IPv4 address__be32 daddr[4]; // dst ip address__u16 sport;     // src(proc self) port__u16 dport;     // dst port__u32 pid;__u32 netns; // network namespace inode. (`stat -L /proc/<pid>/ns/net` or `lsns -t net`)__u32 meta;  // first byte: 0x0000|IPv4 or 0x0001|IPv6; second byte 0x0000|TCP or 0x0100|UDP; ...} conn;          // 连接信息__u32 tcp_seq;   // first byte tcp seq__u16 _pad0;   // 内存对齐填充__u16 func_id; // 函数编号__s32 fd;       // socket fd__s32 buf_len;  // 读写的网络数据字节数__s32 act_size; // 实际采集的 payload 的字节数__u32 index;    // 自增,用于标记进程对 socket fd 读写函数调用顺序} meta;                       // 网络数据 meta__u8 payload[L7_BUFFER_SIZE]; // 网络数据 payload
};

由第二部分的 Agent 实现 eBPF 探针程序的加载和卸载,工作示意图:

网络请求解析、线程跟踪与 eSpan 生成

DataKit-eBPF 程序从 BPF Map 获取网络数据,解析网络协议,根据进程和线程信息构建线程跟踪模型。

其构成主要包含:

  • 采集:
    收集来自 BPF Map 的网络数据等;加载 eBPF 探针程序,attach 到相应的 syscall 函数
  • 解析:
    • 建立进程的线程-网络请求时序模型,通过为应用内关联网络请求(IN/OUT)提供线程跟踪 ID 实现进程内跟踪;
    • 检测网络数据里的网络协议,识别到 HTTP、Redis、MySQL 等协议后进入解析模式,并进行网络协议/进程过滤等;
    • 解析网络协议,采集网络请求,生成请求数据,附加根据 TCP 序列号生成跨进程网络跟踪 ID、附加 Otel/DDTrace 等的链路传播信息(如果有);
  • 生成:
    向生成请求数据中注入线程跟踪 ID,进一步生成 eBPF Span 和生成网络请求聚合数据。
  • 发送:
    由于当前 eBPF Span 中没有建立跨进程调用的父子关系,需要将所有节点的 eSpan 发送至同一个用于 eSpan 链接的 DataKit 或 DataKit-ELinker 服务, 如图:

eSpan 链接

该部分接收来自所有节点的 eSpan 数据,用于建立这些来自多个节点的 eSpan 的跨进程应用调用关系,实现生成完整的链路。

其构成主要包含:

  • 接收 eSpan 并缓存 N 个链接周期(该周期可根据单次应用调用链路的总耗时调参)的 eSpan 数据
  • 按链接周期取数据,加工 eSpan,根据 eSpan 中的进程内跟踪 ID 和跨进程网络跟踪 ID 完成 eSpan 间的链接
  • 采样,该采样为尾部采样;同时,可根据 Otel/DDtrace 等通过网络传播的链路信息中的采样信息进行采样
  • 上传 eBPF 链路数据到观测云

实现效果

这篇关于观测云核心技术解密:eBPF Tracing 实现原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1135175

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Python实现精确小数计算的完全指南

《Python实现精确小数计算的完全指南》在金融计算、科学实验和工程领域,浮点数精度问题一直是开发者面临的重大挑战,本文将深入解析Python精确小数计算技术体系,感兴趣的小伙伴可以了解一下... 目录引言:小数精度问题的核心挑战一、浮点数精度问题分析1.1 浮点数精度陷阱1.2 浮点数误差来源二、基础解决

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

Java实现远程执行Shell指令

《Java实现远程执行Shell指令》文章介绍使用JSch在SpringBoot项目中实现远程Shell操作,涵盖环境配置、依赖引入及工具类编写,详解分号和双与号执行多指令的区别... 目录软硬件环境说明编写执行Shell指令的工具类总结jsch(Java Secure Channel)是SSH2的一个纯J