
1. 先搞清楚Ubuntu 20.04 的网卡为什么叫 ens33 而不是 eth0刚从 CentOS 或者老版本 Ubuntu 转过来的朋友第一次在 Ubuntu 20.04 上敲ifconfig或者ip addr的时候大概率会愣一下网卡名字怎么变成ens33、enp3s0、eno1这种了明明记得以前是清清爽爽的eth0配置静态IP、网关的时候直接写eth0就完事现在却要先ip addr看一眼真名再回去改配置麻烦不说很多老脚本、老文档里写死的eth0直接就跑不通了。这不是 Ubuntu 故意折腾人而是一套叫可预测网卡命名的机制在起作用我们先把这件事讲透后面改起来才不会心慌。1.1 可预测网卡命名机制到底在做什么在老式的 Linux 里内核探测到网卡就按顺序分配eth0、eth1谁先被扫到谁先拿号。这在物理机时代问题不大但到了虚拟机、云主机、多网卡服务器上就出事了今天加了块网卡明天重启一次eth0和eth1可能就换了位置防火墙规则、路由策略、绑定脚本全部错位。于是 systemd 和 udev 联合推出了一套命名规则让网卡名字直接体现它的物理位置或者固件信息比如enp3s0表示 PCI 总线 3 号插槽 0 号功能ens33表示板载第 33 号设备eno1表示主板固件给出的编号。名字虽然难看但稳定重启一百次也不会变。这套机制的关键开关有两个内核参数net.ifnames和biosdevname。只要net.ifnames1系统就会走可预测命名把它设成 0内核就退回到传统的ethX顺序命名。所以想改回eth0本质上就是把这个参数关掉让内核重新用老规矩发号。理解了这一层后面所有操作都只是在关开关和清残留不是玄学。1.2 改回 eth0 的收益与代价先说收益。最直接的就是兼容性大量现成的运维脚本、自动化工具、监控模板、Ansible playbook 里都硬编码了eth0改回统一名字能省掉一大堆替换工作。其次是可读性eth0、eth1一眼就能分清主次比enp4s0f0好记得多。第三是很多教学环境和实验手册都基于eth0编写统一之后你跟着做实验不用每次都翻译网卡名。代价也有得说清楚。第一物理机上如果有多块网卡eth0的归属完全取决于内核探测顺序插槽换一下可能就换了名字所以要配合 udev 规则锁定 MAC 才稳妥。第二某些云厂商的镜像对eth0这个名字有特殊预期改了反而可能触发异常。第三改完必须重启生产环境要挑维护窗口。我个人的经验是虚拟机、实验机、内网自建服务器改回eth0非常值公网云主机、有严格运维规范的集群保持默认更省心。2. 动手把网卡名改回 eth0从 GRUB 到 udev 的完整链路搞清楚原理之后动手部分其实就那么几步但每一步都有细节漏一个就会出现改完没生效或者网卡直接消失的尴尬。我把整条链路拆成三块改 GRUB、清残留、验证。顺序不能乱尤其是第二块很多教程只讲第一步结果读者重启后发现还是ens33然后就开始怀疑人生。2.1 修改 GRUB 内核参数并重新生成引导第一步是编辑 GRUB 配置文件。注意 Ubuntu 20.04 用的是 GRUB2配置文件在/etc/default/grub不是/boot/grub/grub.cfg后者是自动生成的手动改了下次update-grub就被覆盖。打开编辑sudo vim /etc/default/grub找到这一行GRUB_CMDLINE_LINUX把它改成GRUB_CMDLINE_LINUXnet.ifnames0 biosdevname0这里两个参数各有分工。net.ifnames0负责关闭 systemd 的命名策略biosdevname0负责关闭 Dell 等厂商固件提供的命名方案两个都写上才算彻底。如果你的系统本来就有其他内核参数比如consolettyS0那就追加在后面中间用空格隔开别把原有的覆盖掉否则可能丢掉串口输出之类的功能。改完之后执行sudo update-grub这个命令会根据/etc/default/grub的内容重新生成/boot/grub/grub.cfg。执行过程会打印一串Found linux image...看到done就说明生成成功。这里有个坑如果你用的是 UEFI 引导update-grub仍然有效但要确认/boot/efi分区正常挂载否则生成的配置可能不完整。我遇到过 EFI 分区被误卸载导致update-grub报错的情况重新mount /boot/efi就好了。2.2 清理旧的命名绑定与网络配置残留这是最容易被跳过的一步。光改 GRUB 只是让内核不再用新规则但系统里可能还残留着基于旧网卡名生成的配置文件比如 netplan 的 YAML 里写的是ens33或者/etc/network/interfaces里写的是旧名字。重启之后网卡确实变成eth0了但配置文件还在找ens33结果就是网卡起来了却没有 IP等于白改。先看一眼当前有哪些网络配置ls /etc/netplan/ ip addr show假设你的旧网卡名是ens33那么/etc/netplan/下的01-network-manager-all.yaml或50-cloud-init.yaml里大概率写的是ens33。你可以直接把这些文件里对应的网卡名改成eth0也可以先备份再重写。顺手再把旧名字相关的 udev 规则清一下ls /etc/udev/rules.d/Ubuntu 20.04 默认通常没有70-persistent-net.rules这个文件因为现在系统会自动生成。但如果你的机器是从老版本一路升级上来的可能残留了绑定 MAC 和网卡名的规则这种规则会在你改名之后强行把网卡改回旧名字。发现类似文件的话先备份再删除sudo cp /etc/udev/rules.d/70-persistent-net.rules ~/70-persistent-net.rules.bak sudo rm /etc/udev/rules.d/70-persistent-net.rules注意删除 udev 规则前一定要备份。这些规则里可能绑着你不认识但正在用的设备误删会导致别的硬件识别异常。删之前用cat看一眼内容确认里面只有网卡相关的条目再动手。清完残留就可以重启了sudo reboot2.3 重启后的验证与常见翻车点重启之后第一件事不是急着配 IP而是确认网卡名改成功了ip addr show看到eth0就对了如果还是ens33先别慌从下面几个方向排查。第一update-grub是不是真的执行成功了可以用grep net.ifnames /boot/grub/grub.cfg看看新参数有没有写进引导菜单。第二检查是不是有别的配置文件覆盖了 GRUB 参数比如/etc/default/grub.d/目录下的文件有些云镜像会在这里塞东西。第三确认你没有改错文件GRUB_CMDLINE_LINUX_DEFAULT和GRUB_CMDLINE_LINUX是两个不同的变量改错地方也可能不生效。还有一种情况是网卡名变了但 IP 没了。这时候ip addr show eth0会显示state DOWN且没有inet地址说明网络服务没把配置和网卡对上。这就是 2.2 节里提到的配置文件残留问题回去把 netplan 或 interfaces 里的名字改成eth0即可。我在虚拟机里实测下来改名失败十有八九都出在这两个环节要么 GRUB 没生效要么配置没改名。把这两点盯住基本一次成功。3. 配置静态 IP、网关与 DNSnetplan 与 ifupdown 两套方案网卡名搞定之后接下来就是正题配静态 IP、网关、DNS。Ubuntu 20.04 和 CentOS 7 最大的区别在于它默认用 netplan 管理网络配置文件是 YAML 格式而传统的那套/etc/network/interfaces在桌面版默认没装 ifupdown服务器版则要看镜像。两种方式都能用但适用场景不同我建议至少掌握 netplan因为这是官方主推的方向。3.1 netplan 方案YAML 写法与 gateway4 弃用问题先看 netplan 的核心文件位置和权限要求。配置文件统一放在/etc/netplan/下文件名一般类似01-network-manager-all.yaml或50-cloud-init.yaml。权限必须是600否则netplan apply会直接报错Permissions for ... are too opensudo chmod 600 /etc/netplan/*.yaml然后是内容。假设我们要给eth0配192.168.1.100网关192.168.1.1DNS 用两个公共地址最经典的写法是network: version: 2 renderer: networkd ethernets: eth0: dhcp4: no addresses: - 192.168.1.100/24 gateway4: 192.168.1.1 nameservers: addresses: - 114.114.114.114 - 223.5.5.5这个写法在 Ubuntu 20.04 早期版本上没问题但从 netplan 0.99 开始gateway4被标记为弃用netplan apply会打印黄色的警告大意是让你改用routes。虽然短期内还能用但在 Ubuntu 22.04 及以后会被彻底移除。所以更稳妥的写法是network: version: 2 renderer: networkd ethernets: eth0: dhcp4: false addresses: [192.168.1.100/24] routes: - to: default via: 192.168.1.1 nameservers: addresses: [114.114.114.114, 223.5.5.5] optional: true这里几个细节值得展开。dhcp4: false表示关闭 DHCP走手动配置addresses里的/24是 CIDR 前缀长度等价于子网掩码255.255.255.0routes里to: default表示默认路由via就是网关地址optional: true的作用是让系统在网卡没连上时也能正常启动不会卡在启动阶段等网络超时这个参数在虚拟机里尤其有用不加的话开机可能要等九十秒。改好之后先用netplan try试跑它会给你 120 秒确认时间如果配置有问题会自动回滚比直接apply安全sudo netplan try确认没问题再正式生效sudo netplan applyapply会调用后端systemd-networkd重新加载配置。如果你发现 apply 之后 IP 还没变可以用sudo netplan generate --debug看看有没有语法错误YAML 对缩进极其敏感多一个 Tab 就报错建议统一用两个空格缩进。3.2 ifupdown 方案回到 /etc/network/interfaces有些朋友更习惯老式写法尤其是从 Debian 或 CentOS 过来的。Ubuntu 20.04 服务器版理论上支持 ifupdown但需要确认ifupdown包是否已安装dpkg -l | grep ifupdown没装的话sudo apt install ifupdown然后编辑/etc/network/interfacesauto lo iface lo inet loopback auto eth0 iface eth0 inet static address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.1 dns-nameservers 114.114.114.114 223.5.5.5这里auto eth0表示开机自动启用iface eth0 inet static声明静态地址段下面缩进的四行是具体参数dns-nameservers由resolvconf组件负责写进/etc/resolv.conf。写完之后重启网络sudo systemctl restart networking或者单独拉起某个接口sudo ifdown eth0 sudo ifup eth0需要注意的是如果你的机器上 netplan 和 ifupdown 同时存在两者可能互相打架。判断当前谁在管网络看/etc/netplan/里有没有启用的配置文件以及/etc/network/interfaces里有没有实际内容。我的建议是二选一别混用。如果一定要用 ifupdown可以顺手把 netplan 配置文件加上.disabled后缀或者直接清空内容只留个框架。3.3 IP、掩码、网关、广播地址的手算过程配置里填的那些数字不是随便写的搞不明白很容易写出无效配置。拿192.168.1.100/24举例/24表示前 24 位是网络位换算成十进制子网掩码就是255.255.255.0。怎么算的把 24 个 1 排成二进制按 8 位一组11111111.11111111.11111111.00000000逐组转十进制就是255.255.255.0。同理/25是255.255.255.128/26是255.255.255.192每多一位就把最后一段的可用主机减半。网络地址是 IP 和掩码做按位与运算的结果。192.168.1.100和255.255.255.0按位与得到192.168.1.0这就是网段地址。广播地址是把主机位全部置 1得到192.168.1.255。可用主机范围是192.168.1.1到192.168.1.254一共 254 个。而网关必须落在同一个网段内通常是网段里第一个或最后一个可用地址比如192.168.1.1。参数示例值计算/说明IP 地址192.168.1.100主机在网段内的唯一标识前缀长度/24前 24 位为网络位子网掩码255.255.255.024 个 1 按 8 位分组转十进制网络地址192.168.1.0IP 与掩码按位与广播地址192.168.1.255主机位全置 1可用主机数2542 的 8 次方减 2网关192.168.1.1必须与 IP 同网段注意网关写错网段是最常见的低级错误。比如 IP 写192.168.1.100/24网关却写192.168.0.1这种情况系统往往也能接受配置但ip route里显示不出来结果就是能连内网、出不了外网。填之前先确认网段别凭记忆填。3.4 cloud-init 抢配置的处理办法云主机用户大概率会碰上一个诡异现象netplan 配置文件明明改对了netplan apply也生效了但重启之后 IP 又变回 DHCP 分来的地址。这不是玄学而是 cloud-init 在开机时把你的配置覆盖了。cloud-init 是云镜像用来做初始化的组件它会在网络阶段重新生成 netplan 配置文件覆盖你手动改的内容。解决思路是关掉它的网络配置能力让它别插手。创建一个文件sudo vim /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg写入network: {config: disabled}保存后重启cloud-init 就不会再重写网络配置了。这个办法在各大云厂商的 Ubuntu 20.04 镜像上通用实测有效。如果你不确定是不是 cloud-init 捣乱可以在重启前把配置文件的时间戳记一下重启后看时间戳有没有变变了基本就是它干的。4. 常见故障排查实录与避坑清单配置网络这活儿出问题的概率不低而且现象往往很相似排查起来容易绕弯路。我把这些年踩过的坑整理成几类配上排查顺序遇到问题按图索骥基本能定位。4.1 重启后静态 IP 失效这是问得最多的一个问题。原因通常有三个一是前面提到的 cloud-init 覆盖二是 NetworkManager 和 systemd-networkd 抢管理权三是 netplan 文件写法有问题导致 apply 时静默失败。先确认谁在管systemctl status systemd-networkd systemctl status NetworkManager一般桌面版默认用 NetworkManager服务器版用 systemd-networkd。如果两个都活着就可能冲突。netplan 里renderer字段要和实际管理的服务对应写的是networkd就不能让 NetworkManager 也别插手。简单粗暴的做法是关掉不用的那个sudo systemctl disable --now NetworkManager再检查 netplan 配置有没有被覆盖sudo netplan get这个命令会打印当前生效的网络配置。如果打印出来的内容和你写的不一致说明中间有覆盖排查 cloud-init 或/etc/netplan/下的其他文件。4.2 ping 不通网关的排查顺序ping 不通网关也是高频问题别一上来就怀疑网卡坏了。按下面顺序走一遍八成能定位。第一步确认网卡是 UP 状态ip link show eth0看到state UP才算正常DOWN就手动拉起来sudo ip link set eth0 up第二步确认 IP 和网关在同一网段用上一节的算法核对。第三步确认路由表里有默认网关ip route show应该有一行default via 192.168.1.1 dev eth0。没有的话说明配置没生效。第四步确认物理链路虚拟机的话看虚拟网卡是不是桥接到正确的物理网卡物理机的话看网线、交换机端口指示灯。第五步也别忘了对端可能有 ICMP 屏蔽有些网关设备默认不响应 ping这时候可以改用arping或者直接测试出网访问。现象可能原因排查命令网卡 state DOWN未启用或被禁用ip link set eth0 up无默认路由网关配置缺失或网段错误ip route show有 IP 但同网段不通掩码写错或 VLAN 隔离ip -4 addr show eth0网关 ping 不通但能上网网关屏蔽 ICMP直接访问外部地址测试重启后配置丢失cloud-init 覆盖或服务冲突检查 netplan get 与 cloud-init4.3 网卡起不来与命名冲突改完名之后网卡直接消失ip addr里看不到eth0这种最吓人。先冷静大概率是名字冲突。比如系统里已经有一块eth0另一块网卡又被内核命名成eth0就冲突了。用dmesg看内核日志dmesg | grep -i eth如果看到renamed from ens33 to eth0之类的内容、但没有第二块说明只是改名了。如果看到netdev name conflict那就得下决心换名字或者调整物理顺序。另一种情况是网卡被 udev 规则锁定了旧名字。用udevadm查看设备的命名来源udevadm info /sys/class/net/eth0 | grep -i name如果指向的是临时规则可以尝试重新触发sudo udevadm trigger --actionadd实在不行就回到 2.2 节确认旧规则已经清干净。改名这事儿规则越少越好系统越干净越容易成功。4.4 常用验证命令速查表最后放一张我平时最常用的命令清单配合前面的排查流程使用效率会高很多。建议收藏出问题的时候直接抄。用途命令备注查看所有网卡及 IPip addr show最常用比 ifconfig 信息全查看路由表ip route show确认默认网关是否存在查看网卡链路状态ip link show eth0关注 state UP/DOWN查看 DNS 配置resolvectl status 或 cat /etc/resolv.conf确认 DNS 是否生效试跑 netplan 配置sudo netplan try120 秒自动回滚安全应用 netplan 配置sudo netplan apply正式生效查看 netplan 生效结果sudo netplan get比对配置是否被覆盖查看内核网卡日志dmesggrep -i eth查看网络服务状态systemctl status systemd-networkd确认后端服务是否运行测试连通性ping -c 4 192.168.1.1基础连通测试我在多台虚拟机和物理服务器上反复做过这套流程成功率高但每次都会遇到一点小意外最常见的就是配置文件残留和 cloud-init 覆盖。所以我的建议很简单动手之前先cp -r /etc/netplan ~/netplan.bak备份一份动手之后一定重启验证一次不要只netplan apply就以为大功告成因为重启才真正检验配置是不是持久化生效了。另外虚拟机做实验前先拍快照改坏了直接回滚比一点点修复省事得多。至于网卡名能用eth0就统一用团队协作的时候少一堆解释成本。