#BPF

ebpf 采集ebpf 采集tag+tcp五元组

在这里对文章题目作一些说明。笔者想了很长时间也无法给这篇文章想个恰当的表意题目。实际上使用ebpf来进行服务观测是有在进行的,比如获取目前l1s上的常见的四元组。但是本文不是介绍这部分可观测实践的。文章希望阐述的场景是:采集请求触发里的一些信息(诸如trace及其他header等)并和服务请求下游的传输层五元组(protocol, src-ip, src-port, dst-ip, dst-port)进行关联。这也是最近工作中实际遇到的问题。

基于ebpf的丰富的特性能够获取服务很多的信息,不同特性的组合更是可以达到极强的数据整合能力。比如通过uprobe便捷的获取业务信息后,结合kprobe来获取系统调用里的内容,可以获取一般侵入式可观测代码无法获取的内容。笔者最近遇到的一个实际问题是:获取服务A的接口/a响应后,向下游B发起的请求时,所使用的传输层五元组,同时带上结合一些/a触发时的一些内容,比如caller_fun或者traceId
这里值得说明的是,用户态请求的是一个域名。域名的解析是在golanghttp里完成的。但是请注意,golang发起tcp请求时,local port设置的是0,然后由内核态的tpc处理来选择一个空闲的port作为socket里的lport。这部分的信息通过代码的埋点显然是无法获取的(详情可参考TCP连接中客户端的端口号是如何确定的?)。
下面介绍下实现效果及思路。

关于bpftrace使用的介绍,可以参见:bpftrace 无侵入遍历golang链表,关于ebpf来进行数据采集的实践,可以参见ebpf采集mysql请求信息及ebpf对应用安全的思考

·4min·李岩
ebpf 采集ebpf 采集tag+tcp五元组

ebpf采集mysql请求信息及ebpf对应用安全的思考

本文笔者继续介绍ebpf 的应用:使用bpftrace采集mysql连接信息,包括数据库地址、db_nameuser_name。在展示采集操作的同时,附上对ebpf对云时代应用安全的一些思考。

目标

使用bpftrace对一个运行中进程的mysql请求进行采集,目标采集内容包括数据库地址、db_nameuser_name

·4min·李岩
ebpf采集mysql请求信息及ebpf对应用安全的思考

bpftrace 无侵入遍历golang链表

bpftrace 基于 bcc 进行开发的工具,语法简洁、功能强大。用其分析Linux 环境下的程序会很方便。本文构造了一个入参为链表头节点的函数使用场景,通过使用bpftrace无侵入遍历链表成员的方式,介绍bpftrace attach uprobe 的使用。更多使用说明见:bpftrace官网使用文档

·2min·李岩
bpftrace 无侵入遍历golang链表

golang 常见类型字节数

ebpf 分析golang程序时,离不开对参数大小的判断。这里列出来一些基本类型的大小,并通过汇编对应验证函数的方式来肯定判断结果。

信息

这里列出基本类型及其作为参数传递时,占用的空间大小如下表。

类型长度说明
指针8B64位机为 8Byte, 32位机位4Byte
context16Binterface 类型。其中,前8B是类型信息,后8B是对象的指针信息
interface16B2 个指针,详见draveness-go-interface,或者 runtime/runtime2.go iface/eface 定义
int648B-
int8B64位机为 8Byte, 32位机位4Byte
string16B8B 地址 + 8B string长度
slice24B8B地址 + 8B slice 成员数量 + 8B slice capability
func8Bfunc 作为函数参数时,传递的是 func 的地址

需要注意的是,作为函数参数传递时,golang会对参数按照 8B 进行对齐。

·2min·李岩
golang 常见类型字节数