#BPF
golang常见类型作为参数的eBPF解析
即将过去的2022年,笔者相当比例的精力都投入在了eBPF上。最初的时候,写了一篇golang 常见类型字节数 ,开启了
eBPF+golang的总结性工作。此后陆续整理了一些关于ebpf的使用文章,同时项目也在逐步的推进。eBPF的实际落地有很大的挑战,但是最终还是找到了一些落地的场景。年底了,结合最近的调研工作,笔者整理了这篇文章。既算是对之前文章的呼应,也是对今年整理内容的总结。
eBPF能够提供一种切入服务细节的独特视角。本文即通过实例,对golang常见类型作为函数参数时进行解析,期望读者能够感受这一视角。需要说明的是,本文是基于golang-1.16来整理的。
基于ebpf实现的gls
虽然
golang并不推荐使用goid来构建gls(goroutine local storage),仍然有着很多的实现gls并使用的尝试。github-gls这里是一个常见的实现,基本表述了golang里gls的实现思路:获取goid,基于goid构建一个存储。本文中笔者尝试基于ebpf来构建一个golang的gls。
基本功能
本文中基于ebpf实现的gls具有如下功能:
- 基于
goid的存储。即map[goid]=value; - 基于
goroutine派生关系设置的value缺省值。即map[goid=1]=121,且goid=1派生goid=2,则map[goid=2]=map[goid=1]=121;
本文建议参照黑魔法-ebpf-对用户空间数据的写入进行理解。
黑魔法--用 ebpf 构建用户空间数据的桥梁
在之前的示例中,仅涉及到ebpf对用户空间数据的读取。工程性较强的如:ebpf采集mysql请求信息及ebpf对应用安全的思考也仅是通过urpobe采集用户空间的数据。本文介绍点ebpf的“黑魔法”:将用户空间数据的读取、用户空间数据的写入结合起来,成为用户空间数据交互的桥梁。
BPF 获取 LVS FullNat 模式下的 Client IP
搞项目。
观测服务的请求调用需求是客观存在的。一般是需要观测服务的主动发起的调用信息,但是偶尔也会遇到需要观测服务被调用信息的需求。但是一般待采集的服务都是挂载在LVS下面的。这就势必涉及到LVS预设的工作模式下,一般都是FULLNET,需要的real client ip的信息获取方式。
笔者通过调研,实现了一种通过BPF来观测挂载在LVS下的RS被调用TCP连接信息的方式。本文中关于toa的操作及代码定义均引用自Huawei/TCP_option_address。
eBPF tail-calls示例
最近在整理一些技术文章。本来希望把涉及ELF的内容整理出来,结果发现太难了。ELF涉及的内容要多很多,如果要把希望整理的内容表述清楚,还需要做一些准备的工作。刚好最近完成了tail-calls 的调研,先把关于eBPF的tail-calls的功能整理下吧。
eBPF程序是事件驱动的,这就意味着当目标事件触发后,程序才能执行。考虑这样一个场景:有几个不同的BPF程序均挂载在相同的hook点上,而执行需要保持一定的顺序。这时就需要借助tail calls的功能来实现。