某天晚上,发现在告警群里面收到一条关于网络丢包的告警

这里看到有两张网卡都出现了丢包,且丢包数量一致,那是因为这个boud4网卡是由enp26s0f0np0和enp26s0f1np1聚合出来了(为了做高可用),所以只要看enp26s0f0np0这张网卡就好了。

查看节点流量状态

在grafana中查看节点网络状态,确实是有大流量在跑

登录到节点进行排查

先用 ip link 来查看网卡相关信息

# ip -s link show enp26s0f0np0 
4: enp26s0f0np0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 9000 qdisc mq master bond4 state UP mode DEFAULT group default qlen 1000
    link/ether 0c:42:a1:32:11:d6 brd ff:ff:ff:ff:ff:ff
    RX:      bytes     packets errors dropped  missed   mcast           
    25911288114346 25333203540      0  574380       0 9523278 
    TX:      bytes     packets errors dropped carrier collsns           
    30755111916060 25795803740      0       0       0       0

可以发现在网卡接受包的时候出现了丢包原因

使用 ethtool –S 查看网卡包信息,主要关注rx的信息

其中关于丢包的信息要关注以下几个字段 (或者是带err、drop字样的字段)

rx_err_lane_xx_phy 物理层(PHY层)接收过程中,特定传输通道上检测到的错误(可能是网线存在问题)

rx_out_of_buffer 网卡没有可用的接收缓冲区来存储传入数据包而导致丢包

rx_buff_alloc_err 网卡在接收数据包时尝试分配内存缓冲区时发生而导致丢包

rx_oversize_pkts_sw_drop 数据包大小超过了软件层面允许(MTU)的最大值而被丢弃的接收数据包数量

rx_wqe_err 接收工作队列项(Work Queue Entry)错误 , 意味着网卡驱动与硬件之间的通信问题

# ethtool -S enp26s0f0np0 | grep -i rx
...
rx_out_of_buffer  572782
...

我这里发现rx_out_of_buffer的数量一直在增加,说明网卡的缓冲区处理速度更不上网络传输速度,在上图中也看到网络确实有大量流量进来

查看网卡缓冲区大小

# ethtool -g enp26s0f0np0 
Ring parameters for enp26s0f0np0:
Pre-set maximums:
RX:             1024
RX Mini:        n/a
RX Jumbo:       n/a
TX:             1024
Current hardware settings:
RX:             1024
RX Mini:        n/a
RX Jumbo:       n/a
TX:             1024
RX Buf Len:             n/a
TX Push:        n/a

发现RX的网卡缓冲区大小为1024,临时修改为8192,看看问题是否还存在

# ethtool -G enp26s0f0np0 rx 8192
# ethtool -g enp26s0f0np0 
Ring parameters for enp26s0f0np0:
Pre-set maximums:
RX:             8192
RX Mini:        n/a
RX Jumbo:       n/a
TX:             8192
Current hardware settings:
RX:             8192
RX Mini:        n/a
RX Jumbo:       n/a
TX:             1024
RX Buf Len:             n/a
TX Push:        n/a
#  ethtool -S enp26s0f0np0 | grep -i rx_out_of_buffer

在修改后发现 rx_out_of_buffer 的数量没有再添加了,过了5分钟左右对应的告警也恢复了

现在就要把对应的配置进行持久化

# 修改对应的配置文件,添加对应的配置
# vi /etc/sysconfig/network-scripts/ifcfg-enp26s0f0np0
...
ETHTOOL_OPTS="-G ${DEVICE} rx 8192"
# 我这里是bond所以另一张网卡也要修改
# vi /etc/sysconfig/network-scripts/ifcfg-enp26s0f1np1
...
ETHTOOL_OPTS="-G ${DEVICE} rx 8192"

总结

这个网卡的缓冲区有什么用

先看一下一个网络数据包到linux上的大概流程

https://zhuanlan.zhihu.com/p/256428917 这里参考大佬的文章

这里可以看到把数据保存在缓冲区(Ring buffer)为第6步

这个流程再细分一下就是以上的步骤,也就是说当网卡把数据拷到内存的时候发现缓冲区队列满了,无法再添加数据导致本次丢包

同时上述的文章里面也说了为什么ethtool可以修改这个缓冲区的配置,因为网卡驱动实现了ethtool所需要的接口,也在这里完成函数地址的注册。当 ethtool 发起一个系统调用之后,内核会找到对应操作的回调函数(实际上调用的就是网卡的接口)。