负责NTA基础建设工作已经快两年了,最近刚好有需求去排查丢包问题,也称此机会结此项工作做个体面的总结。
背景
目前负责一些NTA(zeek + suricata + arkime)基础建设的工作,但整个过程中都发现有很多的丢包问题,花费很长时间做了大量排查与分析工作,终于找到根源,就此做个经验总结和分享。
丢包场景
当前我们的使用场景是流量相对较大(非突增流量 30 Gbps/Cluster,1.2 Gbps/Server),且Server需要保持多组件使用,发现如下情况均存在丢包现象:
* 组件重启时丢包
* 流量突增时丢包
* 流量过大时丢包
* 特殊流量持续丢包,且丢包率持续居高不下
分析过程
1 资产梳理
要做根源分析,就需要先梳理一下当前NTA所涉及的资产,整个资产整理思路如下:数据源 → 网卡 → 数据包捕获框架 → 应用程序。
- 数据源:数据包封装协议、流量组成、流量大小和包速率
- 网卡:丢包情况、RSS 队列
- 数据包捕获框架及工作原理:传统模式/AF_Packet/PF_RING
- 应用程序:多/单套应用程序、多进程/线程、数据包负载均衡模式
以上每个因素都可能是造成丢包的潜在原因,后面详细分析。
2 监控报表
这一步至关重要,从问题入手,做尽可能多的指标数据搜集并创建监控报表才能让我们有更直观的感受和更准确的判断,我使用的 Prometheus + Grafana,当然时序数据库有更多选择(InfluxDB2)。
我搜集的监控指标主要包含如下:
- 流量
- 包速率
- 包数据(丢包数据、接收包数据、空闲数据包缓冲区数据、预设的数据包缓冲区数据(这里使用的是PF_RING数据)
- 性能数据(细化到进程的cpu使用率、内存使用率)
3 分析过程
3.1 数据源层面
此层面需要结合数据包捕获框架和应用配置来讲,暂且先跳过,后文详述。
3.2 网卡层面
流量是使用云平台上的流量镜像过来的,所以会重点关注 RX 侧参数。很明显,这里一切正常。
- errors- 接收错误数,比如 CRC 校验失败
- dropped- 因缓冲区不足导致丢弃的包数量
- overruns- 因硬件无法处理处理包导致的接收缓冲区溢出次数
3.3 数据包捕获框架层面(PF_RING)
我们使用的是PF_RING这个开源的高性能数据包捕获和传输框架(毋庸质疑白嫖版),其优势主要在于减少了数据包的复制次数和降低CPU开销,当然远不止于此(相对复杂,事实上我也说不清楚),画个图简单说明下在数据包传输层面PF_RING的优势:
3.3.1 RSS (Receive Side Scaling)
RSS是一种**网络 I/O 优化技术,**并不是PF_RING独有的功能,但PF_RING在自身框架中实现了此功能。
按 PF_RING 官方解释,RSS 功能可以设置为多个RX队列,默认情况按五元组方式将数据包平均分配到多个RX队列以便于做负载均衡。可以使用ethtool来设置,但个人理解如果在应用(suricata/zeek)中指定了PF_RING的其它模式(如inner-5-tuple),在这里使用了此功能或者已经跳过了此功能,此想法有待验证。
由于我们使用云主机,RSS 队列是由云平台预设且不能使用ethtool来根据CPU核心数量来调整此参数,所以这一部分未做深入测试和分析,有兴趣可自行查阅PF_RING官方文档(https://www.ntop.org/guides/pf_ring/rss.html)
3.3.2 PF_RING各项参数说明
先展示几张具有代表性的图
针对这几张图,我们需要重点关注以下参数
Slot 相关:
- Ring slots:环形缓冲区总容量(理论最大插槽数)
- Min Num Slots:实际预分配插槽数(根据内存和性能优化动态调整)
- Num Free Slots:空闲的插槽数
Tot 相关:
- Tot Packets:捕获的总数据包数
- Tot Pkt Lost:丢弃的总数据包数
- Tot Insert:成功插入环形缓冲区的数据包总数
- Tot Read:应用程序从环形缓冲区成功读取的数据包总数
明白了各参数意思之后,接下来就很容易查找问题了
参数 |
图左 |
图右 |
Num Free Slots |
0 (无环形缓冲区) |
11947 (还有大量环形缓冲区) |
Tot Pkt Lost 与 Tot Packets占比 |
25% (丢包 25%) |
0 (无丢包) |
Tot Read 与 Tot Insert 占比 |
84% (应用程序读包速率大大低于数据包插入的速率) |
99.9%(应用程序读包速率略滞后于数据包插入的速率) |
分析 |
缓冲区不够 + 应用程序性能不够,需要立即调整 |
缓冲区足够 + 应用程序性能略低,待观察 |
如果认真看数据,可以快速输出相应的公式:
- Tot Packets = Tot Pkt Lost + Tot Insert
- Num Free Slots = Min Num Slots - ( Tot Insert - Tot Read )
以上只是简单的示例,实际情况可能复杂更多,不再详细举例说明,根据我碰到的情况大致做个如下总结(此处踩坑,记得在做监控报表时需要使用单组件的单进程/线程数据,不要只监控单组件的总数据):
- Num Free Slots < Min Num Slots:数据包有积压,可能是突增流量或应用程序性能不足,需观察
- Num Free Slots = 0 AND Tot Pkt Lost > 0:存在丢包情况,缓冲区不够且应用程序性能不足,需立即增加Slots和应用程序的cpu核心数量(对于突增流量和应用程序重启时存在的丢包情况,可以适当调大Slots,能有效缓解丢包问题)
- Tot Read < Tot Insert:应用程序读包的速率跟不上数据速率速度,应用程序性能不足,需要增加应用程序的cpu核心数量
- Tot Read ≈ 0 OR 在某个值处变化很慢:应用程序卡死,需重启应用程序
4 应用程序层面
前文找到了如此多问题且着手调整后,发现依然存在大量丢包现象,尤其是某种类型的镜像源。继续坚持着这一波折磨,发现2个问题:
4.1 流量的负载均衡
zeek和suricata均可配置多个CPU核心(多进程/线程)及不同的PF_RING模式来进行数据包解析,而arkime虽然使用多线程,但从数据包捕获框架只使用了1个进程。所以这里我们重点关注zeek和suricata。
前文已说过,这里需同时考虑数据源、数据包捕获框架一起分析。这里我们从数据源入手开始分析:
4.1.1 流量大小和包速率:当前场景下我们的单台Server接收的流量最高可达 3.8 Gbps(部分流量类型存在突增流量),能明显感受到不同包速率/流量时丢包情况的一个差异,这个层面相对简单,不做深入分析。
4.1.2 数据包封装协议:这部分就比较复杂了,按封装协议可分为3种情况:无封装、VXLAN 封装、GENEVE + VXLAN 双层封装。
- 无封装:使用五元组模式
- VXLAN 封装:可使用内部五元组模式
- GENEVE + VXLAN 封装:复杂的问题,PF_RING本身并不支持 GENEVE 协议解封
由于业务自身原因,同一笔 FLOW 的请求包和响应包会通过 GENEVE 封装在 2 个不同的来源 IP 上,之后再使用 VXLAN 封装,这就会导致无可用的 PF_RING 模式。
但是万能的小伙伴也能通过修改PF_RING源码方式将geneve解封,那么依然可使用内部五元组模式来解决。理论上讲,按此种方式来配置应该可以解决流量负载不均的问题了,但有部分 Server 上的流量却无论如何也无法负载均衡,此处就要考虑流量组成了。
4.1.3 流量组成:
抓包观察发现,有一些流量源同时包含定期高频长链接流量和随机流量导致原始无封装流量不均衡。此种情况很少见,是由流量的业务类型所决定的。对于这种情况,如果有条件,可以往流量拆分方面考虑,比如使用过滤规则或者一台大流量的镜像源分给多台流量镜像目标。
4.2 应用程序性能
由于我们单Server会跑多个应用程序,我们的最终目标是需要在保持成本不变/降低的前提下,尽可能保证 NTA 有高质量的产出。这时候就要考虑各应用程序自身的性能消耗了。当然这会涉及到很多因素:不同云平台自身配置、服务器自身配置、规则加载数量、规则复杂程度等。
这块我没有详细数据,但在我们当前环境上,观察单 Server 的丢包率,发现性能消耗程度如下:Zeek > Suricata > Arkime,所以在单Server上考虑给Zeek分配更多的cpu核心,此举也确实帮我们大幅度节约了成本 。
解决方案
做个简单的总结如下,每种现象可能会多存在个原因和解决方案的对应关系,以下连接线只标准了相对重要的对应关系。
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)