虚拟机vm报文丢包,多数情况下不是单一原因,而是从虚拟机内部到物理网卡这条链路中某个环节出现了性能瓶颈或配置差错,排查需按“虚拟机内虚拟交换机宿主机物理链路”逐层验证。
以KVM和VMware ESXi两种主流虚拟化平台为例,丢包现象普遍集中在网卡驱动、vCPU调度、虚拟交换机队列、物理网卡中断合并这几个层面,直接给出结论:八成丢包问题,通过关闭网卡硬件卸载、调整ring buffer、关闭CPU调频节能、确认vhost-user或SR-IOV配置这四步操作就能解决或显著缓解。
虚拟机vm报文丢包排查从哪里开始:先分虚与实
排查的第一步不是登录虚拟机,而是在宿主机上区分丢包发生在虚拟链路还是物理链路,用ping或iperf3打流,同时在宿主机上执行ethtool -S查看物理网卡丢包计数,在虚拟交换机(如OVS或标准vSwitch)上查看dropped计数,如果物理网卡rx_dropped和tx_dropped大量增长,方向直接从宿主机网卡入手;如果计数正常,问题大概率出在虚拟机内或虚拟化层。
操作路径上,Linux宿主机记住三个核心命令:
ethtool -S eth0 | grep -E "drop|err" ip -s link show eth0 ethtool -g eth0
第一组看物理网卡统计,第二组看IP层丢包,第三组查ring buffer当前值和最大值,行业共识认为,rx_missed和rx_fifo_errors两个计数器只要出现增长,基本指向网卡接收缓冲区溢出,也就是处理速度跟不上到达速率,这在虚拟化宿主机上尤为常见。
宿主机层面的丢包根因:驱动、队列和CPU亲和性
网卡驱动版本与ring buffer对丢包的影响
宿主机丢包的第一个高频原因是网卡驱动与硬件固件版本不匹配,近年来,Intel和Mellanox网卡在虚拟化场景下频繁出现丢包问题,不少就出在驱动bug上,例如ixgbe驱动在旧版本下开启VMDq后容易出现rx_dropped暴涨,升级到较新版本后问题消失。
实操介入顺序:先ethtool -g eth0看当前ring buffer,如果rx/tx小于1024,建议直接调到最大值,以Intel X710网卡为例,命令如下:
ethtool -G eth0 rx 4096 tx 4096
修改后压测对比丢包率,这一步能直接解决相当一部分突发流量下的丢包,注意虚拟机vm报文丢包排查时,ring buffer常被忽略,因为默认值在低流量下看着没问题,一到高峰就丢失。
vhost-net线程与CPU亲和性配置
KVM虚拟化下,vhost-net线程负责处理虚拟机网络IO,如果vhost线程被调度在不同CPU核心间频繁迁移,报文处理延迟就会波动,引发TCP重传和UDP丢包,这是Linux平台特有的坑,Windows Hyper-V则体现为vmswitch线程占用不均。
解决思路是将vhost线程绑定到物理CPU核心,第一步找线程号:
ps -eLo pid,tid,comm | grep vhost
然后使用taskset绑定,更彻底的做法是给虚拟机配置CPU pinning,让vCPU独占物理核心,同时保证网卡队列的中断和vhost线程落在同一NUMA节点上,跨NUMA访问的丢包延迟问题,在大多数虚拟化场景中都是隐形杀手,行业内有一个不常被提及的经验:当vCPU和物理网卡不在同一NUMA节点时,即便带宽本身够用,小包场景下的丢包率也会成倍上涨。
物理网卡队列数不足导致虚拟机vm报文丢包
多队列网卡需要为每个vCPU分配独立的RX队列,否则所有流量挤在一个队列里,单核处理不过来就丢包,检查方式:
ethtool -l eth0
如果Combined值小于虚拟机vCPU数量,建议设置成至少等于vCPU总数,同时打开/proc/irq/下对应中断的smp_affinity,让中断分散到多个核心。
虚拟机内部丢包如何定位:网卡卸载与协议栈调优
关闭TCP/UDP校验和卸载与GSO/GRO
虚拟机内部丢包,最典型的原因是虚拟网卡(virtio-net或vmxnet3)与宿主机物理网卡在硬件卸载功能上的配合出问题,具体表现是:大包传输正常,小包如UDP 64字节高并发时丢包严重。
在虚拟机内执行:
ethtool -K eth0 tx off rx off ethtool -K eth0 gro on gso on tso on
操作逻辑是:虚拟网卡关闭自身的校验和计算,把这类工作交给宿主机物理网卡,同时打开GRO/GSO减少宿主机侧的中断次数。这一开一关之间,较多场景下的丢包问题能直接消除。
另一个值得检查的是虚拟机内网卡的rx/tx队列长度,Linux虚拟机默认txqueuelen只有1000,UDP高速发送时容易触发NETDEV WATCHDOG或qdisc丢弃,调整方法:
ip link set eth0 txqueuelen 10000
virtio-net与vmxnet3驱动的性能差异
KVM平台优先选用virtio-net,但多队列需要确认驱动版本,老版本virtio-net驱动不支持多队列,跑不满带宽且容易出现丢包,VMware ESXi平台则注意vMXNET3和e1000E的取舍e1000E模拟的是老硬件,CPU开销大且有性能上限,生产环境建议切换至VMXNET3。
业界共识:VMXNET3配合多队列和中断自适应,吞吐量比e1000E高出数倍,丢包率差距在多数压力测试中表现都极为明显。
虚拟交换机层面的丢包:OVS流表与队列配置
Open vSwitch的流表规则泄露问题
OVS是KVM平台最常用虚拟交换机,它有两个丢包重灾区:
- 流表超时或冲突导致报文查找失败,直接
drop - upcall到用户态处理时,
handler线程处理能力不足导致延迟丢失
排查方式:
ovs-vsctl get interface vnet1 statistics ovs-appctl dpif-netdev/pmd-stats-show
如果show出的avg processing cycles居高不下,考虑开启DPDK或调大PMD线程数量。在纯软件OVS下,单PMD线程每秒只能处理大约百万级小包,超过这个线就出现丢包,这是物理限制,调参只是缓解。
VLAN与MTU不一致引发的静默丢包
虚拟交换机端口MTU为1500,而虚拟机的接口MTU被调成9000,就会产生分片或静默丢弃,所有链路设备包括物理交换机、宿主机网卡、虚拟交换机、虚拟机网卡的MTU必须保持一致,这是虚拟机vm报文丢包排查中最容易修复的一项,改完无需重启,改错也无需担心。
具体协商流程:
- 确认物理交换机Trunk口MTU
- 宿主机网卡MTU同步调整
- OVS端口组MTU调整
- 虚拟机内部网卡MTU调整
四层全部对齐,不留一个缺口。
高负载特殊场景下的丢包排查思路
UDP泛洪与CPU softirq软中断瓶颈
当虚拟机作为DNS或NTP服务器遭遇UDP风暴时,宿主机softirq会成为第一瓶颈,检查方法:
cat /proc/net/softnet_stat
该文件每行代表一个CPU核,第三列如果持续大于0,说明该核的softnet backlog已经溢出,丢包确实发生在宿主机内核态,增加RPS(Receive Packet Steering)能部分改善:
echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus
但注意RPS本身占CPU,4核以下机器不建议开启。
PCIe带宽饱和与网卡带宽上限
一台宿主机插多张万兆网卡时,PCIe 3.0 x8的带宽上限大约为64Gbps,如果两张40G网卡同时跑满,PCIe总线本身就是瓶颈,此时网卡计数器完全正常,但实际吞吐上不去且伴随少量丢包,此场景没有调参空间,只能换更宽的PCIe通道或减少物理网卡数量,疫情期间远程办公流量激增时,这种PCIe饱和导致的丢包问题在部分云服务商内部频繁出现,症状就表现为宿主机各虚拟机间歇性丢包。
虚拟化平台选型与丢包概率的真实对比
企业采购或现有架构改造时,关心虚拟机vm报文丢包在什么场景下概率高,这里做一个直接对比:
- KVM + OVS:胜在灵活,但小包转发靠CPU,高PPS场景丢包率高
- KVM + DPDK:丢包率极低,PPS能力提升数倍,需要专门CPU亲和性规划
- VMware ESXi + vmxnet3:中等流量下稳定,万兆线速以上受限
- VMware ESXi + SR-IOV:表现最好,直接将物理网卡VF直通给虚拟机,绕过软件交换层
针对上海杭州等二线城市IDC托管机房的用户群体,如果对丢包极度敏感、有业务SLA要求,行业目前的共识是:
SR-IOV方案比一切优化过的虚拟交换机都稳定,代价是牺牲部分热迁移和QoS灵活性。
几个容易忽略的操作细节汇总
- 关闭宿主机CPU的C-States节能状态,
intel_idle.max_cstate=0加到内核引导参数,避免CPU唤醒延迟导致的丢包 - 确认虚拟机网卡的协商速率,不要依赖virtio默认值,用
ethtool eth0实际查看 - 对时延敏感业务,关闭宿主机网卡的LRO(Large Receive Offload),它会把多个小包合并成大包,表面上效率高,实际上增加虚拟机侧延迟抖动
- tcpdump在虚拟机内部抓包时,如果丢包只出现在抓包状态下,但不抓包时业务正常,属于抓包工具自身丢包,不代表业务受损
结合问题场景排查总结
每次排查虚拟机vm报文丢包,默认按“物理网卡→虚拟交换机→虚拟机网卡→协议栈”顺序走完整流程,打开宿主机和虚拟机的丢包统计计数器,一边打流一边观察计数增长位置,增长出现在哪一层,问题就定位在哪一层,切记,不要在虚拟机内部盲目调整TCP参数,多数情况那是无用功,先用计数器确认方向和位置,再做针对性配置修改,整个解决过程一般能控制在半小时内。
关于虚拟机vm报文丢包排查的常见问题解答
虚拟机vm报文丢包和物理机丢包的原因有什么不同?
物理机丢包通常在协议栈或物理网卡层面就能定位;虚拟机多了一个虚拟交换机转发环节,这意味着即便物理链路完全健康,虚拟交换机流表异常、vhost线程调度延迟、virtio队列溢出都会单独导致丢包,排查范围必须包含Hypervisor层。
虚拟机间互访丢包但外网正常,怎么解释?
虚拟机之间通过虚拟交换机直接转发,不经过物理网卡,所以问题锁定在虚拟交换机转发能力和虚拟机网卡驱动上,查OVS的dpif-netdev/pmd-stats-show,或者确认ESXi的vSwitch端口组流量整形策略没有被误开,这个现象在IDC客户做内网迁移时并不少见。
虚拟机丢包与宿主机CPU型号有关系吗?
有关系,且关系不小,较老型号CPU不支持IOMMU直通或支持不完善时,虚拟机网络报文需要更多CPU指令周期来处理,高并发下CPU先满,随即就是丢包,Intel和AMD两类CPU也存在差异,多数情况下Intel在虚拟化网络性能上表现更稳定,AMD EPYC在开启NUMA优化后也能达到接近水平,具体选型上建议直接用压测验证,不要只看核心数和主频。
虚拟机vm报文丢包从现象到根因,本质是一条链路中性能最薄弱环节的暴露,做好每一层的基础配置,比任何单调优化都有效,排查时抓到哪一层特征数据,就在那一层解决,不跨层做无意义的参数堆叠,问题处理起来效率最高。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/745618.html





