ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

多网卡路由优先级混乱?一文搞懂metric调整方法

多网卡路由优先级混乱?一文搞懂metric调整方法 一台服务器上插了两块网卡一块连着办公网一块连着业务专网。刚装好系统的时候一切正常但重启了几次服务之后业务方突然说“外网不通了”。我登上机器一看ping网关、ping公网IP都能通但业务就是访问不了。最后查出来问题出在默认路由上——流量全从专网那张网卡出去了办公网那张网卡虽然也有默认路由但优先级不对压根没被选中。这种“多网卡导致路由优先级混乱”的故障在运维、虚拟化、办公网部署里太常见了。解决办法也很固定调整网卡的路由metric路由度量值让系统明确“走哪扇门出去”。metric这个概念表面上只是个数字但搞懂它背后怎么生效比单纯敲几条命令重要得多。这篇文章就把我这些年调metric踩过的坑、验证过的方法一次性写清楚覆盖Ubuntu、openEuler、Windows和VMware虚拟机这些常见环境。1. 多网卡上流量为什么总走“错门”——metric到底解决什么问题1.1 一个真实到大家都遇过的现场先说个我在200人规模企业里实际处理过的场景。一台Ubuntu 22.04服务器双网卡eth0接办公网网关192.168.1.1eth1接业务专网网关10.10.10.1。服务器上跑着一个内部系统办公网里的同事要访问它但它又要访问专网里的数据库。配置的时候两个网卡都设了默认网关。结果系统一重启内部系统就间歇性抽风有时候办公网的人能访问有时候不能。看路由表发现ip route输出里两条default路由都在但实际出去的流量全走了metric值更小的那条——也就是专网。办公网的人访问服务器请求从eth0进来但服务器回包时从eth1出去连接根本建不起来。这就是典型的非对称路由。原因很简单Linux内核在选择默认路由时不看网关通不通只看路由的优先级metric值。谁的metric小默认路由就归谁。系统不会聪明到“自动检测哪条网关是通的”它严格遵守路由表的“最优匹配”规则。1.2 metric的“越小越优先”到底怎么理解metric的全称叫路由度量值不同系统里叫法不一样Linux的route命令显示为MetricWindows里叫“接口跃点数”Interface Metric路由协议里也称“开销”Cost。但核心规则高度统一数值越小优先级越高。可以把它想象成一个十字路口的指示牌优先级两个指示牌都写着“前方所有目的地”但系统只会看牌子左上角的数字数字小的那个牌子被优先采纳。这不是说大数字的牌子就完全没用只有当小数字那条路由不可达、被删除或失效时系统才会去瞅大数字的路由。metric值的来源通常有两类手动配置管理员在静态路由或网卡配置里显式指定。自动生成DHCP分配的网关、NetworkManager、systemd-networkd会根据接口类型有线、无线、虚拟网卡自动赋一个默认值比如DHCP默认的metric100。理解这一点就能解释很多“明明我改了路由表却不生效”的怪现象可能是DHCP客户端或网络管理工具在你重启网络服务时把默认值重新写回去了。1.3 路由选路逻辑系统不是随机挑网卡出门Linux内核选路由的顺序大致是这样的先根据目标IP查找路由表如果有精确匹配的主机路由、子网路由直接走如果都没有才轮到默认路由0.0.0.0/0。当存在多条默认路由时内核会比较它们的metric选最小的一条。这里有个容易忽略的点默认路由是全局性的但也受源地址影响。所谓源地址就是你本机访问外部时用什么IP作为“发件人”。同一个服务器可以有两个IP系统发起新连接时内核会根据路由表反向决定源IP——选中的是哪个网卡的网关路由源IP就取那个网卡的地址。这就意味着调metric不光是改一条路由的优先级本质上是在告诉系统“这台机器的对外身份用哪个IP”。所以在多网卡场景里合理设置metric的意义不只是“让流量走对门”还直接影响到对外通信的源地址、访问日志里的来源IP、以及基于IP的防火墙策略是否匹配。我见过不少团队在防火墙上配了规则却因为源IP经常“变脸”导致权限时好时坏最后发现就是metric没固定住。2. 动手前先看清现状网卡优先级排查三板斧调整之前一定要先看清楚当前状态。没有这一步很多配置会改错方向甚至把原本能用的网络改坏。2.1 看一眼当前路由表长什么样最直接的办法ip route show这行命令会列出所有路由。重点关注带default字样的行例如default via 192.168.1.1 dev eth0 proto static metric 100 default via 10.10.10.1 dev eth1 proto dhcp metric 10metric 10和metric 100一眼就能看出优先级。上面这个例子里eth1专网那个网关的metric更小所以当前默认路由走得是eth1。如果两条default路由的dev一样比如都是eth0那就说明你在同一块物理网卡上配了多个网关或VLAN这种情况要额外留意往往是网关冲突需要先理清哪个是真网关再谈metric。查看更详细的策略路由规则ip rule show默认状态下会输出类似这样的内容0: from all lookup local 32766: from all lookup main 32767: from all lookup default一般场景用main表就够了除非你有过ip rule add的需求否则先别动策略路由。2.2 从/proc/net/route里读原始数据ip route输出的是格式化好的信息。有时候我想确认系统底层的原始数据或者写脚本判断优先级时会看这个文件cat /proc/net/route输出是十六进制格式的第一列是网卡名第二列是目标地址第三列是网关后面依次是Flags、RefCnt、Use、Metric等。Metric那一列就是这个接口的度量值注意它是十六进制显示比如64代表十进制100。这种直接读内核数据结构的方式适合排查“为什么ip route看起来正确但实际流量不对”的疑难情况。我自己遇到过Netfilter规则或策略路由导致路由表显示正常、实际走法异常的案例看原始表能帮助判断内核到底维护了什么。2.3 确认你的网卡现在处在“几路同时可用”的状态检查两块网卡的物理链路状态ip -br link showUP状态表示网线插着DOWN或者NO-CARRIER说明链路断开一般情况下内核会移除这条链路上的路由。如果你发现路由表里还有对应条目但物理链路已经DOWN那可能是路由配置问题也可能是有线网卡没检测到载波。还要看IP地址是否配置正确ip addr show重点确认网卡名、MAC地址、IPv4地址、子网掩码是否和预期一致。VMware虚拟机里常见的坑是两块网卡都拿到了相同网段的IP但网关不同这种环境下调metric意义不大得先改IP规划。这三板斧做完基本能判断出当前网络处在什么状态哪条网卡是主用、哪条是备用、当前默认路由是谁。接下来改metric才有据可依。3. Linux下修改metric临时生效、持久化配置、以及systemd-networkd的坑Linux发行版多网络管理工具也杂。但metric配置的思路是一致的要么改路由表本身要么改“生成路由表的上层配置”。我建议先学会手动改路由表验证效果再落到配置文件里固化。3.1 临时改法手改路由表适合验证不重启验证metric调整是否有效最快的办法是ip route replace# 把到192.168.1.1的默认路由metric改成50 sudo ip route replace default via 192.168.1.1 dev eth0 metric 50这里有几个关键点replace和add不一样add在已有同网段to default路由时会报“RTNETLINK answers: File exists”replace会把同目的已有路由替换掉。必须有dev eth0参数否则系统找不到出口网卡。改完之后立刻验证ip route show别忘了再用ip route get 8.8.8.8或任意外网IP看实际走向ip route get 8.8.8.8输出里会明确显示dev eth0还是dev eth1这个命令判断实际选路非常好用比单纯看路由表直观得多。临时改法的问题在于重启网络或执行systemctl restart NetworkManager后失效所以它只适合验证方案不适合生产环境固化。3.2 Ubuntu 22.04 netplan一条yaml改完Ubuntu 22.04默认用netplan管理网络配置文件一般放在/etc/netplan/目录下名字可能是01-network-manager-all.yaml或00-installer-config.yaml。先看看你机器上用了哪个ls /etc/netplan/要调整metric打开对应的yaml文件在网卡的routes里加metricnetwork: version: 2 renderer: networkd ethernets: eth0: dhcp4: true dhcp4-overrides: route-metric: 50 eth1: dhcp4: true dhcp4-overrides: route-metric: 200如果用的是静态IP就在routes下加network: version: 2 renderer: networkd ethernets: eth0: addresses: - 192.168.1.10/24 routes: - to: default via: 192.168.1.1 metric: 50 eth1: addresses: - 10.10.10.10/24 routes: - to: default via: 10.10.10.1 metric: 200这里说几个容易踩的坑dhcp4-overrides里的route-metric只对DHCP获取的默认路由生效如果你同时写了静态routes静态的优先级会覆盖DHCP自动路由的行为。修改yaml后一定要跑sudo netplan try这个命令会先试应用配置如果一段时间内没确认比如网络断了会自动回滚防止把远程连接的机器改到失联。yaml文件的缩进非常严格一个空格错位就会应用失败。我见过太多人把routes写成网卡平级导致netplan直接报错。应用成功后用ip route show看效果两条default路由的metric应该就是你设定的值了。3.3 openEuler/兼容RHEL系nmcli和ifcfg文件两种走法openEuler和CentOS系常见的网络管理工具是NetworkManager它也支持纯ifcfg文件配合network.service。先说怎么用nmcli改metric。假设网卡连接名是eth0把它作为默认出口metric改成50# 查看当前连接名 nmcli connection show # 修改eth0连接的默认路由metric sudo nmcli connection modify eth0 ipv4.route-metric 50 # 重新激活连接让它生效 sudo nmcli connection up eth0如果不用默认路由而是想针对某条静态路由设metric可以这样sudo nmcli connection modify eth0 ipv4.routes 192.168.100.0/24 192.168.1.254 metric20ipv4.route-metric是“这个接口上所有自动/默认路由的metric基础值”和ipv4.routes的metric是两回事别混为一谈。如果你偏爱传统的ifcfg文件方式直接编辑/etc/sysconfig/network-scripts/ifcfg-eth0TYPEEthernet BOOTPROTOnone DEVICEeth0 ONBOOTyes IPADDR192.168.1.10 PREFIX24 GATEWAY192.168.1.1 METRIC50注意GATEWAY指定默认网关后METRIC控制这个网关在路由表里的优先级。如果两个网卡都写了GATEWAYMETRIC较小的那个会成为主默认路由。修改完需要systemctl restart network或nmcli connection reload取决于系统是否启用了network服务不是改完立即生效。openEuler默认启用了NetworkManager但在一些无桌面服务器上可能同时存在network.service。如果两个服务同时在管同一块网卡容易产生路由表混乱。我的建议是用nmcli管理连接就停用network.service用ifcfg就禁用NetworkManager避免“两个包工头管一个工地”。3.4 别忽略DHCP给你偷偷追加的metric这里有个非常常见的坑当你手动设置了metric重启网络后发现路由表里的metric值变了——不是你设的那个数。原因多半是DHCP客户端如dhclient、systemd-networkd下载路由时给网关加了一个“自动metric”。在Ubuntu 22.04的netplan里就有一个dhcp4-overrides的选项专门用来控制DHCP分配的路由metric。如果不设置systemd-networkd会依据接口类型给默认值有线网卡通常是100无线网卡通常是600左右。这意味着你即使手动加了静态事件如果DHCP也同时在下发两者之间会互相覆盖最终哪个生效取决于先后顺序和协议优先级。排查思路很简单如果配置了metric但路由表显示值不对先看是不是DHCP在捣鬼用cat /var/lib/dhcp/dhclient.leases如果用的是dhclient能看到有没有routers和interface-mtu这些字段。另外NetworkManager的管理范围里你还可以在“连接”级别上设定自动获取IP时是否应用DHCP下发的路由nmcli connection modify eth0 ipv4.ignore-auto-routes no但更靠谱的做法是显式指定metric让它成为静态路由的一部分别指望DHCP自动生成的metric能稳定。4. Windows、VMware虚拟机里的metric配置没那么复杂很多人以为只有Linux要调metric其实Windows多网卡场景一样会遇到。而且VMware虚拟机里配双网卡底层逻辑也绕不开metric。4.1 Windows图形化改metric和PowerShell改法Windows网卡的metric叫“接口跃点数”。桌面场景最常见的需求是笔记本同时连着Wi-Fi和有线网希望优先走有线。Windows默认会自动计算跃点数有线一般比无线低但偶尔会被自动计算搞出相反的优先级。图形化改法打开“网络连接”窗口ncpa.cpl。右键目标网卡选择“属性”。选择“Internet协议版本4 (TCP/IPv4)”点击“属性”。点击“高级”按钮勾掉“自动跃点”在“接口跃点数”里填入数字比如5。确定保存。PowerShell改法更快# 查看所有网卡接口和当前跃点数 Get-NetIPInterface -AddressFamily IPv4 | Select-Object InterfaceIndex, InterfaceAlias, InterfaceMetric # 把指定接口的metric改成5 Set-NetIPInterface -InterfaceIndex 12 -InterfaceMetric 5InterfaceIndex怎么找Get-NetIPInterface输出里第一列就是。这里要留意Windows的metric同样越小越优先所以想“让有线优先”有线的metric设小值无线的设大值或不改让它自动算出一个稍大的数值。改完之后验证route print -4命令输出里的Metric列可以看到每个网段对应的跃点数。4.2 VMware虚拟机双网卡和物理机多网卡的同与不同VMware虚拟机里的双网卡本质上是虚拟网卡连接到了不同的虚拟网络。常见组合是一个NAT网卡vmnet8用来访问外网一个Host-Only网卡vmnet1只和宿主机互通。理论上两块网卡同时挂上虚拟机系统内部的路由选择和物理服务器完全一致——还是要看metric。但有个特殊点VMware虚拟网卡默认情况下可能会自动生成一个“默认网关是宿主机虚拟网卡”的路由。比如NAT网卡的默认网关一般是vmnet8的网段地址通常为192.168.x.1或192.168.x.2Host-Only网卡没有默认网关或者也会生成一条到宿主机网络的路由。如果两块网卡都配了默认网关虚拟机内部就会面临“到底走哪个网关”的抉择这同样靠metric解决。我在VMware里调metric的步骤和前面Linux方法完全通用但有个细节比物理机更常见虚拟机的两块网卡可能在同一个网段。这时候改metric没有意义因为进程访问同一网段时直接ARP广播根本不用默认路由。必须先保证两块虚拟网卡属于不同的子网再谈网关优先级。另外ESXi环境里如果虚拟机使用了多个端口组如不同iSCSI存储网络也建议把存储网络的网卡metric设得比业务网络低避免vMotion或备份流量占用业务带宽。实际配置在虚拟机操作系统内部改和物理机没有区别。5. 实战案例一台服务器同时连办公网和业务专网的部署记录这个案例比较典型我完整走一遍配置过程可以直接抄作业。机器环境openEuler 22.03双网卡eno1连办公网eno2连业务专网。5.1 需求描述与拓扑eno1办公网192.168.1.20/24网关192.168.1.1。办公网同事需要通过这个IP访问服务器上的协同办公服务。eno2专网10.10.10.20/24网关10.10.10.1。服务器需要访问专网里的数据库、文件服务等资产。要求默认情况下办公网和专网都能访问但主动外访的默认出口必须是办公网专网只用于访问专网内部资源。因为业务方希望在办公网防火墙上做策略不希望服务器以专网IP主动访问公网。这个需求如果用一句话说就是把办公网的metric调小专网的metric调大但两个网络都要通。5.2 初始状态、问题表现刚装好系统时我在两个网卡的ifcfg文件里都写了GATEWAY重启网络后查看路由表default via 10.10.10.1 dev eno2 proto static metric 100 default via 192.168.1.1 dev eno1 proto static metric 101专网网关的metric比办公网小1系统把专网当成了默认出口。结果就是服务器主动访问公网时源IP是10.10.10.20这在办公网防火墙上直接被抓为“来自未知来源”好多服务被拦。办公网用户访问服务器倒是可以通但服务器去连接公网接口时经常出现超时。这个metric为100和101的差异是NetworkManager根据网卡名称排序生成的不是人为指定非常“随缘”。生产环境不能依赖这种自动分配的顺序。5.3 配置过程、验证步骤第一步修改eno1对应的ifcfg文件把metric改成10sudo vi /etc/sysconfig/network-scripts/ifcfg-eno1在文件里加入或修改METRIC10。同时确保BOOTPROTO是none或static。eno2的metric设置为200让专网变成次选sudo vi /etc/sysconfig/network-scripts/ifcfg-eno2 # 加入 METRIC200第二步重启网络服务。如果用的是NetworkManagersudo nmcli connection reload sudo nmcli connection up eno1 sudo nmcli connection up eno2如果用的是传统的network服务sudo systemctl restart network注意如果两个管理服务同时存在务必确认当前生效的是哪个。我建议在openEuler上只保留NetworkManager因为network.service和NM对ifcfg-METRIC的支持程度不太一样容易白改一场。第三步查看路由表ip route show default via 192.168.1.1 dev eno1 proto static metric 10 default via 10.10.10.1 dev eno2 proto static metric 200办公网排在最前符合预期。第四步验证默认出口ip route get 8.8.8.8 # 输出中应显示 dev eno1访问专网内部资源时因为目标10.10.10.0/24有直连路由根本不会走default所以直接访问数据库没问题。第五步验证办公网同事访问服务器在办公网一台PC上ping 192.168.1.20以及尝试访问业务端口。关键是反向流量路径服务器从eno1收到请求回包时看路由表因为源IP是192.168.1.20而ip rule默认main表里对这个数据的查表顺序一致最终也走eno1返回避免了非对称路由。这里有个细节值得多说一句当服务器只有一张网卡有默认网关时入站请求从哪个网卡进来回包也大概率从哪个网卡走因为目标IP是办公网段走直连路由。但当两个网卡都有默认网关且有非对称路由风险时光调metric不一定能解决所有回包问题。更稳的思路是给回包流量加策略路由不过那是另一个话题大多数人其实用不到先不展开。配置完成后跑了三天办公网防火墙的拦截日志里再也没有出现来自10.10.10.20的公网请求整体稳定。6. 排查技巧与常见问题速查表改metric这件事操作不复杂但出问题时排查链比较长。我把实际运维中遇到的高频问题整理成一张速查表照着查能省不少时间。现象可能原因排查/解决办法改了配置文件路由表不变网络服务没重启或管理工具冲突确认是NetworkManager还是network.service在管执行对应的reload/restart路由表改了但实际流量不从预期网卡走存在更小的metric路由或策略路由规则ip rule showip route get 目标IP看实际选路两块网卡同网段metric不起作用同网段是直连路由不查default改网络规划确保不同网卡在不同子网重启后metric被重置DHCP客户端覆盖在netplan里用dhcp4-overrides.route-metric显式锁定改metric后办公网网民无法访问服务器非对称路由确认回包路径必要时加策略路由按源地址选路Windows改跃点数后不生效DHCP仍然在下发路由在高级设置里勾掉“自动跃点”并手动填数值检查是否有多个网卡竞争VMware里两块虚拟网卡外网时通时不通两块网卡都设了默认网关保留一个网关另一个网卡只配IP不加GATEWAY或调低其metric几条实战心得都是踩过坑才总结的改metric别贪心差一个数量级足够。比如办公网设10专网设100优先级已经非常明确。设成1和2虽然也可以但一旦需要往后插新网卡你会发现自己没有足够数字空间了。改完一定要验证实际选路不只停留在看路由表。ip route get是必做的验证步骤。有些场景下策略路由优先级高于路由表光看ip route会误导你。不要再手动改/etc/iproute2/rt_tables这种底层文件了除非你有明确的策略路由需求。正常情况下metric配置完全够用动策略路由表反而容易把系统搞到网络全断。备份配置文件再动手。netplan和ifcfg的语法容错率极低改之前cp一份原文件改完发现不对立刻cp回去比重新写快得多。至于“改完网络断了怎么办”这种情况尤其是远程服务器我强烈建议先写好一个自动回滚脚本或者至少确认有一个带外管理通道比如IPMI能进去。等手头有可以随时物理接入的机器再放心大胆地改。真实生产里因为调metric导致SSH断连、人不在机房、最后只能让同事跑一趟的教训我都见过不止一次。metric这个东西你说它简单吧命令就那么几条说它复杂吧牵扯到系统选路、DHCP行为、网络管理工具策略任何一环不对都会出幺蛾子。但把原理捋清楚、验证步骤养成习惯之后它反而是多网卡服务器里最可控、最容易定位的配置项之一。我自己现在每配一台双网卡机器第一件事就是检查默认路由的metric把优先级明确写进配置里然后顺手把验证命令记录到交接文档里。这个习惯帮我少处理了不知道多少“网络时好时坏”的工单。
返回列表