文章/eBPF技术探索SIG随着eBPF技术的广泛应用,在操作系统层面提供了更多的观察能力,在操作系统层面查看应用的行为数据Trace追踪成为了一种新的方式应用程序监控方法。本文主要介绍基于eBPF实现应用网络数据监控的背后逻辑。1.请求包的组成一个完整的应用程序请求包主要包括请求地址信息和具体的请求数据。其中,请求地址信息就是我们常说的五元组信息(IP+端口+协议),由操作系统协议栈负责解析;请求数据由应用程序通过各种协议进行封装和解析。常见的应用程序协议包括:http、mysql、rediis、dns等。应用程序每次请求数据的接收和发送都是通过网络相关的系统调用与操作系统进行交互。如果请求报文没有加密,那么很容易通过拦截系统调用,传递函数输入的方式获取应用协议数据。.目前流行的应用可观察性就是基于这种方法来追踪应用网络数据,包括:延迟、流量统计、协议等。2.基于系统调用的请求跟踪2.1网络请求模型基于系统调用的应用进程的网络请求模型如下(这里只介绍client):通过socket创建一个socket,获取一个fd作为socket标识。通过connect填写IP端口信息,发起连接请求。通过read/write请求/接收特定数据,除了read/write系统调用,send/recvfrom、readv/writev等都可以。通过关闭结束此请求。通过上面的流程图,我们大致了解了一个完整的网络请求的系统调用逻辑。有几点需要注意:对于单个建链请求,发送数据和接收数据往往是串行的,或者一个写必须匹配一个读,所以我们可以统计RT时间,以及读/写的次数返回的字节可以作为我们的流量统计。如何配对写/读,对于客户端来说,先写后读。通常的做法是使用进程pid和socketfd作为配对标识,实现本次write/read完整请求数据的配对。2.2系统调用跟踪eBPF技术可以在不改变内核源代码或加载内核模块的情况下,在内核中插入指定的钩子代码,并在内核或应用程序执行到特定的钩子点时执行。预定义的挂钩包括系统调用、函数退出/进入、内核跟踪点、网络事件等。有了eBPF作为系统调用的钩子,系统调用的事件收集对我们来说变得非常方便,但是需要注意哪些事件需要上报,以及请求数据上报后的匹配策略。同时,获取请求数据也有一些讲究。对于write发送的数据,在系统调用函数的入口直接获取入参即可获取数据,但是对于read的数据,我们需要在系统调用函数的出口做一个hook来获取.数据。上面说了pid+fd作为traceid作为请求的唯一标志。实现方法有两种:方法一:当有connect时,先在BPFmap中记录traceid,表示建立了新的请求,后续的读写请求数据都与此配对。但是在http长连接的场景下,连接发起可能在我们trace之前,所以只能通过netlink等其他方式获取链接信息。方法二:其实我们关心的只是读写请求数据,以及如何配对。是否可以仅根据fd获取连接信息?BPF程序可以得到当前进程的task_struct,根据fd可以得到对应的sock结构,sock结构中记录了请求地址信息。除了BPF框架的技术选型外,我们采用了Coolbpf开发。通过对libbpf的改进,在拥有核心特性的同时,提供了更加简洁的API接口。exporter程序可以直接加载so形式的代码。以上只是网络请求事件集合的最小单位。借助exporter的其他能力,可以获得更丰富的数据指标:错误数、延迟、进程级流量统计等。3、应用协议识别在系统只能识别4层网络协议调用级别,无法识别应用的7层协议。实际上,通过hook系统调用获取到buf参数后,处理的是buf的前几个字节。协议头分析,目前支持的协议有:http、mysql、kafak、dns、mongo、pgsql、dubbo。对于https等加密报文,可以通过uprobehookssl加密库,后续会支持这部分功能。4、部署我们在日常值班问题中也遇到了各种网络抖动延迟问题,所以我们将这部分功能放在SysOM智能诊断平台的agent中,可以通过容器一键部署,并查看对应的grafana中的延迟分布和具体的延迟请求信息。同时,我们与sls合作,将这部分内核的采集能力输出给了iLogtail。5.what'smore除了上面提到的基于系统调用的应用观察,对于应用因为自身原因收包慢,导致网络“假抖动”的情况,我们也基于Coolbpf做了相关的观察实践.一个完整的收包过程主要分为两个阶段:Stage1:OS通过软中断将数据包发送到应用程序收包队列,并通知进程协议栈的收包工作完成。Phase2:应用程序接到通知后,去接收队列取包。这两个阶段可以被认为是异步的。我们观察从数据包到达收包队列到应用程序取包完成的这段时间,作为应用程序的“收包延迟”。很大的帮助。案例1一个基于dubbo框架容器的业务应用在业务层收到之前延迟了将近1秒收到了tcp包。部署SysOMagent观察“数据包接收延迟时间”,发现“数据包接收延迟时间”接近1秒,右侧红色框部分为时间,单位为纳秒。结合左边的红框,每次在某个时间点的延迟时间是42秒。怀疑是和业务的某个定时任务有关,导致应用本身的延迟。最后发现业务的某个任务会被延迟。定期收集jvm的参数,对应用程序有停止动作。停止任务后,抖动问题消除。Case2业务高峰期,客户端rpc比服务端多20-30ms。业务监控如下:部署SysOMagent观察“收包延迟”,发现对应时间段有比较大的“收包延迟”。所以首先排除网络链路问题。红框部分是纳秒级的时间,图中的时间还需要加上8小时。根据时序对比,发现应用在这段时间在做GC,最终通过调整GC参数解决。6.总结以上是Coolbpf在可观察性方面的实践。相关功能集成在SysOMagent中,后续会推出更多应用观察功能。当应用日志无法解决问题或者没有日志时,利用eBPF技术在OS层面观察应用行为逻辑,对于定位一些应用的疑难问题有很大的帮助。参考链接:eBPF介绍链接地址:https://www.rutron.net/posts/...coolbpfgitee代码仓库链接地址:https://gitee.com/anolis/cool...kernel文档链接地址:https://www.kernel.org/doc/ht...龙蜥实验室coolbpf链接地址:https://lab.openanolis.cn/#/a...——完——
