一种宿主机内核bug导致kvm虚拟机丢包的监控和处理方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一种宿主机内核bug导致kvm虚拟机丢包的监控和处理方法相关的知识,希望对你有一定的参考价值。
近期公司一台kvm虚拟机丢包引发应用异常,经过分析宿主机内核bug导致,没有包转发到虚拟机,体现为虚拟机丢包引发应用异常。
原因分析和相关概念
如下是现象和分析过程
1、收集虚拟机内部的virtio0-input中断,执行如下命令,隔1分钟收集一次,发现有一个队列中断数一直没有变化,这个就是导致虚拟机丢包的直接原因。因为中断代表cpu收到了网卡的中断请求,这里没有中断,则是虚拟机并没有接收到网络请求。
2、虚拟机中断没有发生,可能原因有很多,这里涉及到kvm虚拟机网络实现的架构流程,kvm一般使用的是virtio是半虚拟化的解决方案,virtio分为前端和后端,vhost-net是后端,在host内核上运行,virtio-net是前端,在guest上运行。virtio架构大致如图所示,当虚拟机未发生中断时,问题原因为下图中步骤A或步骤B之一出了问题
3、如果步骤A出现问题,是tun设备和vhost_net传输阶段出现问题导致丢包,如果是步骤B出现问题,则是虚拟化中断注入异常导致中断注入失败,或者环形缓冲区(ring buffer)满了,vhost_net不对其传输数据。这里环形缓冲区是指具有固定的有限大小的缓冲区,如果缓冲区满了,就代表virtio处理数据不及时。
应用厂商通过crash工具和perf工具内核分析发现,环形缓冲区并没有满,并且期间有一个vhost队列是sleep状态,没有被tun唤醒,而其他队列都有被唤醒。即是步骤A出现的问题。
该问题属于宿主机的kernel中tun设备代码实现中有bug导致的问题。问题的原因在于tun设备内部的tx_array中数据错乱导致环形队列无法工作,进而导致虚拟机virio_net无法收包。
临时处理办法
因为属于宿主机bug,暂时无彻底解决方法,而这个问题会体现到虚拟机队列中断没有发生,因此可以通过关注虚拟机中断是否持续发生,如果队列中断长时间没有发生,很可能就是发生丢包了。
监控方法
执行如下命令,将每个队列的virtio0-input中断采集下来,然后隔几分钟再次执行采集,对比前后两次,如果中断数量没变化的情况,很可能就发生这个丢包问题了。如下图11号队列,前后两次中断数量没有变化,可能出现问题了。
cat /proc/interrupts |tr -s |grep virtio0.input.|awk sum=0;for(i=2;i<=NF;i++)sum+=iprint NF" "sum
临时处理
因为这个问题是由于网卡多队列引起,其中一个队列没有发生中断导致,因此只需要在虚拟机内部重置网卡队列,重新释放后网卡队列后,再恢复网卡队列,即可恢复正常。
比如虚拟机网卡名为eth0,则先执行ethtool -l查看当前网卡队列数Current hardware settings的值为N,
N=ethtool -l eth0 |grep -wA4 "Current hardware settings" |grep -i Combined |awk print $2
先将网卡队列数设置为1,然后再恢复,这样可以快速恢复。
ethtool -L eth0 combined 1
ethtool -L eth0 combined $N
注意事项
1、 一般虚拟机的网卡队列数设置为小于或等于cpu核数,如果大于cpu核数,则多出的网卡队列则无意义。然后如果cpu核数大于网卡队列的话,注意前面监控方法,需要把没有绑定网卡队列的cpu核剔除比对,因为没有绑定网卡队列的cpu核,是不会发生中断的。
2、 如果虚拟机的流量很小(比如一些热备机器),同时网卡队列数比较大,这个前面的监控可能会误告警,可根据实际情况增加两次采集中断数的时间间隔。
ping虚拟机丢包问题分析
宿主机ip:192.168.1.2
虚拟机ip:192.168.1.3
第三台机器ip:192.168.1.4
问题说明:
第三台机器 ping 虚拟机 丢包严重
第三台机器 ping 宿主机 正常
宿主机 ping 虚拟机 正常
虚拟机 ping 任何机器 正常
问题分析:
根据现象排除了防火墙问题,排除了虚拟机设置的问题。
根据现象需要确认第三台机器ping虚拟机时到底ping的是哪台机器,于是使用arp -a进行查看,发现arp -a中有与虚拟机mac地址相同的记录。所以判断应该是mac地址的问题。
问题解决:修改虚拟机的ip地址,重新配置网络,问题解决
以上是关于一种宿主机内核bug导致kvm虚拟机丢包的监控和处理方法的主要内容,如果未能解决你的问题,请参考以下文章