一台本来运行好好的机器,某天整机网络起不来了。你去看网卡,发现接口名退回了默认名字,而网络配置里写的还是原来那个名字——两者对不上,网络自然起不来。更奇怪的是,硬件没动过。
现象
典型表现:
- 系统起不来网络,SSH 连不上;
ip link看到网卡叫了一个你不认识的名字(比如系统的默认命名,而不是配置里那个);- 网络配置文件里写的接口名(比如
ens18或某个自定义名),在系统里找不到对应网卡。
而这次事故之前,这台机器一切正常,也没人动过网络配置文件。
根因
根子在网卡名是怎么来的。
那些"看起来稳定"的网卡名,很多是由一条 udev 重命名规则生成的,而规则里常常按 MAC 地址匹配:找到 MAC 等于某个值的网卡,把它改名为某个特定的名字。
问题在于:你匹配的那个 MAC,可能不是个永远不变的量。
具体地,有些环境里网卡用的是本地管理位地址(locally administered address)——这类 MAC 在某些场景下(比如清 CMOS 后固件重新计算、或虚拟化/固件层面的地址重生成)会变化。一旦 MAC 变了:
- udev 规则拿着旧 MAC 去找,找不到(没有网卡的 MAC 等于那个值);
- 规则不匹配 → 不改名 → 网卡保持默认名字;
- 网络配置却还按老名字写 → 对不上 → 网络起不来。
一句话:按 MAC 给网卡命名,等于把网络配置绑在了一个可能变化的量上。 平时风平浪静,那个量一变,全线崩。
解决
先确认现状,再二选一改。
先看清楚:网卡现在的实际名字和 MAC。
ip -br link # 现在叫什么、状态如何、MAC 是什么
方案一:改重命名规则里的 MAC。
把 udev 规则里的匹配值改成网卡当前真实的 MAC:
# 看有哪些网卡命名规则
ls /etc/systemd/network/ /etc/udev/rules.d/
grep -rn "ATTR{address}" /etc/udev/rules.d/
# 编辑对应的规则文件,把 MAC 改成当前值
sudo vi /etc/udev/rules.d/70-persistent-net.rules
# 让规则重新生效
sudo udevadm control --reload
sudo udevadm trigger
方案二:改网卡配置里的接口名。
不动规则,改网络配置,让它用网卡当前实际的名字:
# 看网卡现在实际叫什么
ip -br link
# 把网络配置里的接口名改成那个名字
sudo vi /etc/network/interfaces # 或 /etc/netplan/*.yaml 等,按你的系统
改完重启网络:
sudo systemctl restart networking # Debian 系
# 或
sudo netplan apply # Ubuntu netplan
更彻底的方案:不按 MAC 命名。
如果条件允许,换成按固件/PCI 位置命名(即现代 Linux 的可预测命名,ens18 这类),或者干脆用别的方式区分网卡,别拿 MAC 当锚点。这样 MAC 再变也不影响。
延伸与预防
这条坑的通用教训是:别把配置绑在"你以为稳定、实际会变"的量上。
MAC 就属于这类"看起来是硬件唯一标识、实际可能被改"的量——虚拟化环境里可以随时重置、物理机清 CMOS 后可能重算、网卡也可以手动改 MAC。把它当锚点,就是在赌"它永远不变"。
应用到别处同理:
- 用磁盘的
/dev/sda名字写 fstab?盘序一变就挂错,应该用UUID/LABEL; - 用网卡序号、用设备在总线上的位置做标识,也要想清楚它稳不稳。
判断标准很简单:这个标识是"烧死在硬件里、永不变"的吗? 是,可以绑;不是,就找一个更稳的锚点(UUID、序列号、固件位置),或者至少做好"它变了怎么快速修"的预案。
预防上还有一条:关键网络配置变更前,留一条带外访问通道(比如带外管理口、串口、或另一张独立网卡)。像这类"整机网络起不来"的事故,如果没有带外通道,你只能到现场或重启进救援——代价很大。