基于 eBPF 的网络监测实践
作者:孙文杰
本文地址:https://www.ebpf.top/post/ebpf_network_exporter
公有云网络问题,是一个老生常谈的事情了。今天主要简单说明下,在内网环境下去分析 & 定位这个问题。也并不是一开始就需要 eBPF 加持的,可以从简单的基础工具到监控配合去相关比较快速的定位问题,解决问题。下面会从发现问题到一步步配合使用 Or 开发一些简单的东西去解决问题的大致思路。
1. 常见的网络相关问题
- 业务负载不均衡:业务系统会越发的复杂,不可能单个服务承接所有流量,一定会逐步迭代为一组服务承接流量,那我们是可以先用一些负载均衡组件去解决这个问题(不推荐一上来就喊,我要自研,图啥呢?),可以使用 HaProxy、Nginx 配合公有云的弹性能力去解决问题。伴随着业务的发展慢慢的当全站使用 K8s 的时候,还会遇到 Kube-Proxy 存在负载不均衡的问题,这个时候就可以应入 Envoy 到最终上线 Istio 去解决问题,做到内部服务的负载均衡(当然服务的健康检查 & 优雅停止需要考虑下)。配合边缘公有云 LB 做入流量控制,到 Kong 这种非常自动化的网关来解决业务整个边缘路由的分流能力。至此 xLB + Kong/Openresty/Apisix/Envoy + Istio(Evnoy) 基本上已经到了天花板了。(应该还有更优的)
- 网络异常抖动:日常会发生抖动的情况大致有几种情况吧。服务间异常、交换机过载、存储系统异常、业务系统 Bug,如上问题都需要专业的同学去帮助解决,并不能也不是每次都是网工的锅是吧。
- 网络延时增大:抛开业务系统问题,Slow Query、Big Key、Hot Key、消费生产(消息队列)延时等问题的话。那只能朝着网络层面去找问题了。(你想,交换机里面也有 CPU)举一个例子,家里 Wifi 为什么没啥人用也会卡,有一个东西叫信道,就好比虽然有很多信道但是呢流量都在一个信道里面跑(1个人干活,一群人看)能不卡吗?(应该能解的,这个就不懂了,不懂不捣乱)
2. 如何定位
Istio
- Istio 监控指标里面其实已经可以发现服务链路之间的调用的情况了,就是会发现为什么有些快有些慢呢,在排除 xDS(服务发现、路由下发等,Envoy API 与 Pilot 交互) 的问题后(其实没几家公司可以触发 Istio 的 Bug 的),依然慢的莫名其妙。
Ping
- 这个是一个好东西哦,简单看看绝对富裕了。闲来无事基于 ping_exporter 加了一个 RESTful API,这样想 Ping 哪里 Ping 哪里,如果需要 K8s 里面互相 Ping 的话,其实只要依靠 K8s API 做自发现 Node 互 Ping 就能一目了然的发现很多问题了(原来网络真的很糟糕)
3. eBPF
-
eBPF(extended Berkeley Packet Filter) 是一种可以在 Linux 内核中运行用户编写的程序,而不需要修改内核代码或加载内核模块的技术。简单说,eBPF 让 Linux 内核变得可编程化了。eBPF 程序是一个事件驱动模型。Linux 内核提供了各种 hook point,比如 system calls, function entry/exit, kernel tracepoints, network events 等。eBPF 程序通过实现想要关注的 hook point 的 callback,并把这些 callback 注册到相应的 hook point 来完成“内核编程”。
-
bcc 是一个基于 eBPF 的工具包,内部包装了 LLVM。你可以用 C 语言 + Python、Lua 等高级语言编写 eBPF 程序,同时还提供了不少有用的工具。BCC是一个用于跟踪内核和操作程序的工具集,其软件包中包含了一些有用的工具和例子,它扩展了BPF(Berkeley Packet Filters),通常被称为eBPF , 在Linux3.15中首次引入,但大多数BCC的功能需要Libux4.1及以上版本。(可以话时间研究下下的,基础功能 & BPF 代码里面多有)
-
bpftrace 是一门基于 eBPF 的高级追踪语言,可以方便快捷地编写 Linux 追踪程序。
-
工作原理:eBPF 通过 C 语言自由扩展(这些扩展通过 LLVM 转换为 BPF 字节码后,加载到内核中执行。从图中你可以看到,eBPF 的执行需要三步:从用户跟踪程序生成 BPF 字节码;加载到内核中运行;向用户空间输出结果。
-
实际上,在 eBPF 执行过程中,编译、加载还有 maps 等操作,对所有的跟踪程序来说都是通用的。把这些过程通过 Python 抽象起来,也就诞生了 BCC(BPF Compiler Collection)。
-
BCC 把 eBPF 中的各种事件源(比如 kprobe、uprobe、tracepoint 等)和数据操作(称为 Maps),也都转换成了 Python 接口(也支持 lua)。这样,使用 BCC 进行动态追踪时,编写简单的脚本就可以了。
-
不过要注意,因为需要跟内核中的数据结构交互,真正核心的事件处理逻辑,还是需要我们用 C 语言来编写。
cloudflare/ebpf_exporter
- Prometheus exporter for custom eBPF metrics. 非常棒的一个项目,在与 K8s 结合的时候,以 DaemonSet 的形式运行在集群中,可借鉴 kube-ebpf-exporter。
- 依据 Bcc Tools tcpconnlat,配合 ebpf_exporter 的改写如下(ebpf_exporter 例子中没有网络延时相关的)
|
|
基于上面一轮干下来,基本上哪里慢,为什么慢,怎么慢也就差不多定位了。剩下么,该干嘛干嘛。记得调用链还是非常有用的哦,配合网络监测 + 调用链,问题自然而然的就暴露啦(当然调用链接入姿势是另外一个问题啦)
最后推荐几本书吧,BPF之巅:洞悉Linux系统和应用性能 & Linux内核观测技术BPF。
原文地址:基于 eBPF 的网络检测实践
- 原文作者:孙文杰
- 原文链接:https://www.ebpf.top/post/ebpf_network_exporter/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 最后更新时间:2022-11-05 21:36:52.003290016 +0800 CST