非常好的问题 👏——eth0、ens33、enp4s0、eno1这些名字确实让人一开始很困惑,其实它们的区别来自于Linux 的“可预测网络接口命名规则(Predictable Network Interface Names)”的演进。
下面我系统讲清楚它们的来源、命名逻辑和演变历史 👇
🧩 一、历史背景:从 eth0 到 enpXsY
早期(比如 CentOS 6 / Ubuntu 14):
- 所有网卡默认叫
eth0,eth1,eth2…… - 命名顺序取决于内核识别设备的先后次序
但问题是:
顺序不稳定—— 一旦加拔网卡或硬件顺序改变,接口名也会变。
比如:
- 第一次启动:eth0 → 网卡A,eth1 → 网卡B
- 下次启动顺序变了:eth0 → 网卡B,eth1 → 网卡A
😱 结果网络配置全错。
⚙️ 二、systemd 引入“可预测命名”(Predictable Interface Names)
从systemd v197 (约 2015 年)开始,引入了“基于硬件拓扑的命名规则”:
按照设备在主板上的物理位置、总线拓扑等信息生成稳定名称。
🧠 三、命名规则逻辑(核心)
| 前缀 | 来源 | 示例 | 含义 |
|---|---|---|---|
| en | Ethernet | 通用前缀 | |
| wl | Wireless | 无线网卡(Wi-Fi) | |
| ww | WWAN | 移动宽带(3G/4G) |
接着后缀说明设备位置:
| 类型 | 格式 | 示例 | 说明 |
|---|---|---|---|
| onboard (板载) | enoX | eno1 | 主板上集成的网卡(BIOS 固定序号) |
| PCI slot index | ensX | ens3 | 插在主板插槽的 PCI-E 网卡 |
| PCI bus path | enpXsY | enp4s0 | PCI 总线号与插槽号(最常见) |
| MAC-based (fallback) | enx<MAC> | enx001122334455 | 当其他信息不可用时使用 MAC 命名 |
| 传统方式(旧) | ethX | eth0 | 旧版 udev 风格,不可预测 |
🔍 四、示例说明
| 接口名 | 含义 |
|---|---|
eno1 | Onboard 网卡 #1(板载) |
ens3 | PCI slot 3 上的网卡 |
enp4s0 | 位于 PCI 总线 4、插槽 0 的网卡 |
enx00e04c680001 | 按 MAC 地址命名 |
eth0 | 旧命名方式(随机) |
🧩 五、为什么有些系统还是 eth0?
取决于发行版是否启用了 predictable 命名:
| 系统 | 默认命名 |
|---|---|
| Ubuntu 14 / CentOS 6 | eth0 |
| Ubuntu 16+ / CentOS 7+ / Debian 9+ | ensX/enpXsY/enoX |
| Kubernetes 节点(cloud-init / containerd 环境) | 多为eth0(容器命名固定) |
⚙️ 六、如何控制命名方式
可以通过内核启动参数或udev 规则控制:
1️⃣ 禁用可预测命名,恢复传统eth0
在/etc/default/grub里添加:
ini
代码解读
复制代码
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"
然后:
bash
代码解读
复制代码
sudo grub2-mkconfig -o /boot/grub2/grub.cfg sudo reboot
启动后恢复旧命名(eth0、eth1)。
🧠 七、运维角度总结
| 命名方式 | 稳定性 | 可读性 | 推荐 |
|---|---|---|---|
eth0 | ❌ 不稳定 | ✅ 简洁 | 不推荐 |
ensX/enpXsY/enoX | ✅ 稳定 | ⚙️ 略长 | ✅ 推荐 |
enxMAC | ✅ 稳定 | ❌ 冗长 | 临时用 |
| 自定义(udev rename) | ✅ 稳定 | ✅ 灵活 | 高级用法 |
✅总结一句话:
eth0是旧的“按顺序命名”,ensX/enpXsY/enoX是新的“按物理位置命名”,
它们的不同只是命名策略的变化,功能上完全等价。
一张图,展示从 BIOS → PCI bus → systemd → 内核 → 接口命名 的整个生成流程?那样你会一眼看懂为什么有enp4s0和eno1。
非常好 👍 我来接着讲,并帮你画清楚整个接口命名生成流程图,让你彻底理解为什么有eth0、enp4s0、eno1、ens3等不同命名。
🧭 一、命名生成全过程(从 BIOS 到内核)
下面这张逻辑流程图展示了Linux 启动时是如何决定网卡名字的:
bash
代码解读
复制代码
┌──────────────────────────────┐ │ BIOS / 主板固件 │ │ ↳ 记录板载网卡序号 (onboard index) │ └──────────────┬──────────────┘ │ ▼ ┌──────────────────────────────┐ │ 内核探测硬件(PCI 总线扫描) │ │ ↳ 每块网卡都有 Bus ID,如 0000:04:00.0 │ └──────────────┬──────────────┘ │ ▼ ┌──────────────────────────────┐ │ systemd-udevd 启动时读取: │ │ • /sys/class/net/* │ │ • /sys/devices/pci... │ │ • BIOS/固件信息(onboard flag) │ └──────────────┬──────────────┘ │ ▼ ┌────────────────────────────────────────────────────────────┐ │ 根据规则匹配并生成接口名: │ │ │ │ ① 如果是板载:enoX │ │ ② 如果是PCI插槽:ensX │ │ ③ 如果可确定PCI路径:enpXsY │ │ ④ 如果以上都失败:enx<MAC> │ │ ⑤ 如果Predictable命名关闭:ethX │ └────────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────┐ │ 最终接口名注册到内核网络命名空间 │ └──────────────────────────────┘
🧠 二、命名规则来源文件
Linux 中的这套规则主要来自:
| 文件/工具 | 作用 |
|---|---|
/lib/udev/rules.d/60-net.rules | udev 默认规则 |
/lib/udev/rules.d/80-net-setup-link.rules | systemd 网络命名规则核心 |
/etc/systemd/network/99-default.link | 默认链路命名策略 |
/etc/systemd/network/*.link | 可以自定义接口名映射(高级用法) |
示例:
ini
代码解读
复制代码
[Match] Driver=e1000e [Link] NamePolicy=kernel database onboard slot path MACAddressPolicy=persistent
⚙️ 三、不同前缀的含义对照
| 前缀 | 含义 | 典型来源 |
|---|---|---|
enoX | Onboard(板载) | BIOS 固定序号 |
ensX | PCI slot 编号 | PCI 插槽 |
enpXsY | PCI bus + slot 路径 | 多总线系统最常见 |
enx... | MAC 地址命名 | 无法探测拓扑时 |
ethX | 旧式命名 | Predictable 命名关闭 |
🧩 四、实际例子
例 1:主板板载网卡
bash
代码解读
复制代码
/sys/devices/pci0000:00/0000:00:1f.6/net/eno1
命名规则:onboard→eno1
例 2:PCI-E 插卡型网卡
bash
代码解读
复制代码
/sys/devices/pci0000:00/0000:00:1c.0/0000:04:00.0/net/enp4s0
命名规则:path-based→enp4s0
例 3:虚拟机中的网卡(如 KVM)
通常 BIOS 里没有 on-board 信息,PCI 插槽信息也可能是虚拟的,结果:
代码解读
复制代码
enp0s3
虚拟机内常见路径 →enp0s3
例 4:Docker / Containerd 容器
容器里命名通常强制为:
代码解读
复制代码
eth0
原因:容器命名由runc/netns直接固定写死,不走 udev/systemd 命名逻辑。
🔧 五、怎么查看当前接口命名来源
你可以在系统中执行:
javascript
代码解读
复制代码
udevadm test-builtin net_id /sys/class/net/enp4s0 2>/dev/null | grep ID_NET_NAME
输出类似:
ini
代码解读
复制代码
ID_NET_NAME_PATH=enp4s0 ID_NET_NAME_SLOT=ens3
这表示该接口是通过path或slot命名的。
🧭 六、禁用或修改命名规则(可选)
禁用 predictable 命名:
ini
代码解读
复制代码
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"
效果:恢复传统eth0命名。
自定义名称(例如改成 public0)
创建/etc/udev/rules.d/70-custom-net-names.rules:
ini
代码解读
复制代码
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:11:22:33:44:55", NAME="public0"
✅ 七、总结
| 名称示例 | 类型 | 来源 | 稳定性 | 备注 |
|---|---|---|---|---|
| eth0 | 传统 | 内核顺序 | ❌ 不稳定 | 老版本 |
| eno1 | 板载 | BIOS on-board | ✅ 稳定 | 服务器常见 |
| ens3 | 插槽 | PCI slot | ✅ 稳定 | 云主机常见 |
| enp4s0 | 路径 | PCI bus path | ✅ 稳定 | 新系统最常见 |
| enx001122334455 | MAC 地址 | 唯一标识 | ✅ 稳定 | 临时命名 |
如果你想,我可以帮你结合你的真实ip link输出(或/sys/class/net目录)画一张结构图,标出每个网卡是板载、PCI 插卡还是虚拟设备。
作者:bobz965
链接:https://juejin.cn/post/7569547273115467826
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。