eBPF 核心技术与实战
倪朋飞
资深 Linux 专家,Kubernetes 项目维护者
10452 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已更新 26 讲/共 37 讲
eBPF 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

10 | 网络跟踪:如何使用eBPF排查网络问题?

你好,我是倪朋飞。
上一讲,我带你一起梳理了应用进程的跟踪方法。根据编程语言的不同,从应用程序二进制文件的跟踪点中可以获取的信息也不同:编译型语言程序中的符号信息可以直接拿来跟踪应用的执行状态,而对于解释型语言和即时编译型语言程序,我们只能从解释器或即时编译器的跟踪点参数中去获取应用的执行状态。
除了前面三讲提到的内核和应用程序的跟踪之外,网络不仅是 eBPF 应用最早的领域,也是目前 eBPF 应用最为广泛的一个领域。随着分布式系统、云计算和云原生应用的普及,网络已经成为了大部分应用最核心的依赖,随之而来的网络问题也是最难排查的问题之一。
那么,eBPF 能不能协助我们更好地排查和定位网络问题呢?我们又该如何利用 eBPF 来排查网络相关的问题呢?今天,我就带你一起具体看看。

eBPF 提供了哪些网络功能?

既然想要使用 eBPF 排查网络问题,我想进入你头脑的第一个问题就是:eBPF 到底提供了哪些网络相关的功能框架呢?
要回答这个问题,首先要理解 Linux 网络协议栈的基本原理。下面是一个简化版的内核协议栈示意图:
Linux内核协议栈
如何理解这个网络栈示意图呢?从上往下看,就是应用程序发送网络包的过程;而反过来,从下往上看,则是网络包接收的过程。比如,从上到下来看这个网络栈,你可以发现:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

eBPF技术在网络排查中的应用备受关注。本文深入介绍了eBPF在网络问题排查中的应用,以及其提供的丰富网络功能。文章首先解释了Linux网络协议栈的基本原理,从应用程序发送网络包到网络包接收的过程。接着详细介绍了eBPF提供的网络功能,包括过滤、捕获和重定向等功能,并强调了eBPF程序类型的多样性,涵盖了多个网络领域。以网络丢包为例,说明了如何使用eBPF来排查网络问题。通过示例和命令展示了如何使用bpftrace进行调用栈的跟踪,以及如何改进跟踪程序以过滤网络信息并打印相关数据。文章还介绍了如何根据函数偏移快速定位源码,以及内联函数的优化技术。总的来说,本文为读者提供了清晰的技术概览,使他们能够快速了解eBPF在网络排查中的应用及其特点。文章内容涵盖了eBPF在网络排查中的实际应用案例,为读者提供了宝贵的技术指导和实践经验。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《eBPF 核心技术与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(13)

  • 最新
  • 精选
  • 莫名
    1、比较赞同【最主要是因为不清楚内核中都有哪些函数和跟踪点可以拿来跟踪】这一观点。如果对内核不熟悉,借助 tracepoint 通配符可以很好的协助理解网络协议栈的关键路径。举两个简单例子。 > 例 1:追踪 net 相关追踪点以及调用堆栈: # bpftrace -e 'tracepoint:net:* { printf("%s(%d): %s %s\n", comm, pid, probe, kstack()); }' 输出示例(sshd 发送数据包关键路径,涉及 tracepoint:net:net_dev_queue、tracepoint:net:net_dev_xmit 等追踪点,可以借助这些追踪点可进一步计算数据包排队时间等): sshd(219966): tracepoint:net:net_dev_queue __dev_queue_xmit+1524 dev_queue_xmit+16 ip_finish_output2+718 __ip_finish_output+191 ip_finish_output+54 ip_output+112 ip_local_out+53 __ip_queue_xmit+354 ip_queue_xmit+16 __tcp_transmit_skb+1407 tcp_write_xmit+982 __tcp_push_pending_frames+57 tcp_push+219 tcp_sendmsg_locked+2415 tcp_sendmsg+44 inet_sendmsg+59 sock_write_iter+156 new_sync_write+287 __vfs_write+38 vfs_write+171 ksys_write+97 __x64_sys_write+26 do_syscall_64+71 entry_SYSCALL_64_after_hwframe+68 sshd(219966): tracepoint:net:net_dev_xmit dev_hard_start_xmit+368 dev_hard_start_xmit+368 sch_direct_xmit+278 __dev_queue_xmit+1713 dev_queue_xmit+16 ip_finish_output2+718 ... __x64_sys_write+26 do_syscall_64+71 entry_SYSCALL_64_after_hwframe+68 > 例 2:使用 perf trace 也比较方便: # perf trace --no-syscalls -e 'net:*' curl -s time.geekbang.org > /dev/null 输出示例(可以看到具体走了哪些网络设备、数据包长度、skb 内存地址等): 0.439 curl/2240 net:net_dev_queue:dev=eth1 skbaddr=... len=54 0.452 curl/2240 net:net_dev_start_xmit:dev=eth1 skbaddr=... len=54 0.455 curl/2240 net:net_dev_xmit:dev=eth1 skbaddr=... len=54 0.707 curl/2240 net:netif_receive_skb:dev=eth1 skbaddr=... len=52 2、dropwatch.bt 头文件有些没使用到,可以做下简化: #include <linux/skbuff.h> #include <linux/ip.h> #include <linux/socket.h> #include <linux/netdevice.h> =====================> #include <linux/skbuff.h> #include <net/ip.h> 思考题直接用 bpftrace 内置变量 comm、pid 即可。

    作者回复: 非常👍的答案!也谢谢分享跟踪点学习的经验!

    2022-02-07
    2
    20
  • Geek_9e1ece
    老师 ntop这个函数返回的是字符串么?为什么我用$sip或$dip去做if判断时候提示我两端的数据类不正确呢。 另外我翻了一下内核的源码,好像没有直接找到ntop()这个名字的函数,请问还有pton()这样的函数可以将字符串转成inet数据类型么,以便我在if判断中作为过滤条件。

    作者回复: ntop是bpftrace提供的一个内置函数,把IP地址转换成字符串形式,方便展示。 具体文档可以参考 https://github.com/iovisor/bpftrace/blob/master/docs/reference_guide.md#14-ntop-convert-ip-address-data-to-text

    2023-02-03归属地:北京
  • janey
    第二图里怎么没有tracepoint?应该是跟kprobe在同一个层面吧

    作者回复: 图里的syscall其实就是tracepoint。不过你说的也有道理,tracepoint其实有很多,不只是syscall,也包括很多网络跟踪点。

    2022-11-25归属地:江苏
  • k8svip
    老师 如何跟踪下PHP-fpm线程,去处理MySQL 域名解析的过程呢?偶现连不通的情况,回出现udp receive error 包数量增加,tcpdump又捕获不到

    作者回复: 可以考虑去跟踪DNS请求?这可能比跟踪进程更简单一些

    2022-03-16
  • 从远方过来
    老师,看了你举的查找SKB的例子,我很好奇要怎么才能快速地从内核相关文档中找到相关的函数呢? 例如:找出关于内存分配的函数, 这个有什么好窍门么?

    作者回复: 最容易的就是使用eBPF跟踪系统调用相关的内核栈,然后对栈中的相关函数进行跟踪。当然,如果熟悉内核代码,去内核源码查看更好。

    2022-02-24
  • 阿斌斯基
    ubuntu 18.04 ,snap安装的bpftrace,kernel symbol解析失败 ➜ ~ bpftrace -V bpftrace v0.13.0 ➜ ~ echo $BPFTRACE_VMLINUX /usr/lib/debug/boot/vmlinux-5.4.0-96-generic ➜ ~ uname -a Linux max-machine 5.4.0-96-generic #109~18.04.1-Ubuntu SMP Thu Jan 13 15:06:26 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux ➜ ~ sudo bpftrace -e 'kprobe:kfree_skb /comm=="curl"/ {printf("kstack: %s\n", kstack);}' [sudo] password for max: Attaching 1 probe... kstack: 0xffffffff9091b941 0xffffffff90a5f5f7 0xffffffff90914e41 0xffffffff90a5eae9 0xffffffff909f4009 0xffffffff90a351c0 0xffffffff9090b8e2 0xffffffff9090b975 0xffffffff902e0276 0xffffffff902e047e 0xffffffff900c493d 0xffffffff90003ec9 0xffffffff90004320 0xffffffff90c0008c kstack: 0xffffffff9091b941 0xffffffff90a5f5f7 0xffffffff90914e41 0xffffffff90a5eae9 0xffffffff909f4009 0xffffffff90a351c0 0xffffffff9090b8e2 0xffffffff9090b975 0xffffffff902e0276 0xffffffff902e047e 0xffffffff900c493d 0xffffffff90003ec9 0xffffffff90004320 0xffffffff90c0008c kstack: 0xffffffff9091b941 0xffffffff9090fad3 0xffffffff9090fb6a 0xffffffff90004207 0xffffffff90c0008c kstack: 0xffffffff9091b941 0xffffffff9090fad3 0xffffffff9090fb6a 0xffffffff90004207 0xffffffff90c0008c

    作者回复: 有没有使用snap install --devmode来安装?Github上面也有个类似的issuehttps://github.com/iovisor/bpftrace/issues/1488。旧的发行版最好还是从源码安装 BCC 和 bpftrace。

    2022-02-07
  • 为了维护世界和平
    github上的程序 执行 段错误 #bpftrace dropwatch.bt Segmentation fault (core dumped)
    2022-07-19
    2
  • InfoQ_1e92d5385cc8
    建议可以根据GPT 4.0来自动解析日志,如网络不通回复如下: 这是一个bpftrace日志,它使用了dropwatch.bt脚本来追踪丢失的网络数据包。从日志中,我们可以看到一个数据包从10.206.0.13发送到39.106.233.176时被丢弃了。以下是内核栈(kstack)的调用顺序: kfree_skb+1:释放数据包的内存。 nf_hook_slow+167:调用Netfilter钩子,处理网络数据包。 __ip_local_out+215:处理本地IP数据包的输出。 ip_local_out+23:将数据包发送到本地IP层。 __ip_queue_xmit+349:将数据包放入队列以进行传输。 __tcp_transmit_skb+1362:传输TCP数据包。 tcp_connect+2753:建立TCP连接。 tcp_v4_connect+1112:建立IPv4 TCP连接。 __inet_stream_connect+209:建立INET流连接。 inet_stream_connect+54:建立流连接。 __sys_connect+154:系统调用,发起连接。 __x64_sys_connect+22:64位系统调用,发起连接。 do_syscall_64+91:执行64位系统调用。 entry_SYSCALL_64_after_hwframe+101:进入64位系统调用。 从这个调用栈中,我们可以看到数据包在网络层(Netfilter钩子)被丢弃。可能的原因包括防火墙规则、路由问题或其他网络配置问题。要解决这个问题,你需要检查你的网络设置,特别是防火墙规则和路由配置
    2023-10-10归属地:广东
  • Bachue Zhou
    $ sudo bpftrace -l 'kprobe:kfree_skb*' kprobe:kfree_skb_list_reason kprobe:kfree_skb_partial kprobe:kfree_skb_reason kprobe:kfree_skbmem $ uname -r 5.19.0-38-generic 尴尬 我这边 5.19 就没有 kfree_skb 这个函数了
    2023-04-06归属地:上海
    2
  • linker
    $ apt list --installed |grep '\<linux-' WARNING: apt does not have a stable CLI interface. Use with caution in scripts. binutils-x86-64-linux-gnu/jammy-updates,jammy-security,now 2.38-4ubuntu2.1 amd64 [installed,automatic] linux-base/jammy,now 4.5ubuntu9 all [installed,automatic] linux-buildinfo-5.19.0-35-generic/jammy-updates,jammy-security,now 5.19.0-35.36~22.04.1 amd64 [installed] linux-firmware/jammy-security,now 20220329.git681281e4-0ubuntu3.9 all [installed,upgradable to: 20220329.git681281e4-0ubuntu3.10] linux-headers-5.19.0-35-generic/jammy-updates,jammy-security,now 5.19.0-35.36~22.04.1 amd64 [installed] linux-hwe-5.19-headers-5.19.0-35/jammy-updates,jammy-security,now 5.19.0-35.36~22.04.1 all [installed,automatic] linux-hwe-5.19-tools-5.19.0-35/jammy-updates,jammy-security,now 5.19.0-35.36~22.04.1 amd64 [installed,automatic] linux-image-5.19.0-35-generic/jammy-updates,jammy-security,now 5.19.0-35.36~22.04.1 amd64 [installed] linux-libc-dev/jammy-updates,jammy-security,now 5.15.0-67.74 amd64 [installed,automatic] linux-modules-5.19.0-35-generic/jammy-updates,jammy-security,now 5.19.0-35.36~22.04.1 amd64 [installed,automatic] linux-sound-base/jammy,now 1.0.25+dfsg-0ubuntu7 all [installed,automatic] linux-source-5.19.0/jammy-updates,jammy-security,now 5.19.0-35.36~22.04.1 all [installed] linux-tools-5.19.0-35-generic/jammy-updates,jammy-security,now 5.19.0-35.36~22.04.1 amd64 [installed] linux-tools-common/jammy-updates,jammy-security,now 5.15.0-67.74 all [installed,automatic]
    2023-03-13归属地:江苏
收起评论
显示
设置
留言
13
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部