写点什么

滴滴是如何落地 eBPF 技术的?

作者:滴滴技术
  • 2023-07-25
    北京
  • 本文字数:4360 字

    阅读完需:约 14 分钟

滴滴是如何落地eBPF技术的?

导读

eBPF 是 Linux 内核革命性技术,能够安全高效地扩展内核能力,应用广泛,尤其是在云原生可观测性领域的应用已经成为行业热点。在滴滴云原生环境中,eBPF 技术进行了业务实践和内源共建,HuaTuo eBPF 平台快速落地并取得初步收益,目前已经支持云原生关键组件,诸如服务访问关系拓扑、容器安全、宿主机安全、网络诊断、根因定位等业务,HuaTuo 也是滴滴开源委员会的精品孵化项目。希望本文为业界开发者提供一种如何将 eBPF 技术快速应用到云原生场景的落地方式,共同提升云原生系统深度可观测性。

BPF 技术的前世

Berkeley Packet Filter BPF 伯克利报文过滤器,最初构想提出于 1993 年,Steven McCanne 和 Van Jacobson 的论文《The BSD packet filter: a new architecture for user-level packet capture》。其目标提供一种新的高效过滤网络报文的方法。最初 BPF 只附着在 Linux 内核网络套接字上,当套接字绑定 BPF 字节码后,每接收一次报文都会执行该字节。内核根据 BPF 字节码返回值决定是否允许网络报文通过。



从指令集角度,BPF 起初的架构比较简单,只有一个 32 位宽度累加器 A,一个 32 位宽度寄存器 X,以及 16x32bit 数组内存空间。但 BPF 实现了加载、存储、跳转、运算四类指令。BPF 起初还没有即时编译器 JIT,所有这些指令完全在内核小巧的虚拟机中运行,即便如此性能已经完全碾压其他报文过滤器。



BPF 使用起来也比较方便,我们可以通过 tcpdump、libpcap 或者 bpf_asm 生成 BPF 字节码,通过 setsockopt SO_ATTACH_FILTER 加载到内核。如下所示实现 ICMP 报文过滤,只需要根据 L2/L3 报文头漂移量判断协议号是否符合条件。



BPF 最先在 sk_filter 落地使用,后续在 netfilter、seccomp、team 驱动等网络子系统都有应用,但应用方向依旧在网络报文处理。



BPF 技术的今生

BPF 最核心的思想实现了内核可编程,即在不改动源码,重新编译内核的情况下,实现高效扩展内核能力。2013 年,Alexei Starovoitov 对 BPF 进行改造,增加新特性,改善其性能。BPF 的进一步发展,为内核带来了巨大的改变,使内核具备了更加强大、可编程的动态变化的能力。这种能力在各种需要定制化的应用场景中,将发挥巨大的价值,既可以用于扩展功能,也可以用于优化性能。新版本被命名为 eBPF (“extended BPF”),以前的 BPF 变成 cBPF(“classic” BPF),后续篇章中 BPF 特指该项技术。

首先指令集角度,eBPF 是一种精简指令集,支持 R0-R9 10 个 64bit 通用寄存器。其中 R0 寄存器用于内核函数的返回值,R1-R5 寄存器用于内核函数的参数传递,这和 x86_64、aarch64 类似。eBPF 支持两种指令集编码格式,64 位宽度的基础编码,128 位宽度的宽指令编码(该指令编码在基础编码之后附加 64 位立即数实现)。此外,eBPF 也丰富了四类指令集。




Just In Time,  JIT 编译器,BPF 指令会被内核的 JIT 编译器动态编译为物理机原生指令,实现运行效率的“零”损耗。该特性在 cBPF 时期由 Eric Dumazet 实现,只支持 x86-64 架构。eBPF 根据自身指令特点再次扩展该编译器,eBPF 指令不仅仅可以 JIT 成物理机 CPU 原生指令,同时可以翻译成一些设备如某些智能网卡的特定指令。这样诸如智能网卡的设备可以通过 eBPF 的方式实现可编程。

除了对指令层面丰富和扩展,eBPF 也增加了基于键值对的数据存储机制,可用于实现内核用户态的数据存储和交换。eBPF 新增比较丰富的 BPF Helper 函数,这使 BPF 程序可以访问内核功能,扩展 BPF 能力,同时保持 BPF 程序和内核的安全隔离。 

随着 BPF 功能增强,该技术不再局限于在内核网络子系统,也逐步应用于动态追踪、事件检测、性能分析优化、IO 子系统、进程调度、文件子系统等等。应用场景也从具体的点扩展到面:可观测性、Tracing、安全、性能分析和根因分析等等。同时也涌现出大批优秀的开源项目如 Bcc、Cilium、bpftrace、Falco、Katran、Pixie。



滴滴生产环境的业务痛点

在数据中心有很多基础服务,这些服务在稳定性、生产效能、可扩展性、安全等发挥着重要作用,这些基础设施在实际落地时都面临着不同程度的挑战。

流量回放测试

云原生的规模越来越大,承载的业务种类,业务流量和规模也都在急剧地扩大,软件测试也面临极大的挑战,包括测试环境搭建和测试用例的编写和维护等。流量回放测试是一种全新的测试方法。通过在线下测试环境进行回放,实现回归测试,流量回放能够完整的复现线上复杂的业务访问场景,极大地提高项目迭代效率、加速业务回归测试进度,保证业务研发质量提升。项目面临的挑战:

  • 业务编程语言繁多,基础库种类版本繁多。

  • 业务网络模型不统一(php 单进程处理,golang 协程处理,其他编程语言多线程/进程)。

  • 对特定业务定制化,难以提升覆盖度,并且成本较高。

  • 业务有感,在稳定性上较难保障。 

服务访问拓扑

随着微服务架构的兴起,服务数量日渐增多,服务之间的依赖关系变得越来越复杂。服务链路的可观测性对业务稳定性保障有很重要的意义。它能够清晰地展示服务接口之间的访问关系,以及诸如性能、延迟、超时等业务指标。线上出现问题的时候,依据服务拓扑关系能够快速地定位问题节点。项目面临的挑战:

  • 业务种类量大,人工梳理成本高易出错。

  • 通过推广特定 SDK 依靠 metric 以及日志中服务调用关系进行串联的方式推动难度大,在生产环境中容易出现断链的情况。 

容器安全

在云原生的大势所趋下,越来越多的企业选择拥抱云原生,容器已经成为应用交付的标准,也是云原生时代计算资源和配套设施的交付单元。容器的使用日益普及,容器安全问题日益凸显。滴滴针对容器安全有一套完整的方案,其中一些核心的痛点就通过 eBPF 技术解决。 

内核根因定位

滴滴云原生平台的容器部署密度、超卖比都较高,在共享内核容器虚拟化场景下容易出现资源不合理使用导致的问题。传统的内核指标偏向于基本、整体、粗粒度层面的统计检测,同时传统的定位工具资源消耗较多,性能影响较大。因此彻底确定内核根因,需要对内核子系统进行深度观测,以及实现常态化观测,解决事中事后出现的突发、超时、毛刺等棘手问题。

滴滴 HuaTuo eBPF 平台实践

eBPF 技术能够很好的解决上述出现的语言依赖痛点,同时 eBPF 和动态追踪技术结合对实现深度观测内核提供支撑。但实际落地过程中需要回答如下问题:

  • 在需求多的情况下,如何快速的满足这些需求,提升研发效能快速落地?

  • 目前行业中虽有落地案例,但规模相对较小,如何实现从点到面的落地,如何保证宿主机稳定性?

  • 如何统一观测和保障插桩点性能损耗,出现问题如何快速回退、降级、止损? 

平台建设

基于如上考虑我们研发了 eBPF 平台,业务可以直接使用平台提供的通用能力,只需要关注自身逻辑实现即可。平台建设过程中重点围绕着提升研发效能,提供业务视角,保障稳定性和保障性能等维度。

  • 提升研发效能

早期用户需要关心如何解析 BPF 字节码,如何加载到内核,创建 KV Map 以及将特定的 Section 代码附着到特定的运行节点。最后用户还需要关注如何从内核获取数据。平台重要的功能是将底层的技术细节屏蔽,类似的上述功能只需要调用 bpfload 和 bpfmap 接口即可。

  • 提供业务视角

业务和平台,业务和业务之间的发布规律不同。最终我们采用 BPF Obj 字节码的方式将业务的逻辑和平台解耦,业务根据需求调用平台接口即可。同时平台需要考虑标准化,支持其他开源组件定义的 SEC,这样就能够兼容已有的 BPF 字节码,直接在平台运行。



  • 保障稳定性

作为新的技术落地,需要重点关注宿主稳定性问题。稳定的保障主要从内核层,框架侧,以及和业务感知的方面建立。



  • 保障性能

所有的 BPF 代码都是运行在内核态,因此过多的耗时依然会对系统造成影响。事件驱动,共享内存,ringbuf 生产消费等方式在该平台都有应用。



平台组成

  • BPF 字节码管理

首先是解析 ELF 能力,包括 SEC、Map、变量、结构体的定义。通过 SEC 能够清楚 BPF Prog 类型以及可以自动加载的 Hook 附着点等。通过 Map 的定义解析出其类型,大小,Key 类型,Value 类型等信息。

  • 高性能数据处理

平台支持业务类型较多,因此需要从各个维度考虑性能保障。首先在内核侧对 probe hook 点动态评测,提供熔断机制。在平台侧提供高性能数据通信,ringbuf 生产消费方式减低延迟。

  • 稳定性管理

平台设计初衷是解决线上问题保证业务稳定性,因此平台自身实现了事件熔断和自愈功能。当检测到宿主 BPF 出现异常,平台会自动 unload bpf 从而避免当前 BPF 造成过高的负载。除了实现事件的熔断和自愈,同时限制平台使用的系统资源如 cpu、mem。

  • 容器信息管理

实现该功能主要基于如下因素:1. 所有业务运行在容器,参数的传递,业务的识别都需要该信息。2. 内核 cgroup 信息需要和容器信息进行聚合。

平台使用

平台除了 API 接口,还提供了命令行方式,这样非常态运行 BPF OBJ 或者调试 OBJ 都可以在该平台运行。

代码示例如下:



编译:

clang -O2 -g -target bpf -c $(NAME).bpf.c -o $(NAME).o
复制代码

运行:平台自动解析 BPF 定义的结构体并打印到 stdout。



滴滴业务落地实践

在滴滴很多业务已经接入 HuaTuo eBPF 平台,例如服务测试回归、容器安全、主机安全、服务访问拓扑、网络诊断,内核根因定位等等。下面主要以内核根因定位为例进行讲解。 

内核根因定位背景

现今,降本增效是广大互联网公司的主题,在滴滴容器部署密度,超卖比都较高,共享内核容器技术在这种情景下很难避免由于资源不合理使用影响到其他业务的情况。在发生故障时第一举措是止损,容器漂移,这样问题现场就丢失了,线下复现问题的难度大,人力机器的成本很高。此外,线上偶发的毛刺、耗时和超时等问题没有规律可循,综上原因常态观测是一个非常强的需求。

内核根因定位思路

根据可观测性三大支柱(如下图所示),首先我们建立起内核深度观测指标,这些指标更加细粒度,能够反映出内核各子系统健康状态。建立这些指标时会从不同的角度评测合理性、性能影响,最终实现常态观测。其次,事件驱动实现获取内核异常日志上下文,我们关心内核各子系统在异常路径,慢路径等出错状态收集。异常事件是解决内核问题根因的关键。随着底层基础能力的建立,我们可以将这些信息就行汇总、分析、最终给出分析报告。



内核根因定位平台



我们将内核根因定位平台分为四部分:

  • 内核数据采集。该部分主要实现内核核心指标采集,以及内核异常上下文的收集。

  • 内核数据聚合。该部分主要实现将内核观测数据和容器/Pod 信息进行汇总并上传到存储设备。

  • 数据分析层。该部分主要将收集到的数据进行处理,对上提供分析服务。

  • 数据展示层。主要分析诊断中心、观测中心、日志中心、分析报告、以及报警中心等。

未来规划展望

eBPF 内核技术在滴滴云原生场景进行了大规模多场景的落地实践,未来 HuaTuo eBPF 平台会服务更多的业务线。如今,我们正寻求合适的基金会进行项目孵化,一起和行业开发者共建、共享。最近几年,eBPF 技术虽然有比较大的发展,但在某些场景中的功能还不够完善,比如在性能上进行优化、CPU 调度等在离线混部场景中深入探索等,期待后续与大家持续交流探讨。


关注滴滴技术公众号,获取更多技术干货


发布于: 刚刚阅读数: 3
用户头像

滴滴技术

关注

还未添加个人签名 2020-06-29 加入

滴滴出行官方技术号

评论

发布
暂无评论
滴滴是如何落地eBPF技术的?_云原生_滴滴技术_InfoQ写作社区