【Docker】封装在docker中的TCP dump未占用大量CPU资源,但不能完全抓包

想测试基于docker的一个平台的抓包性能。docker分配的资源是10%(4核)的CPU,内存128M。虚拟机是Linux的系统,4核。
使用docker里的tcpdump抓包,用top查看的时候tcpdump只占了单核6%的CPU,但是抓包总结显示有包没抓到。ksoftirqd进程只占了0.7%左右的CPU。

回答

好吧,这个问题我自己来回答啦。

在linux系统上,使用tcpdump抓包结束之后会提示:

【Docker】封装在docker中的TCP dump未占用大量CPU资源,但不能完全抓包

简单来说, captured是tcpdump处理过之后,得到的数据包数量,亦即最终获得的pcap文件中数据包数量; received是经过过滤器处理的所有数据包; dropped则是未经处理的数据包数量。
received by filter的结果这取决于运行tcpdump的操作系统及其配置。如果指定一个过滤器,包无论是否被筛选器表达式匹配,即使他们被筛选器表达式匹配,无论tcpdump是否读取和处理他们,都会进行计算,即收到一个包,received by filter会加1。如果sock的接收buffer被填满时,则把这个数据包丢弃,将dropped by kernel加1,所以 received by filter和dropped by kernel的计数由内核维护。
造成丢包的原因,是由于libcap抓到包后,tcpdump上层没有及时的取出,导致libcap缓冲区溢出,从而丢弃了未处理包,此处即显示为dropped by kernel。这里的kernel并不是说是被linux内核抛弃的,而是被tcpdump的内核,即libcap抛弃掉的。

解决办法也有一些,比如:
1、-n 参数,禁止反向域名解析()
2、-s 参数,控制抓取数据包的长度
(采用更大的捕捉范围既增加了处理报文的时间,又相应的减少了报文的缓冲数量,可能导致报文的丢失。尝试把snaplen设的尽量小,只要能够容纳需要的协议信息就可以。)
3、将数据包输出到cap文件
4、用sysctl修改SO_REVBUF参数,增加libcap缓冲区长度

方法1我试过了,效果不理想。
方法2也试过了,效果不错。但我本来就是要测抓包性能的,肯定得把包抓全啊,想想之后放弃了这个方案。
方法3这个.....我本来就是输出到文件里的,但还是有丢包的问题,所以好像并没有什么卵用。
方法4感觉有点复杂,不过前面解释里也提到是因为缓冲区不够才导致的丢包,遂觉得这方法有门,不过就是麻烦了一点。然后灵机一动,我查到了tcpdump里有个-B参数可以修改缓冲区大小,哈哈!!

所以最后的解决办法就是:我使用-B参数修改了tcpdump的缓冲区大小!!!
这里要注意的是如果未指定 -B 选项,那么缓冲区大小缺省为32768,既然这样我就乘二试了试,-B 65535。
嘻嘻,一下子什么丢包都飞走了~~

我用raw 。和tcpdump一样占用1.3%CPU -0.7%cpu 有读取阻塞,偶尔存在丢包。net.core.rmem_max = 16777216 有稍微缓解。还是会丢。如果如果CPU亲和力只占用一个还没有测试。取消阻塞会占100%接近的CPU,未测试
5

以上是 【Docker】封装在docker中的TCP dump未占用大量CPU资源,但不能完全抓包 的全部内容, 来源链接: utcz.com/a/74756.html

回到顶部