编者按:eBPF(extendedBerkeleyPacketFilter)是一种可以在不修改内核代码的情况下,在Linux内核中运行用户编写的程序或加载内核模块的技术。简单地说,eBPF使Linux内核可编程。本文整理自龙百合讲坛第57期。浪潮信息SE王传国从原理上分析了eBPF的加载过程,解释了它如何保证系统的稳定运行,以及为什么能够加快网络速度。01eBPF加载过程我们知道,一般的eBPF加载过程是先写C代码,然后用llvmlang编译成ELF文件,再用libelf解析ELF文件,解析完后,根据libbpf所需的格式,组织,然后通过BPF系统调用,所有这些数据都可以加载到内核中,包括程序翻译的eBPF指令集。在内核中,有一个负责验证程序的验证器,还有一个负责翻译和分析程序的JIT。1.1RelocationBPF基础设施提供了一组有限的“稳定接口”,使用convert_ctx_access转换各种CTX,保证内核版本升级时的稳定性。CO-RE的核心思想是使用(BTF)非硬编码的形式来描述成员在结构中的偏移位置,解决不同版本之间的差异。需要重定位的元素:映射、函数调用、Helper函数调用、字段、外部内核符号和kconfig。1.2安全检查:数据、指令、循环数学计算的除数不能为0,指令调用范围[0,prog->len)深度优先遍历排除环。1.3eBPF指令集1.4指针安全检查判断指针类型,范围修正,无法识别的指针类型不允许被引用。范围检查,不同的指针类型有不同的检查方法和范围。02eBPF加速容器网络主要涉及eBPF程序类型:XDP、tc、sock_ops。它们加速网络性能的基本原理是将数据从一端(网口/套接字)的发送队列直接传输到另一端的接收或发送队列,绕过不必要的网络协议栈。XDP位于整个Linux内核网络软件栈的最底层,尚未生成skb,可以很早的识别并丢弃攻击包,性能较高;但有时可能无法支持虚拟机中XDP程序的加载,比如虚拟机网卡的接收队列太小。在tc函数的sch_handle_ingress和sch_handle_egress中添加hook点,分别为tcingress和tcegress。XDP没有那么多要求。基本上可以在所有OS中使用,绕过netfilter等不必要的内核网络协议栈路径,可以极大的提高网络性能,减少延迟。技术概述:将数据从一端套接字的发送队列直接发送到对端套接字的接收队列或发送队列。sockops:挂载到cgroup,监控整个cgroup所有socket的握手和wave(active|passive),记录tcp连接。sockmap:存储数据特征与socket句柄的关系。写入数据时执行bpf_map_update,修改对应socket的sendmsg函数指针。sk_msg:使用sockmap重定向数据。经过我们的测试,如果我们将calico换成Cilium,在TCPThroughput模式下进行测试,pod之间的通信性能可以提升58%,sockops可以提升153%,节点间通信可以提升24%。如果采用TCP-RR模式进行实测,与calico相比,同一节点可以提升28%,sockops可以提升200.82%,跨节点可以提升43%。如果使用TCP_CRR模式进行测试,calico可以在同节点上提升40%,sockops提升35%,跨节点提升55%。当Cilium提升性能时,它的CPU使用率降低了10%以上,所以我们测试的结果是Cilium的性能明显优于使用iptables的calico。所以目前我们计划使用Cilium来优化我们的容器网络。直播课件及视频播放获取方式:【PPT课件获取】:关注微信公众号(OpenAnolis)回复“龙百合课件”即可获取。如有任何问题,欢迎随时咨询龙蜥小助手——小龙(微信:openanolis_assis)。【视频播放】:可到龙蜥官网观看视频播放。-超过-
