作为常年混在虚拟化环境里干活的人我花在网卡配置上的时间真不算少。尤其是当你面对的是一台承担了核心业务流量的Linux虚拟机网卡单点几乎就是悬在头顶的一把刀。这两天又把“Linux虚拟机网卡bond配置”从头到尾梳理了一遍趁着热乎劲把过程、原理、还有踩过的坑都写出来给同样在这条路上折腾的朋友做个参考。这个内容要解决的事情很单纯让一台虚拟机的多张虚拟网卡绑定成一个逻辑接口实现链路冗余和流量分担同时避免因为配置不当导致网络中断。适合刚接触bond的新手也适合已经配过但总遇到莫名其妙问题的老手。1. 为什么要在一台虚拟机里折腾网卡bond很多刚接触虚拟化网络的人会有个疑问物理服务器上做bond很好理解因为网卡硬件、线缆、交换机端口都有故障可能绑一下能提高可用性。但虚拟机里的网卡本质上是虚拟设备后端大多走的是宿主机物理网卡或者分布式交换机那虚拟机里再搞一层bond还有意义吗答案是有意义而且有时候比物理机更需要。1.1 bond到底解决什么问题bond简单说就是把两块或者多块物理网卡绑定成一个逻辑网卡对外表现为同一个IP对内则根据配置的模式去处理流量的发送和接收。它解决的核心问题有两个第一是冗余一张网卡坏了、一根线断了、一个交换机端口挂了流量自动切到另一张网卡上业务不中断第二是提升吞吐通过特定模式把多张网卡的带宽叠加起来或者把不同连接的流量分布到不同网卡上。这个逻辑放在虚拟机里依然成立。虽然虚拟网卡是软件模拟出来的但它的稳定性并不是100%。某些虚拟化平台的网络驱动在升级、热迁移、资源竞争激烈时会出现网卡假死、丢包飙升的情况。如果虚拟机只有一张网卡这种情况出现时你只能通过VNC或者宿主机控制台去救业务侧早就断了。做了bond之后即使一张虚拟网卡出问题另一张还能把流量顶住。而且虚拟机做bond还有一个物理机没有的好处可以配合虚拟化平台的端口组策略做平滑的网络维护。比如宿主机要进行网络改造、物理交换机要升级配置只要保证虚拟机至少一张虚拟网卡所在的后端链路是通的业务就不会中断。这在大规模虚拟化集群里非常实用。1.2 虚拟化场景和物理机场景的差异刚开始我犯过一个错误直接用物理服务器上那套bond配置思路来处理虚拟机结果出了不少问题。后来才意识到虚拟化场景下有几个差异点是必须重新考虑的。第一个差异是网卡驱动和队列机制。物理机的网卡驱动和硬件队列是直接跟硬件交互的虚拟机的虚拟网卡后端是软件交换。某些模式比如mode 0balance-rr、mode 4802.3ad在物理机上表现很好但在虚拟机上可能受限于后端虚拟交换机的处理能力实际吞吐提升不明显甚至因为乱序导致TCP性能下降。第二个差异是MAC地址漂移问题。虚拟机的虚拟网卡MAC地址是由虚拟化平台管理的某些平台在虚拟机重启或者迁移之后会重新分配MAC。而bond在切换时依赖MAC地址的一致性配置需要格外小心。这个后面专门展开。第三个差异是NetworkManager和服务器的管理习惯。桌面版Linux和某些云镜像默认开启了NetworkManager它跟传统ifcfg配置方式争抢网卡控制权。在物理机上你可能已经关掉了但虚拟机镜像里经常没关干净就会导致bond配置在重启后失效。1.3 适合什么人参考如果你跟我一样维护着一批Linux虚拟机并且这些虚拟机承担着数据库、网关、容器集群节点之类的关键角色那么网卡bond的配置值得你认真看一遍。这篇内容适合下面几类读者需要给虚拟机做双网卡冗余但不知道该选哪种bond模式的人。已经在虚拟机上尝试配置bond但重启后就失灵或者切换测试不通过的人。想深入了解bond链路聚合模式和虚拟化网络之间关系的人。2. 网卡bond的七种模式和选型逻辑Linux内核的bonding模块提供了7种模式从mode 0到mode 6。大多数人记住的就是mode 0、1、4这三个另外几个各有适用场景但比较少见。我先把常用模式的核心逻辑和适用场景讲清楚再给一个虚拟化环境下的选型建议。2.1 四种常见模式对比先看一张我整理的模式对比表这是我在实际项目里反复对照后总结出来的能帮你快速缩小选择范围。模式名称工作机制优点缺点虚拟化环境评价mode 0balance-rr轮询发送从bond的第一个slave到最后一个slave依次发送数据包理论吞吐高两条链路都满载要求交换机端配置静态聚合否则对端可能乱序丢包虚拟机后端虚拟交换兼容性不一谨慎使用适合绑定后流量持续很大的场景mode 1active-backup主备模式只有一张网卡工作主网卡故障后自动切换配置简单不依赖交换机协议只要两个物理链路通就行带宽不叠加主网卡在用备网卡闲着虚拟化环境首选安全可靠mode 4802.3ad动态链路聚合要求交换机启用LACP协议双方协商聚合同时获得冗余和带宽叠加流量负载均衡配置复杂交换机不支持LACP则完全不通如果后端链路允许可以考虑但前提是交换机配合mode 5balance-tlb发送流量根据每张网卡的负载动态分配接收由当前网卡处理不需要交换机特殊配置发送可均衡接收侧只靠一张网卡上行吞吐提升有限可以做但意义不大这里要说一个选择bond模式时的核心思路不要只看理论带宽要看你的瓶颈到底在哪里。如果虚拟机主要承担的是东西向流量对吞吐要求不高但对稳定性要求极高mode 1就是最省心的选择。如果虚拟机是大流量网关且后端物理网络具备LACP条件mode 4才能发挥真实作用。一张表看下来你会明白bond本身不是万能的模式选错反而会搞出一个新的故障点。2.2 虚拟机场景下选型的两个主流答案基于我自己的经验虚拟机环境里最稳的答案永远是mode 1。原因很简单第一它不依赖对端交换机的聚合协议。虚拟机的后端链路可能是标准虚拟交换机、分布式交换机也可能经过了复杂的网络虚拟化设备你根本不清楚中间设备有没有正确配置LACP。mode 1只要链路二层通bond就能工作。第二mode 1的切换逻辑独立、开销小它的状态监测是周期性检查slave网卡的链路状态发现问题就把流量切到备用网卡。这个机制在虚拟化环境中很少误判。如果你的后端网络是明确的物理交换机组并且交换机的聚合口已经配好了LACP那么mode 4也是一个很值得考虑的方案。它能把两张虚拟网卡对应的物理链路同时用起来实际带宽提升明显。我见过不少网关虚拟机用mode 4之后吞吐比mode 1翻了一倍。但前提条件必须确认好后端的虚拟交换机端口要能透传LACP报文很多虚拟化默认配置是不放行未知组播和特定以太网帧的这就导致LACP协商失败。2.3 模式参数和链路聚合协议的一些坑除了选模式bond启动参数里有几个值也容易踩坑。一个是miimon用来设置链路状态监测的时间间隔单位是毫秒。mode 1的默认建议是miimon100也就是每100毫秒检查一次。如果你把它设成1000切换速度就会慢很多用户侧可能已经感知到中断。另一个是fail_over_mac它决定bond在做主备切换时MAC地址怎么处理。物理机上一般不需要设置但虚拟机上因为MAC地址的特殊性经常需要配合设置。使用mode 4的时候还有一个参数需要关注就是xmit_hash_policy。它决定了发送数据包如何选择网卡默认是layer2也就是根据MAC地址哈希。在虚拟机场景虚拟网卡的MAC地址变化相对少如果流量集中到某一对MAC地址上负载均衡效果会很差。这时候可以尝试改成layer34结合IP和端口做哈希。不过这不是随意改的交换机端的负载均衡策略要匹配否则效果适得其反。3. 动手配置双网卡bond完整实操接下来进入正题我以常见的双网卡bond配置为例用的系统是某主流Linux服务器发行版网卡名为eth0和eth1bond接口名为bond0。整个配置过程分五步走环境检查、加载模块、编写配置、重启网络、验证效果。每一步我都把为什么要这么做讲清楚省得你照着抄却不知道为什么。3.1 配置前的检查清单动手之前请务必完成以下检查否则中间很容易反复折腾确认虚拟机管理平台里已经给这台虚拟机添加了两张虚拟网卡并且两张网卡都处于连接状态。确认两张网卡的驱动能被系统正确识别。执行ip link命令应该能看到eth0和eth1都在且状态是UP或者DOWN都行但至少不能是错误状态。确认交换机侧对于要连接的物理端口没有配置单独的访问策略特别是不要启用端口安全检测否则bond的多个MAC会触发告警然后被交换机锁端口。想清楚IP地址应该配置在bond0上而不是eth0或eth1上的任何一个。这是一个新手最容易犯的错误IP配置在物理网卡上bond就只剩下一个空壳切换的时候IP就丢了。3.2 加载bonding内核模块并确认驱动参数绑定bond使用的内核模块是bonding。在配置bond接口之前需要先确认模块已经加载。执行以下命令lsmod | grep bonding如果没有任何输出说明模块没加载用modprobe加载modprobe bonding想让模块开机自动加载可以新建一个配置文件内容写上echo bonding /etc/modules-load.d/bonding.conf模块加载完成后还需要把bond参数配置进去。对于mode 1我推荐的最小参数集是options bonding miimon100 modeactive-backup这一步很多教程会漏掉。如果你不预先在模块配置里写参数后面创建bond0时只能靠网络配置界面里的BONDING_OPTS来指定两者本质上是一样但模块参数在启动早期更早生效减少了网卡刚被拉起时无bonding状态的可疑窗口期。3.3 编写ifcfg-bond0和物理网卡配置以传统ifcfg配置方式为例这是最直观、也最容易排查的方式。先创建bond0的配置文件/etc/sysconfig/network-scripts/ifcfg-bond0DEVICEbond0 NAMEbond0 TYPEBond BONDING_MASTERyes BOOTPROTOnone ONBOOTyes IPADDR192.168.10.10 PREFIX24 GATEWAY192.168.10.1 BONDING_OPTSmodeactive-backup miimon100需要说明的是在较新的网络配置实现中配置方式可能更倾向于用connection配置文件但纯ifcfg体系依然被大量服务器版系统默认支持。如果你用的是NetworkManager管理风格命令方式不同但配置文件原理一样。接着修改两张物理网卡的配置。eth0的配置调整为DEVICEeth0 NAMEeth0 TYPEEthernet BOOTPROTOnone ONBOOTyes MASTERbond0 SLAVEyeseth1的配置类似只是设备名和连接名不同。关键字段是MASTER和SLAVE。MASTER告诉系统这张网卡归属哪个bond接口SLAVE表示它是bond的成员之一。这里不配置IP地址因为IP已经交给bond0了。有些系统里还会看到USERCTLno、NM_CONTROLLEDno之类的参数。我的建议是如果用了NetworkManager就不要用NM_CONTROLLEDno因为会引起混乱如果坚持用ifcfg那我建议干脆彻底停用NetworkManager做到干净统一。3.4 重启网络并验证bond状态配置写完后各有各的重启网络方式。老一点的习惯是systemctl restart network如果你用的是NetworkManager管理模式更规范的写法是nmcli connection reload nmcli connection up bond0无论用哪种方式重启后立刻查看bond状态cat /proc/net/bonding/bond0正常输出里应该能看到Bonding Mode: fault-tolerance (active-backup)以及两个slave接口其中一个状态为active。看到类似下面的信息就说明成功了一半MII Status: up Slave Interface: eth0 MII Status: up Active Slave: eth0然后确认bond0有没有拿到IP地址ip addr show bond0到这里基本的配置链路已经走通了。但我建议你别急着收工因为还有一层验证没有做故障切换是否真的可靠。别再相信“理论上应该没问题”动手把备份网卡顶上去才是硬道理。3.5 故障切换实测拔网线/封端口测试的时候把虚拟机的eth0从虚拟化平台里断开或者直接在虚拟机里执行下面这个操作模拟链路故障ip link set eth0 down这时候再查看/proc/net/bonding/bond0会发现主备状态发生切换原本的active slave变成fail另一个变成active。同时bond0的IP仍然可达ping不会丢包或者只丢一两个包。根据miimon100的配置10毫秒内就能探测到链路变化所以对业务的影响非常小。测完之后恢复eth0正常情况下bond会保持当前的工作slave不变不会立刻切回旧网卡。这种特性叫auto mode也叫非抢占式切换。好处是减少不必要的切换次数降低因切换造成的瞬间抖动。4. 那些年踩过的坑常见问题与排查经验配置bond这件事文档一搜一大把但真正让运维头疼的是那些“按教程配完却不工作”的情况。我在不同虚拟化环境里做过不少次bond配置总结下来至少一半的故障集中在NetworkManager冲突、MAC地址漂移和交换机匹配这几个地方。单独拎出来讲一讲。4.1 NetworkManager和bond配置打架很多云镜像默认开启了NetworkManager但服务器的网络配置文件还是ifcfg的老一套。结果就是两个网络管理机制同时试图控制网卡互相抢设备最后bond0起不来或者起来了但状态异常。如果你确实要用ifcfg方式管理bond最简单的做法是彻底停用NetworkManagersystemctl stop NetworkManager systemctl disable NetworkManager注意一定要disable否则下次重启它又自己跑起来了。然后重启network服务加载bond配置。反过来如果你希望保留NetworkManager那就别用ifcfg那一套直接用nmcli创建bondnmcli connection add type bond ifname bond0 mode active-backup miimon 100 nmcli connection add type ethernet ifname eth0 master bond0 nmcli connection add type ethernet ifname eth1 master bond0这属于不同的配置路线但都能得到bond0。我的经验是在纯服务器环境、且团队习惯传统配置方式的环境里关掉NetworkManager更省事在桌面化的、强调自动配置的发行版里用nmcli反而更符合系统设计。4.2 虚拟机MAC地址漂移导致bond切换失败虚拟机平台里虚拟网卡通常可以配置MAC地址。默认情况下某些平台在创建新的虚拟网卡时会自动生成一个随机MAC。如果创建之后没有固定下来重启虚拟机或者在某些迁移场景下MAC可能变化。而bond的切换逻辑依赖slave设备信息虽然bond本身能容忍slave的MAC变化但上层交换机的MAC学习和报文转发会受影响严重时表现为链路状态正常但数据包出去回不来。解决办法是在虚拟化平台的虚拟网卡配置里把两个虚拟网卡的MAC地址手动固定并且确保不同。同时在bond配置中设置fail_over_macactive让bond切换时继续使用active slave的MAC发送报文减少对端交换机MAC表项的重新学习时间。这里有一点要特别提醒如果两张虚拟网卡设置了相同的MAC地址虚拟化平台很可能直接报错或者让某张网卡无法连接。所以手动指定时一定要让eth0和eth1的MAC不同但它们的MAC都会被bond0的切换逻辑处理业务层面只认bond0的MAC。4.3 交换机端口模式不匹配LACP起不来用mode 4配置LACP时最常遇到的问题就是bond0起来了显示802.3ad模式但是partner state一直不对实际网络就是不通。排查方向是交换机侧。虚拟机的后端链路实际上要经过虚拟交换机和物理交换机两级。虚拟交换机如果端口模式不对LACP报文根本到达不到物理交换机。物理交换机如果聚合口配的是静态模式而不是动态LACP双方状态也不匹配。我遇到过一种情况虚拟交换机把两个网络端口都设成了VLAN trunk物理交换机却只在一个端口上配了access模式结果两张网卡同时发送LACP报文时物理交换机直接认为是环路把端口给error-disable了。这个问题的排查思路是先在虚拟化平台侧确认端口组类型确认是否放行LACP所需的组播和广播报文再到物理交换机上看聚合口状态用命令查看LACP对端信息。如果对端信息里看不到虚拟机的system ID说明报文根本没到物理交换机问题出在虚拟交换机。如果能看到system ID但无法聚合问题多半出在策略不一致上需要逐项比对聚合参数。4.4 重启后bond消失或者IP地址丢失还有一种极其常见的现象第一次配置完bond正常但只要重启虚拟机bond0就没了或者IP地址没了必须手动配置才能恢复。这个问题在大部分情况下和网络服务启动顺序有关。如果bond0的配置依赖bonding模块而模块没有在启动早期加载那么网络服务启动时看不到bonding设备就会跳过bond0的启动。解决办法就是前面提到的把bonding模块加进/etc/modules-load.d/并且把modeactive-backup等参数写进模块配置里让内核在网络服务启动前就准备好bonding能力。另有一些情况是物理网卡的ONBOOT没设置成yes。很多发行版默认物理网卡是no毕竟服务器很少用图形界面管理网络。如果你漏改了这一点系统启动时eth0、eth1都不会被自动拉起bond0自然也就没有slave可以激活。这个坑排查起来非常隐蔽因为你看配置文件会觉得都没问题但实际上每次开机都倒在第一步。4.5 排障速查表把常见的故障现象和排查方向整理成一张速查表方便你以后快速定位。这是我这些年排查网络问题时养成的习惯能省下很多重复操作。故障现象可能原因排查命令/动作bond0不存在bonding模块未加载lsmod grep bondingmodprobe bondingbond0存在但没有IPIP配在slave网卡上检查ifcfg-bond0和ifcfg-eth0的BOOTPROTO、IPADDRbond0状态是down物理网卡未识别ip link查看eth0/eth1状态切换后业务中断MAC漂移或ARP缓存问题检查虚拟网卡MAC是否固定设置fail_over_macactiveLACP协商失败交换机/虚拟交换机策略不匹配查看/proc/net/bonding/bond0对端状态核对聚合配置重启后bond失效模块加载顺序/NetworkManager抢占添加modules-load配置停用NetworkManager流量只走一块网卡模式选型或哈希策略不合理换mode 1确认基础连通再考虑mode 4调参这张表不是让你背命令而是提醒你碰到不同类型的问题时应该去检查哪个层面。网络问题最怕的就是在表层反复试不去看底层状态。5. 一些额外的小技巧除了前面这些主流程我还有一些零散但很实用的经验写在这里供参考。第一测试bond切换前先把monitor脚本准备好。最简单的是用ping从另一台机器持续发流量同时在虚拟机里写一个循环脚本去每秒记录/proc/net/bonding/bond0的状态。这样可以精确知道从链路故障到切换完成用了多久也能证明切换过程中丢包情况。第二如果你准备用bond0承载基于MAC地址的服务比如某些授权软件绑定MAC那么bond0的MAC就成了唯一关键值。切换时如果MAC会变会影响这些服务的合法性判断。这时候需要把bond0的MAC手动设置成一个固定值方法是在ifcfg-bond0里加一行MAC地址配置并设置fail_over_mac0确保任何时候对外的MAC一致。第三在写ifcfg-slave配置时注意不要留DNS和路由配置。很多模板文件里自带GATEWAY字段粘过来后很容易让bond0和slave网卡都产生默认网关路由表混乱。网上有一种现象是“bond配置好了但走外部网络时一直超时”很多就是这种默认网关残留导致的。确定只让bond0持有GATEWAY其他slave只保留DEVICE、BOOTPROTO、ONBOOT、MASTER、SLAVE这五要素。第四如果在虚拟机上做mode 4且后端是分布式虚拟交换机一定要确认两张虚拟网卡是否分布在同一个宿主机上。如果迁移或者配置不当导致一张网卡在一个宿主机、另一张在另一个宿主机LACP的聚合条件就会失效。物理机网卡都在同一台机器上这个问题并不存在虚拟机则需要多考虑一层。6. 最后再分享一点个人心得我在实际配置中发现虚拟机bond这件事最大的风险往往不是命令写不出来而是链路层面的思维没有转过来。你面对的不只是一张虚拟网卡而是一整条跨越虚拟机、虚拟交换机、物理交换机、物理网线的数据通道。任何一个环节对bond模式不支持都可能导致配置看起来对了、实际却半死不活。所以我做虚拟机的bond配置时习惯先做最小化验证先用mode 1做通再考虑要不要mode 4。mode 1虽然不叠加带宽但它能保证业务不中断这种“求稳”思路在虚拟化环境里尤其重要。如果你没有专门的测试窗口我更建议你直接用mode 1不要纠结于那点带宽冗余。等业务验证完、后端网络策略也确认好了再找个维护窗口平滑切到mode 4。另外还有一件容易被忽略的事bond配置完成后一定要把配置文件纳入版本管理同时把/proc/net/bonding/bond0的状态采集到监控系统里。这个文件可是宝贵的状态来源哪天它发生了变化往往意味着链路在频繁切换那就要赶紧排查后端网络了。别等到业务报障了再回头看bond那就慢了。
阅读完成 · 觉得有帮助?