工业双网卡路由优先级配置:systemd-networkd Metric实战指南
1. 工业现场的双网卡困境为什么插上两根网线反而上不了网在工业计算机和边缘网关的部署现场有线网卡和无线网卡同时存在几乎是标配。有线接产线内网的PLC和HMI无线连办公网或者云端做数据回传听起来是很合理的分工。但很多人第一次把两根线都插上、WiFi也连上之后会遇到一个非常反直觉的现象内网设备突然ping不通了或者云端数据传不上去了甚至两个都不通。问题的根源不在网卡本身而在Linux内核的路由决策机制。当系统里同时存在两条默认路由default route时内核需要一套规则来决定这个包到底从哪个网卡出去。这套规则的核心就是Metric路由度量值——数值越小优先级越高。如果两张网卡都拿到了默认路由而且Metric相同或者无线网卡的Metric更小那么所有出站流量都会往无线网卡上挤有线内网的流量自然就断了。工业场景比普通办公环境更麻烦的地方在于很多工业计算机跑的是精简版Linux发行版网络管理用的是systemd-networkd而不是NetworkManager配置文件是.network格式的网上大量教程都是针对NetworkManager或者netplan的直接照搬根本对不上。而且工业设备往往要求开机即用、无人值守配置必须写进文件持久化不能靠临时敲命令。这篇内容就是把我自己在工业计算机上反复调试双网卡路由优先级的过程完整拆出来从路由表怎么看、Metric怎么算、systemd-networkd的配置文件怎么写到实测中遇到的各种意外情况一步步讲清楚。不管你是刚接触Linux网络的新手还是被双网卡路由搞到头大的运维都能照着复现。2. 先看懂路由表Metric到底在哪个位置起作用2.1 用ip route命令读出真实的决策依据很多人排查网络问题第一反应是ifconfig但ifconfig只告诉你网卡有没有IP不告诉你流量往哪走。真正要看的是路由表ip route show典型输出长这样default via 192.168.1.1 dev wlan0 proto dhcp src 192.168.1.100 metric 600 default via 10.0.0.1 dev enp2s0 proto dhcp src 10.0.0.50 metric 100 10.0.0.0/24 dev enp2s0 proto kernel scope link src 10.0.0.50 metric 100 192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.100 metric 600这里有两个default条目分别走wlan0和enp2s0。内核选哪条看metric100比600小所以默认走有线enp2s0。这个结果是符合预期的。但如果你的输出是这样default via 192.168.1.1 dev wlan0 metric 100 default via 10.0.0.1 dev enp2s0 metric 100两条默认路由metric一样内核就会按照路由添加的顺序或者网卡状态来选行为不确定这就是冲突的典型表现。更隐蔽的情况是无线网卡的metric比有线还小那所有流量都走WiFi内网直接失联。2.2 Metric数值的来源谁在给你的路由打分Metric不是凭空来的不同来源有不同的默认值路由来源典型默认Metric说明内核直连路由0同网段直连最高优先级DHCP客户端100有线/ 600无线不同发行版和DHCP客户端差异较大systemd-networkd静态配置未指定时按接口类型需要手动设置才可控NetworkManager100有线/ 600无线有默认的接口类型区分关键点在于systemd-networkd在你不显式配置Metric的时候行为并不总是可预测的。它可能根据接口名称、接口类型给一个默认值也可能让DHCP返回的值直接生效。工业计算机上如果DHCP服务器下发的路由metric不合理你的本地配置就会被覆盖。提示判断当前metric来源可以看ip route show输出里的proto字段。proto dhcp说明是DHCP下发的proto static说明是静态配置的proto kernel是内核自动生成的直连路由。2.3 双默认路由为什么必然冲突从内核的角度看路由表是一个最长前缀匹配优先同前缀比metric的结构。两条default路由前缀长度都是0所以只能比metric。metric相同的时候内核实际上会做**ECMP等价多路径**或者按添加顺序选一条具体行为取决于内核版本和配置。工业场景最怕的就是这种不确定性。今天重启走有线明天重启走无线产线设备时通时断排查起来极其痛苦。所以正确的做法不是让系统自己选而是显式指定每条路由的metric把决策权握在自己手里。3. systemd-networkd的配置文件结构改对文件才有效3.1 .network文件放在哪、叫什么名字systemd-networkd读取配置的目录有三个优先级从高到低/etc/systemd-networkd/*.network—— 管理员手动配置优先级最高/run/systemd-networkd/*.network—— 运行时生成重启丢失/usr/lib/systemd-networkd/*.network—— 发行版或软件包自带你自己写的配置必须放在/etc/systemd-networkd/下面。文件名建议用10-有线网卡名.network、20-无线网卡名.network这种带数字前缀的命名因为systemd-networkd会按文件名字典序处理数字前缀能保证处理顺序可控。先确认你的网卡名字ip link show工业计算机上常见的有线网卡名可能是enp2s0、eno1、eth0无线网卡可能是wlan0、wlp3s0。名字一定要对写错了配置文件不生效还不报错。3.2 Match段和Network段的分工一个最小的.network文件长这样[Match] Nameenp2s0 [Network] DHCPyes[Match]段决定这个文件管哪张网卡[Network]段决定怎么配。要控制路由metric关键在[DHCP]段或者[Route]段。对于DHCP获取地址的有线网卡控制默认路由metric的写法是[Match] Nameenp2s0 [Network] DHCPyes [DHCP] RouteMetric100RouteMetric100告诉systemd-networkd通过DHCP拿到的路由metric都设成100。无线网卡那边设成600[Match] Namewlan0 [Network] DHCPyes [DHCP] RouteMetric600这样有线100、无线600有线优先符合内网走有线、外网走无线的预期。3.3 静态IP场景下用[Route]段精确控制如果工业计算机用的是静态IP产线环境很常见因为要固定地址方便PLC寻址那就要用[Route]段[Match] Nameenp2s0 [Network] Address10.0.0.50/24 Gateway10.0.0.1 DNS10.0.0.2 [Route] Gateway10.0.0.1 Metric100注意这里[Network]段的Gateway和[Route]段的Gateway是两回事。[Network]里的Gateway会生成一条默认路由但metric不可控[Route]段里的才是你能精确指定metric的。两个都写会导致重复路由正确做法是只在[Route]段写Gateway[Network]段不写。无线网卡同理[Match] Namewlan0 [Network] Address192.168.1.100/24 DNS192.168.1.1 [Route] Gateway192.168.1.1 Metric6003.4 改完必须做的两步reload和restart配置文件写完不是自动生效的要执行sudo systemctl restart systemd-networkd或者更温和一点sudo networkctl reload sudo networkctl reconfigure enp2s0 sudo networkctl reconfigure wlan0reload只重读配置reconfigure才会真正应用。实测下来改metric这种操作直接restart systemd-networkd最省事但会短暂断网工业现场如果正在跑数据采集建议在维护窗口操作。验证结果ip route show networkctl status enp2s0 networkctl status wlan0networkctl status会显示每张网卡当前的路由和metric比ip route更直观。4. 实测踩坑那些配置文件写了却不生效的情况4.1 DHCP下发的metric覆盖了本地配置这是最常见的一个坑。你在[DHCP]段写了RouteMetric100但ip route一看还是600。原因通常是DHCP服务器或者上游的路由器在DHCP Offer里带了classless static route选项直接把metric写死了systemd-networkd优先用了DHCP下发的值。排查方法journalctl -u systemd-networkd -b | grep -i metric看日志里有没有RouteMetric相关的记录。如果确认是DHCP覆盖有两个解法一是让网络管理员改DHCP服务器配置二是在.network文件里加[DHCP] RouteMetric100 UseRoutesnoUseRoutesno表示不采用DHCP下发的路由只用本地[Route]段定义的。这个选项要慎用因为有些环境确实需要DHCP下发特定路由。4.2 无线网卡连上但没拿到默认路由工业计算机的无线网卡如果用的是wpa_supplicantsystemd-networkd的组合有时候WiFi显示连上了但ip route里没有无线的default条目。这通常是因为[Network]段里没写DHCPyes或者[Match]段的网卡名写错了。用networkctl status wlan0看如果State是routable但路由表里没有default检查[Network] DHCPyes如果WiFi是静态IP那必须显式写[Route]段否则systemd-networkd不会自动生成默认路由。4.3 两张网卡同网段导致的ARP冲突这个坑比较隐蔽。有线是10.0.0.50/24无线不小心也配成了10.0.0.100/24两张网卡在同一个网段。这时候内核的ARP表会混乱同一个IP可能从两个网卡出去路由metric怎么调都没用。工业现场如果无线和有线确实需要同网段比如做冗余那要用策略路由policy routing而不是靠metric。但大多数情况下有线内网和无线外网应该是不同网段配之前先确认IP规划。4.4 重启后配置丢失文件没放对目录有人把.network文件写在了/usr/lib/systemd-networkd/下面重启或者系统更新后被覆盖了。记住你自己的配置永远放/etc/systemd-networkd/。另外如果系统里同时装了NetworkManager和systemd-networkd两者会抢网卡管理权需要确认当前哪一个是激活的systemctl status NetworkManager systemctl status systemd-networkd工业精简系统通常只有systemd-networkd但如果是Ubuntu Server这类可能两个都在跑。禁用不需要的那个sudo systemctl disable --now NetworkManager sudo systemctl enable --now systemd-networkd5. 进阶场景策略路由与多网段工业组网5.1 什么时候metric不够用需要策略路由Metric解决的是默认路由走哪张网卡的问题。但如果你的需求是访问10.1.1.0/24走有线访问10.2.2.0/24也走有线但访问192.168.0.0/16走无线而且这些网段可能有重叠或者需要基于源地址选路那metric就不够了需要策略路由。策略路由的核心是路由表routing table加规则rule。Linux默认有local、main、default三张表你可以自定义表echo 100 wired | sudo tee -a /etc/iproute2/rt_tables echo 200 wireless | sudo tee -a /etc/iproute2/rt_tables然后在.network文件里用[RoutingPolicyRule]段[RoutingPolicyRule] From10.0.0.50 Table100 Priority100配合[Route]段的Table100就能实现基于源地址的选路。这个配置在工业网关做多网段隔离时非常有用。5.2 用Table指定路由表避免主表污染在.network文件里[Route]段可以指定Table[Route] Gateway10.0.0.1 Metric100 Table100这样这条路由不会进main表而是进自定义的100表。好处是主路由表保持干净排查问题的时候ip route show table main和ip route show table 100分开看逻辑清晰。工业现场如果有多条专线或者多个VLAN建议每张网卡对应一张独立路由表用[RoutingPolicyRule]做分流。这套配置写进.network文件后systemd-networkd重启会自动重建比手写ip rule命令可靠得多。5.3 无线网卡做备份链路的metric设计有些工业场景要求有线为主、无线为备有线断了自动切无线。这种需求下metric的设计要配合链路检测。单纯设有线100、无线600有线断了之后内核不会自动把流量切到无线因为路由还在网卡物理层可能还up只是上游断了。真正的故障切换需要用systemd-networkd的[Link]段配置RequiredForOnline做链路状态检测或者用Keepalived、VRRP这类工具做上层切换或者写脚本监控有线网关的可达性不可达时动态调整metric#!/bin/bash if ! ping -c 2 -W 1 -I enp2s0 10.0.0.1 /dev/null 21; then ip route change default via 192.168.1.1 dev wlan0 metric 50 else ip route change default via 10.0.0.1 dev enp2s0 metric 100 fi这个脚本可以放到cron或者systemd timer里定时跑。注意ip route change需要路由已存在不存在的话用ip route replace。6. 一套可直接抄的工业双网卡配置模板6.1 有线网卡配置内网静态IPmetric 100# /etc/systemd-networkd/10-wired.network [Match] Nameenp2s0 [Network] Address10.0.0.50/24 DNS10.0.0.2 IPForwardyes [Route] Gateway10.0.0.1 Metric100IPForwardyes在工业网关上需要开如果这台机器只是终端设备可以去掉。6.2 无线网卡配置外网DHCPmetric 600# /etc/systemd-networkd/20-wireless.network [Match] Namewlan0 [Network] DHCPyes [DHCP] RouteMetric600 UseDNSyes如果无线也是静态IP把DHCPyes换成Address和[Route]段metric设600。6.3 应用配置并验证的完整命令序列# 1. 确认网卡名 ip link show # 2. 写配置文件 sudo vi /etc/systemd-networkd/10-wired.network sudo vi /etc/systemd-networkd/20-wireless.network # 3. 重启服务 sudo systemctl restart systemd-networkd # 4. 等待几秒让DHCP完成 sleep 5 # 5. 验证路由 ip route show # 6. 验证连通性 ping -c 3 -I enp2s0 10.0.0.1 ping -c 3 -I wlan0 192.168.1.1 # 7. 验证默认路由走向 ip route get 8.8.8.8第7步的ip route get最关键它会明确告诉你访问某个目标地址时内核选了哪张网卡、哪条路由。输出里的dev字段就是实际出口。6.4 开机自检脚本让工业计算机自己报告网络状态工业设备无人值守建议加一个开机自检脚本把网络状态写到日志或者上报#!/bin/bash # /usr/local/bin/net-check.sh LOG/var/log/net-check.log echo $(date) $LOG ip route show $LOG echo --- default route test --- $LOG ip route get 8.8.8.8 $LOG echo --- wired gateway --- $LOG ping -c 2 -W 2 -I enp2s0 10.0.0.1 $LOG 21 echo --- wireless gateway --- $LOG ping -c 2 -W 2 -I wlan0 192.168.1.1 $LOG 21配合systemd service在network-online.target之后运行# /etc/systemd/system/net-check.service [Unit] DescriptionNetwork Check Afternetwork-online.target Wantsnetwork-online.target [Service] Typeoneshot ExecStart/usr/local/bin/net-check.sh [Install] WantedBymulti-user.target这样每次开机都会在/var/log/net-check.log里留下网络快照出问题的时候直接看日志不用现场敲命令。7. 几个容易被忽略的细节和我的实际体会第一个细节是metric的数值范围。Linux的metric是32位整数理论上可以设很大但实际使用中建议保持在0-999之间因为有些工具和脚本会假设metric是三位数。有线设100、无线设600是社区里比较通用的做法也方便记忆。第二个细节是IPv6的metric。如果你的工业环境启用了IPv6[DHCP]段的RouteMetric只管IPv4IPv6的默认路由metric要用[IPv6AcceptRA]段的RouteMetric控制。很多双网卡问题在IPv4下看着正常IPv6却乱走就是这个原因。第三个细节是networkctl的实时状态。networkctl status不带参数会列出所有网卡带网卡名看详情。详情里的Gateway、Routes、DNS字段比ip命令更聚合排查的时候先看这个。我自己在工业现场最深的体会是双网卡配置一定要在实验室先跑通再上现场。现场环境复杂DHCP服务器、交换机VLAN、无线AP的配置都可能影响路由行为。实验室里用一台普通路由器模拟内网、一个手机热点模拟外网把metric配置验证一遍到了现场只需要改IP地址能省掉大量排查时间。另外配置文件写完记得用networkctl reload而不是直接重启网络服务工业设备上跑着采集程序的时候重启网络可能导致数据断点。reload是平滑重载对现有连接影响最小。如果必须restart提前跟产线沟通好维护窗口。最后如果你用的是国产化工业计算机或者定制Linux发行版systemd-networkd的版本可能比较老某些配置项比如[RoutingPolicyRule]可能不支持。先查版本systemd --version networkctl --version版本低于v237的话策略路由相关的配置项可能缺失需要升级systemd或者改用ip rule脚本方案。这个在项目选型阶段就要确认别等到部署了才发现配置写不进去。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →