今天给技术伙伴们分享一下 BCC 和 Ftrace 的使用方法,在开发实践过程中会遇到哪些问题,本篇文章都将一一道来~
BCC 一个用于跟踪内核和操作程序的工具集,其软件包中包含了一些有用的工具和例子,是 eBPF 技术的一个前端,集成了 ebpf/kprobe/uprobe 等工具,可以使用 Python 来封装,对一些常见功能进行了整合。
而 eBPF 是近几年比较热门的一项技术,它的前身是 BPF(Berkeley Packet Filter),也就是 tcpdump 使用过滤数据包的技术。eBPF 对 BPF 进行了扩展,它能在内核中运行自定义程序,而无需修改内核源码或者加载内核模块。
Ftrace 有两种概念,一种是广义的 Ftrace 框架,一种是狭义的追踪技术。广义的 Ftrace 框架包含了 krpobe trace event 很多追踪技术,而狭义的 Ftrace 也就是本期的重点内容,今天会对其中一种 Ftrace 的使用做着重介绍。
Tracer 的概念直译为追踪器,可以直观理解为内核提供的一些追踪技术,比如有 function tracer,function graph tracer 等等,今天将着重介绍 function graph tracer,因为 function tracer 的很多功能用 BCC 就可以实现,而 function graph 却是 BCC 没有的功能。
function graph tracer 的效果如图:
BCC 效果如图:
>>>> 安装
BCC 使用 yum install bcc -y 就能安装。Ftrace 不用安装,是内核提供的,只要开启 CONFIG_DYNAMIC_FTRACE 就行,而这个选项我们是默认开启的。
内核版本越高,BCC 和 Ftrace 能使用的功能就越多。也就是说,在低内核版本上,可能一些功能并没有集成进去所以就不能使用这个功能。
BCC 安装完成后如图所示:
而 Ftrace 需要手动开启内核一些选项:
Trace 语法:
*: 用来匹配任意字符的通配符。-r 选项允许使用正则表达式。
详细可见《bpf之巅——洞悉linux系统和应用性能》
>>>> 安装
可以看到环境上有两个同网段的 ip,这个环境作为 client 向 server 发消息,server 地址是 100.1.1.21。
>>>> ifdown 测试
在 client 和 server 的正常通信中通过 ifdown 把网卡 down 掉,会发生什么呢?
我们可以看到,client 在 down 掉网卡后,返回值还是正常的,但是 server 阻塞在 read(),就已经接收不到数据。
>>>> ip link set down 测试
在 client 和 server 的正常通信中通过 ip link set ens192 down 把 link down 掉,会发生什么呢?
可以看到,client 和 server 都还可以正常收发!
这里有两个问题:
接下来,我们将通过 BCC 和 Ftrace 追踪工具解答这两个问题。
根据排查定位,我们定位到了路由这一块。而路由是在 ip 层做的事情,所以我们来看 ip 层的代码:
ip_queue_xmit() -> ip_queue_xmit() ip_queue_xmit() 是 ip 层的入口函数。
可以看到,ip 层的第一步就是一个检查,那么我们需要看一下对两种测试来说,检查的结果是什么,有什么不同?
我们需要用 BCC 自带的 Trace 工具来查看 sk_dst_check() 的返回值。
>>>> ip link set down 测试
>>>> ifdown
可以看到,在 ifdown 测试中,后面的返回值全部变为了 NULL ,而 ip link set down 测试中,只有一次变为了 NULL ,而后面就恢复了正常。
经过了解后,变为 NULL 的原因很简单。因为 struct sock 里缓存了上次成功的路由,而这 sk_dst_check() 检查路由缓存是否还可用, ifdown 和 ip link set down 后肯定就不可用了。
梳理代码逻辑后可以观察到,如果路由缓存不可用的话,会通过 ip_route_output_ports() -> ip_route_output_flow() 来查找路由表,如果查找成功会再次将其缓存起来。所以这里发生的事情是, ifdown 路由缓存失效后,查找路由表找不到有效路由。而 ip link set down 后,查找路由表可以找到有效路由。
那么要通过 Ftrace 看一下,在两种测试中,ip_route_output_flow() 的逻辑到底有什么不同?
Ip link set down后,路由查找的过程:
ifdown 后,路由查找的过程:
对比两种输出的不同和内核代码,可以发现,ifdown 后会直接查找设备失败,进而直接返回给上层 (tcp)-EHOSTUNREAD。而 ip link down 后,会查找设备成功,进而查找路由成功。
再对比内核代码中的查找路由过程,发现在 fib_table_lookup() 中,有以下逻辑:
然后发现 /proc/sys/net/ipv4/conf/ens40/ignore_routes_with_linkdown 这个选项,控制了 link down 后,原来路由是否还会生效,而这个值默认是 0,也就是不忽略原来的路由项。
至此,终于可以解答前面的两个疑问了:
通过本期文章的分享,大家应该对 BCC 和 Ftrace 的使用方法有了一定的了解,我们后续还会有更多技术文章的分享,可以持续关注。
留言与评论(共有 0 条评论) “” |