ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

CentOS双网卡路由优先级配置:Metric与策略路由实战指南

CentOS双网卡路由优先级配置:Metric与策略路由实战指南

CentOS装双网卡,十个运维有九个都踩过“流量不走对的网卡”这个坑。明明内网口接了交换机,外网口接了宽带,系统重启之后,外网流量偏偏跑去挤内网口,导致业务通不了。这事儿说大不大,说小能把人逼疯。我做了多年运维,给内部团队排障时,这类“双网卡优先级混乱”的问题占了网络类故障的三成以上。后台看路由表,两条默认路由都在,Metric值还一模一样,谁能想到Linux选路这么“耿直”。

这篇东西就是给正在被双网卡折磨的朋友看的。不管是新装的服务器,还是接手别人配过的老机器,只要你想让多块网卡按你的意图走流量,都得搞清楚路由优先级这套底层逻辑。我会把原理拆开揉碎,再贴出完整可用的配置步骤,最后聊聊我踩过的坑。不想让内网外网互相打架,往下看就对了。

1. 双网卡“分身乏术”的根源:路由表决定流量方向

1.1 网卡多没用,关键看系统怎么选路

很多人有个直觉:服务器上有两块网卡,一块配了内网IP,一块配了外网IP,系统自然会各走各的,互不干扰。这个想法只对了一半。网卡只是物理出口,真正决定数据包从哪里出去的是内核里的路由表,也就是常说的 FIB(Forwarding Information Base)。

我用个生活里的例子解释一下。你家住的小区有两个门,一个南门通向城市主干道,一个北门通向单位方向。你出门之前会先想走哪个门更顺路。操作系统也一样,发一个数据包前,先看路由表,找一条最匹配的路径。问题在于,当系统意识到目标地址不在任何一个已知网段时,它就走默认路由。默认路由通常由网关配置生成,如果两块网卡都配了网关,就等于小区里立了两块写着“出门右转”的指示牌,而且指向相反的方向。

这时候优先级就上场了。规则很简单:Metric 值小的胜出。就像两个导航软件同时报不同路线,系统更信任那个“距离更短”的方案。实际工作中,绝大多数双网卡选路乱走,根子都在默认路由和 Metric 值配置上,而不是网卡本身有问题。

1.2 网卡命名变来变去,坑了多少人

聊优先级之前,还得先把一个更容易踩的坑摆出来:网卡名字。老运维习惯了eth0、eth1那套命名,CentOS 7 开始换成了ens33、ens160、eno1这种基于 BIOS 位置或总线信息的名字。你看着像乱码,其实里面藏着“物理位置顺序”的编码。

这跟优先级有什么关系?关系大了。很多一键安装的脚本或者手敲的配置,会把“第一块网卡”当成“内网网卡”,写死在/etc/sysconfig/network-scripts/ifcfg-eth0里。结果换了新机器,原来的eth0现在叫eno16777736或者ens256,配置文件里的DEVICE=eth0根本找不到对应设备,等于没配。

更麻烦的是,如果你有两块网卡,系统按什么顺序分配名字,取决于 PCI 总线枚举顺序,而这个顺序有时候会跟物理插槽对不上号。你明明把内网线插在 1 号口,系统却把这个口识别成第二块网卡。所以做任何优先级配置前,第一步永远是先确认哪块网卡对应哪个接口,用ip link一眼看清 MAC 地址,再跟交换机端口上的标签对一对,避免对着空气配置。

2. Metric 优先级机制:选路规则的底层逻辑

2.1 路由表里到底存了什么

Linux 的内核路由表可以简单理解成一张 Excel 表格,每一行是一条路由记录。用ip route show命令能看到类似这样的输出:

default via 192.168.1.1 dev ens33 proto static metric 100 default via 10.0.0.1 dev ens160 proto static metric 200 192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.100 metric 100 10.0.0.0/24 dev ens160 proto kernel scope link src 10.0.0.100 metric 200

每一行里,via是下一跳地址,dev是出口网卡,metric是这条路由的权重。数字越小,优先级越高。当系统要访问一个公网 IP 时,前两条默认路由都能用,它就会选metric 100那条,也就是从ens33出去。

这里有个细节容易被忽略:proto kernel那几条是系统配置 IP 时自动生成的直连路由,Metric 默认按网卡上配置的值来。而proto static那条默认路由,到底带多少 Metric,取决于配置来源。

2.2 为什么两块网卡会造成“抢流量”

如果你给两块网卡都配了网关,系统就会看到两个默认路由,它们会形成一个竞争关系。没有显式指定 Metric 时,CentOS 系统会根据网卡自身的某些属性自动分配一个值,但这个值的大小并不符合你的预期,导致内网流量跑到外网口去兜圈子,外网请求又从内网口出去,直接断网。

用通俗的话讲,这就是“两头都想管,结果两头都管不好”。不少刚入门的工程师会试图用route del default删掉一条默认路由来“解决”,这个操作有两个问题。第一,重启后配置丢失;第二,如果内网网卡的网关被删了,内网跨网段访问反而会失败,因为内网不同 VLAN 之间的通信也需要网关帮忙转发。

真正标准的做法不是删除路由,而是给每块网卡设定明确的 Metric 值。让系统永远优先走你指定的那扇门,另一扇门作为备用。只要路径判断规则清晰,双网卡完全可以稳定共存。

2.3 两张网关卡谁当“老大”,先想清楚业务

动手配置之前,你得先想清楚哪块网卡是“主路”,哪块是“备路”。一般有两种常见场景。

第一种,内外网隔离。ens33走办公外网,用于访问公网;ens160走机房内网,给业务系统之间互通。这种场景下,默认路由应该指向外网口,内网口只保留直连路由,不要给它配默认网关,或者说把它的 Metric 值调到很大,让它永远只承担内网段通信。

第二种,双线路冗余。两块网卡都接到两个不同运营商或者两个不同交换机上,走的是负载均衡和故障切换的思路。这种情况默认路由可以有两条,但必须保证同等的 Metric,或者用主备模式让其中一块稍高一些。

配置文件里一句话就能控制:METRIC=100。在/etc/sysconfig/network-scripts/ifcfg-对应的网卡配置文件里加上这个参数,重启网络后,内核就会按照这个值排序路由。别小看这一行,它是整篇操作里最关键的一步。

3. 手把手配置:让流量按你的意图走

3.1 先给网卡“验明正身”

我这里直接用一台 CentOS 7.9 的虚拟机做演示,系统里有两块网卡,分别为ens33和ens160。运行ip addr show能看出两块网卡的 IP 分别是192.168.1.100和10.0.0.100。先确认路由状态:

# 查看当前所有路由 ip route show # 或者用传统命令 route -n

如果输出里看到两条default路由,接着往下做。找不到默认网关的直连网段,可以手动给网卡配置网关。

3.2 临时优先级配置:一条命令立即生效

如果你只是临时测试,想验证把流量切到某个网卡的效果,不用改任何配置文件,直接用ip route命令动手就行。

# 假设当前默认路由走了 ens160,想切到 ens33 # 先加一条高优先级默认路由,metric 100 sudo ip route add default via 192.168.1.1 dev ens33 metric 100 # 再把原来那条默认路由的 metric 改成 200,作为备用 sudo ip route replace default via 10.0.0.1 dev ens160 metric 200 # 确认结果 ip route show

这里有个小细节:ip route add如果发现已经存在同样条件的默认路由,会报RTNETLINK answers: File exists的错误。我习惯用ip route replace来覆盖旧记录,这样不用先删再加,少一步操作。

命令生效后,立刻用ping验证一下出口方向。ping -I ens33 8.8.8.8指定从ens33口发测试包,确认公网能通。再ping -I ens160 10.0.0.2验证内网口没问题。这种“指定出口”的 ping 方式是排查双网卡问题的神器,比普通 ping 更直观。

3.3 永久配置修改:重启也不丢

临时命令只能撑到下次重启,真正要落库的内容写在网卡配置文件里。进入/etc/sysconfig/network-scripts/,编辑两块网卡的 ifcfg 文件。

先看ifcfg-ens33,这是外网口:

TYPE=Ethernet BOOTPROTO=static NAME=ens33 DEVICE=ens33 ONBOOT=yes IPADDR=192.168.1.100 NETMASK=255.255.255.0 GATEWAY=192.168.1.1 METRIC=100

再看ifcfg-ens160,这是内网口:

TYPE=Ethernet BOOTPROTO=static NAME=ens160 DEVICE=ens160 ONBOOT=yes IPADDR=10.0.0.100 NETMASK=255.255.255.0 # 不配置 GATEWAY,或者配置一个很大的 METRIC METRIC=200

关键点就在这:内网口不要写GATEWAY=,只保留METRIC=200。如果你给内网口也写了默认网关,系统就会生成两条默认路由,哪怕 Metric 分开了,某些情况下数据包也可能因为策略路由规则走得乱七八糟。

保存后重启网络服务:

sudo systemctl restart network

重启完再执行ip route show,看看默认路由是不是只剩一条。正常情况下,走公网的那条应该排在最前面,Metric 100。内网口的路由表里只有直连的 10.0.0.0/24 网段和备用默认路由,优先级低,平时不参与选路,但链路出问题时会自动接管。

3.4 NetworkManager 参与时多留个心眼

CentOS 7 及以上的版本里,NetworkManager 是否在运行,直接决定了 ifcfg 文件改完管不管用。默认安装的 CentOS 7 虽然桌面版带 NetworkManager,但服务器版多数还是用 network 脚本。你可以在修改完配置文件后运行:

systemctl status NetworkManager systemctl status network

如果 NetworkManager 是 enabled 状态,它有自己的连接管理逻辑,跟你手改的 ifcfg 文件之间偶尔会打架。我遇到过一次诡异情况:明明ifcfg-ens33里写了METRIC=100,重启后路由却变成了metric 0。查了半天,发现 NetworkManager 接管了网卡配置,自动生成了新的连接配置。

遇到这种情况要么直接禁用 NetworkManager,让 network 脚本完全接管:

systemctl stop NetworkManager systemctl disable NetworkManager systemctl restart network

要么在 NetworkManager 的 nmcli 里显式设置 route-metric:

nmcli connection modify ens33 ipv4.route-metric 100 nmcli connection up ens33

两种方案任选一种,尽量别混着用。老运维普遍偏爱关闭 NetworkManager 的朴素方式,统一由 network 命令控制,排查问题也少绕弯子。

4. 策略路由进阶:比 Metric 更细粒度的控制

4.1 同一个包里既要内网又要外网怎么办

Metric 只能解决“默认路由走哪”的问题,但很多真实业务场景比这个复杂。比如服务器要访问10.10.20.0/24的内网开发环境,同时又要上公网下载软件包。如果内网口和外网口都配了网关,光靠 Metric 很难让特定网段总走内网口。

这时候需要引入策略路由。通俗地说,Metric 是给所有流量定一个默认方向,而策略路由是给特定流量画一条“专属路线”。

CentOS 里策略路由主要通过两个文件实现:/etc/iproute2/rt_tables和/etc/sysconfig/network-scripts/rule-这一类规则文件。老手习惯直接在/etc/iproute2/rt_tables里加一行自定义路由表:

200 inernet

然后在 rc.local 或专门的脚本里写入:

# 添加独立路由表内容 ip route add 10.10.20.0/24 via 10.0.0.1 dev ens160 table inernet # 从特定网段来的流量查找这张表 ip rule add from 192.168.1.100/32 table inernet

这样凡是源地址为192.168.1.100的数据包,都会优先查找inernet路由表;找不到匹配项回退到主路由表。这种“按来源选路”的方式比纯 Metric 更精细,适合多网卡、多网段混布的环境。

4.2 什么时候该用策略路由,什么时候用 Metric 就够

这是我的经验判断:如果只是上下级网络环境的简单隔离,比如一台机器既要连办公网又要连测试网,Metric 足够。配置量小,排障也直观,一眼能看懂。

但服务器还要承担多个网段的互通,或者你有多块网卡都有流量进出需求,比如防火墙、负载均衡器这类设备,建议尽早规划策略路由。不同的业务网段走不同的出口,这也是生产环境最常见的姿势。

策略路由的配置要更小心,出错的影响范围也更大。我建议先在测试机上把规则完全调通再上生产。别在生产环境验证,这个锅我背过。

5. 实测排障:双网卡配置的那些坑

5.1 内网ping通,外网不通

症状:两块网卡都配了 IP,内网互访正常,公网请求超时。排查ip route show,发现默认路由走了内网口。原因十有八九是ifcfg-ens160里写了GATEWAY=10.0.0.1,系统拿着这个网关去公网,结果被设备挡了回来。

解决办法很简单,把内网口的网关删掉,或者像上文一样,给两块网卡设置不同 Metric。内网通信走直连路由也能通,不依赖默认网关。如果业务要求内网必须跨网关访问其他 VLAN,那么就单独为那个 VLAN 添加静态路由,而不是给整块网卡配默认网关。

ip route add 172.16.0.0/12 via 10.0.0.254 dev ens160

这条命令只影响 172.16.0.0/12 网段的流量,不会干扰默认路由选择。

5.2 改了配置文件重启网卡,路由没变化

这类问题一般分三种情况。第一,network服务其实没有真正重启,systemctl restart network有时候因为配置错误只报个警告就退出,不会重读路由。用journalctl -xe看看 network 服务日志。

第二,NetworkManager 又偷偷接管了。上文已经给了禁用方法,关键是先确认 NetworkManager 状态。

第三,也是最容易忽略的,ifcfg 文件名跟网卡实际名称不匹配。你编辑了ifcfg-ens33,但系统里那块网卡实际叫ens33f0。这种情况network脚本启动时会报Device ens33 does not seem to be present。用ls /etc/sysconfig/network-scripts/核对文件名,再用nmcli dev或者dmesg | grep eth找到真实的设备名。

5.3 DNS 解析慢,感觉流量没走该走的网卡

双网卡配置完成后,网络通是通了,但访问外网偶尔卡顿。这时候别急着怀疑路由,先检查/etc/resolv.conf。这个文件在配置 DHCP 或 NetworkManager 时会被自动重写,可能把内网 DNS 地址和外网 DNS 地址混在一起。如果内网 DNS 对外网域名解析失败,解析过程就会卡到超时。

我的做法是把内网 DNS 只放在内网口对应的网卡配置里,外网口只保留公网 DNS。具体操作是在 ifcfg 文件里设置DNS1=223.5.5.5(外网),内网口则只放内网 DNS。CentOS 的 network 脚本会合并所有网卡的 DNS 配置写入 resolv.conf,顺序就是网卡启动顺序。多块网卡的 DNS 互相挤占导致查询超时,这个问题排查起来相当隐蔽,值得记在速查本上。

5.4 不知道哪块网卡对应哪个物理接口

实际机房环境里,服务器上一排网口,系统里的ens33、ens160到底对应哪一个?拿网线和手电筒去机房对照是办法,但太慢。

更好的办法是用ethtool命令让网卡灯闪烁:

ethtool -p ens33 10

执行后ens33对应的物理网口灯会闪烁 10 秒,肉眼直接识别。这是我最常用的物理定位手段,比拔线测试高效得多。如果ethtool没安装,先yum install ethtool。

5.5 MAC 地址配置错误引发的启动失败

给新网卡配置时,直接复制了旧配置文件,结果忘了改HWADDR或MACADDR行,导致网卡服务启动报错。系统会提示配置里的 MAC 跟设备实际 MAC 不一致。

如果你配置的是静态网卡,HWADDR这一行可以删掉,或者改成对应网卡真实 MAC。一般安装系统后,ifcfg 文件里会自动生成正确的 MAC,除非你手动编辑时改乱了。我遇到过不少人直接把 uuid 和 mac 复制了一遍,结果系统启动后串到另一块网卡上,路由表也跟着错。每次编辑 ifcfg 文件,第一件事就是核对 DEVICE、NAME、MAC 三者一一对应。

6. 备份与回滚:改配置前先留一手

双网卡配置的改动看似简单,实际出错时可能直接导致 SSH 断开。你在远程改路由表的时候,一旦把默认路由指向了不通的网关,当前连接立马断掉,人还没在机房,那就真的只能喝西北风了。

我的习惯是动手之前先备份关键文件。最省事的方式:

cp -a /etc/sysconfig/network-scripts/ /root/network-scripts.bak.$(date +%F) cp -a /etc/iproute2/rt_tables /etc/iproute2/rt_tables.bak

改完后测试通过,备份文件留两三天再删,以防后续调到别的服务时回溯。

如果远程改了路由瞬间断开,短时间内系统会重新拨号或启动脚本恢复?基本没戏。所以强烈建议涉及默认路由的操作,临时命令用ip route replace之前,先确保当前控制台还开着,或者有一个稳定的带外管理口,比如 iLO / iDRAC / IPMI,别让手里没有救命稻草。

我自己还习惯把每次变更记录到~/.bash_history之外的单独笔记里,不是为了给老板看,纯粹是因为半年后你根本记不得当时为什么把 Metric 设成 300。

7. 双网卡优先级速查表

给到一个快速参考,实际配置时对照着检查一遍,能少踩不少坑。

检查项目标状态常见错误
网卡识别MAC 与物理接口对应复制配置文件导致 MAC 混乱
默认路由只留一条优先的 default两块网卡都配 GATEWAY 导致两条默认路由
Metric 值主网卡小于备用网卡没写 METRIC 导致系统默认值抢占
NetworkManager与 network 脚本冲突两者同时生效造成路由不复位
DNS 配置外网口只放外网 DNS内外网 DNS 混排堵塞解析
策略路由按 needs 自定义 table简单场景误用复杂策略

表中每一条都是实际故障里常见的诱因,排查时从上往下过一遍,绝大多数双网卡的问题都能定位出来。

再提一件事,配置完成后,可以用ip route get 1.1.1.1直接查看系统为某个目标 IP 选出的路径。这个命令会告诉你数据包实际会走哪块网卡、哪个网关,是验证优先级配置是否生效的最快方式。

双网卡场景下的优先级控制,说到底是操纵系统对“默认出口”的认知。Metric 是基础,策略路由是进阶,NetworkManager 是个隐藏变量,三者叠加在一起才组成完整的选路逻辑。按文章里的步骤走一遍,先确认网卡身份,再设置 Metric,必要时上策略路由,配完记得用ip route get验证。这套流程我用了好多年,不管新机器还是老机器,都能稳稳控制住流量的走向。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进