基于eBPF技术的开源项目Kindling之探针架构介绍

网络工
• 阅读 1437

Kindling开源项目是一款基于eBPF技术的云原生可观测性项目。本文将主要介绍探针的具体架构设计。

Kindling探针的架构设计理念

Kindling架构设计中有一个很重要的理念:关注点分离(Separation of Concerns)。eBPF技术或者内核模块是一种内核技术,需要的背景知识是C语言和操作系统知识。而可观测开发者关注的是要输出什么样的指标,同时因为平时使用Go、Java这一类语言较多,对C也比较生疏,所以我们的设计是基于两层的分层领域。下层是eBPF的开发能力,主要是为事件透出服务;上层是可观测性需求开发,主要是为数据分析和指标产生服务,同时可以方便扩展可观测场景化需求。
基于eBPF技术的开源项目Kindling之探针架构介绍
另外一个重要的理念是:不重复造轮子,我们目标是把eBPF的能力以简单的方式透出给用户使用。所以kindling的设计是以falcosecurity-libs为基础的。目前这个开源项目承担的主要职责就是系统调用的事件透出,对于可观测方面的能力需要进一步扩展。但是它有一个优势是它会将原始内核数据和cgroup信息进行关联,方便后续将数据关联到k8s相关的resources, 同时falcosecurity-libs也对原始数据做了预处理,比如将网络数据进行更丰富的关联,让用户能够直接拿到某个对fd操作的网络事件属于哪个四元组的信息,所以我们复用了这部分能力。但falcosecurity-libs本身并不支持kprobe、uprobe等能力,kindling目前已经对其扩展了kprobe能力,后续也会持续不断的扩展uprobe等能力,同时还会集成其他开源工具的数据能力。
一般来说,eBPF探针主要由两部分程序组成:内核态程序用作采集数据以及用户态程序用作分析数据。但基于以上两个理念,我们的架构并不是传统的两部分。我们基于关注点分离理念,为了让cloud-native领域的开发者能够更方便的使用eBPF的能力,把原来falcosecurity-libs的C/C++用户态程序拆分成了一个Go程序和一个C/C++程序,让用户能更关注自己擅长的领域。
基于eBPF技术的开源项目Kindling之探针架构介绍

Kindling探针架构介绍

Kindling探针整体包含三个部分:用户态Go程序、用户态C/C++程序和内核态drivers程序。用户态Go程序满足的是上层可观测需求的开发,其他两个部分实现的是内核需求的开发。这样不同领域的人可以用自己擅长的语言开发自己关注的内容,同时探针也有较好的松耦合特性。Kindling具体组件描述如下:
基于eBPF技术的开源项目Kindling之探针架构介绍

内核态程序:drivers

为了更好的支持低版本内核的可观测能力,kindling的探针使用内核模块的形式支持低版本内核,所以drivers又分为eBPF probe以及内核模块。drivers主要负责采集内核事件,将事件放入由直接内存映射技术创建的数据结构,供用户态程序获取并处理。在事件采集这一层后续会持续将其他开源工具集成进来,比如BCC、bpftrace。

用户态C/C++程序:kindling-probe

kindling-probe是一个由C/C++语言编写的程序,运行时以一个单独的container运行在pod中,其主要的职责是负责和内核态程序进行交互并将内核事件暴露给上层处理程序。目前负责的工作主要有三个部分:

  • 负责调用bpf API加载eBPF内核态的字节码或者安装低版本内核的内核模块
  • 负责从mmap映射出来的ringbuffer结构中读取内核产生的原始事件并对原始事件进行预处理,最后转换为标准事件格式发送给kindling-collector
  • 负责提供动态配置通道,例如可以通过配置实现内核数据过滤,减少原始数据量以及无关数据

用户态Go程序:kindling-collector

用户态Go程序是一个可扩展模块,用户可以订阅自己关注的内核事件,基于自己的使用场景扩展自己的分析程序。目前kindling实现的分析程序被称为kindling-collector,它在运行时也是以一个单独的container运行在pod中,其主要职责是负责获取事件并进行分析,并对数据进行label的丰富。kindling-collector部分模块集成了opentelemetry的SDK,这样kindling的指标在输出时有较高的灵活性,可以输出到opentelemetry collector 、prometheus 、kindling标准版后端等多种可观测性平台。目前kindling-collector订阅的事件只是probe暴露出来的部分事件,主要是以系统调用以及kprobe为主,具体订阅信息如下:
subscribe:

    - name: syscall_exit-writev
      category: net
    - name: syscall_exit-readv
      category: net
    - name: syscall_exit-write
      category: net
    - name: syscall_exit-read
      category: net
    - name: syscall_exit-sendto
      category: net
    - name: syscall_exit-recvfrom
      category: net
    - name: syscall_exit-sendmsg
      category: net
    - name: syscall_exit-recvmsg
      category: net
    - name: kprobe-tcp_close
    - name: kprobe-tcp_rcv_established
    - name: kprobe-tcp_drop
    - name: kprobe-tcp_retransmit_skb

程序间通信方式

drivers和kindling-probe程序之间通信方式

eBPF程序采用BPF MAP 数据结构通信;内核模块采用mmap构造的ringbuffer进行通信。下图是eBPF程序使用的架构模型,为了兼容4.X内核,BPFMAP结构使用的是BPF_MAP_TYPE_PERF_EVENT_ARRAY,每个cpu都有相应的一个perf-event的map,在kindling-probe层会对事件进行排序组合。
基于eBPF技术的开源项目Kindling之探针架构介绍

kindling-probe和kindling-collector之间通信方式

这个过程使用了unix domain socket,它是一种IPC方式,虽然使用了socket,但是由于数据不需要经过网络协议栈,所以有比较好的传输性能。目前probe暴露的kindling event会进行序列化发送给unix domain socket,collector会从socket中读取数据并进行反序列化,然后得到标准化事件进行分析。

Kindling通信标准化事件格式

正如不同微服务间的通信大多都基于一份RESTful的HTTP接口定义,kindling在分层后也需要一种标准化的事件格式来屏蔽不同领域的实现细节,目前kindling设计的事件格式被称为kindling-event。Kindling-event是kindling-probe程序暴露出来的内核事件,底层eBPF程序会遵循kindling-event的标准格式暴露数据,这样上层应用也能基于标准去分析事件。具体的kindling event的结构如下:
message KindlingEvent {
Source source = 1;
// Timestamp in nanoseconds at which the event were collected.
uint64 timestamp = 2;
// Name of Kindling Event
string name = 3;
// Category of Kindling Event, enum
Category category = 4;
// Native attributes of hook point, including arguments or return value.
Property Native_attributes = 5;
// User-defined Attributions of Kindling Event, now including latency for syscall.
repeated KeyValue user_attributes = 6;
// Context includes Thread information and Fd information.
Context ctx = 7;
}

对Kindling感兴趣或者在云可观测性方面有问题的小伙伴欢迎与我们联系:

联系我们
基于eBPF技术的开源项目Kindling之探针架构介绍

关注我们
基于eBPF技术的开源项目Kindling之探针架构介绍

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Peter20 Peter20
4年前
mysql中like用法
like的通配符有两种%(百分号):代表零个、一个或者多个字符。\(下划线):代表一个数字或者字符。1\.name以"李"开头wherenamelike'李%'2\.name中包含"云",“云”可以在任何位置wherenamelike'%云%'3\.第二个和第三个字符是0的值wheresalarylike'\00%'4\
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
4年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Stella981 Stella981
4年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这