VMware 虚拟机 Ubuntu 无网络:从 NO-CARRIER 到 NetworkManager 的完整排查记录
结论先行 :故障根源是
ens33网卡没有被 NetworkManager 接管------Netplan 配置残缺,且默认把这块网卡渲染给了没在运行的 systemd-networkd,两条管理链路谁都没管它。执行一条nmcli device set ens33 managed yes让 NetworkManager 接管后,网络立即恢复。
背景
最近在 VMware 虚拟机上装完 Ubuntu,发现完全没有网络。这里把完整的排查过程记录下来,希望能帮到遇到类似情况的人。
环境信息:
| 项目 | 信息 |
|---|---|
| 宿主机 | Windows |
| 虚拟化平台 | VMware Workstation |
| 客户机 | Ubuntu 26.04.1 LTS |
| 网卡 | ens33 |
| 网络模式 | 初始为桥接,后改为 NAT |
一、故障现象与快速定位
症状
ping baidu.com报「网络不可达」- 同时出现
Temporary failure in name resolution(域名解析失败)
先分流:DNS 问题还是网络层问题
遇到"没网",先用两条命令分流:
r
ping -c 3 8.8.8.8 # 纯 IP,不依赖 DNS
ping -c 3 baidu.com # 域名,依赖 DNS 解析
| 结果 | 结论 | 排查方向 |
|---|---|---|
| 两个都不通 | 网络层问题 | 网卡、IP、路由 |
| IP 通、域名不通 | DNS 问题 | DNS 服务器配置 |
本次是第一种:连 8.8.8.8 都 ping 不通,所以先放一放 DNS,从网络层查起。
如果确认是 DNS 问题(IP 通、域名不通):先看
cat /etc/resolv.conf里有没有nameserver(被 systemd-resolved 托管时用resolvectl status看实际生效的 DNS);静态 IP 场景还要检查 Netplan 里的nameservers是否和addresses同级。可以用nslookup baidu.com 8.8.8.8(或resolvectl query baidu.com)验证公共 DNS 是否可达。本文不是这种情况,不展开。
二、排查过程
第 1 步:ip route show ------ 路由表是空的
sql
ip route show
输出完全是空的 。正常至少应该有一行 default via 192.168.x.x dev ens33------这是默认路由,告诉系统外网流量交给谁转发。没有它,数据包不知道怎么出网,这就是「网络不可达」的直接原因。
路由表为空通常只有两种可能:网卡没拿到 IP ,或者网卡本身没起来。继续往下查。
顺带解释开头那个 DNS 报错:网络层不通时,域名解析请求根本发不出去,Temporary failure in name resolution 很可能只是连带结果,先别急着折腾 DNS。
小技巧:如果网卡有 IP、只是缺默认路由,可以临时执行
sudo ip route add default via 192.168.1.1 dev ens33验证通不通;通了再把它写进 Netplan 的routes里持久化。
第 2 步:ip addr show ------ 网卡 NO-CARRIER + DOWN
sql
ip addr show
截图里有两个关键点:
ens33没有 IP :只有link/ether(MAC 地址),没有inet开头的 IPv4 地址。- 状态是
NO-CARRIER+state DOWN:NO-CARRIER表示链路层没有载波,通俗说就是虚拟网线没接上;state DOWN表示网卡处于未工作状态。
这两个现象是连着的:没载波 → 网卡起不来 → 拿不到 IP → 没有路由 → 网络不可达 。到这里可以下结论:这不是 DNS 或 Netplan 配置的问题,而是更底层的网卡没连上,排查方向要转向 VMware 的设置。
判断技巧:在系统里执行
sudo ip link set ens33 up,如果状态仍然是NO-CARRIER,说明问题在虚拟机/宿主机那一层,客户机里怎么改都没用。
第 3 步:检查 VMware 设置,切换到 NAT 模式
虚拟机出现 NO-CARRIER,最常见的原因在 VMware 的网络设置,而不是 Ubuntu 内部。检查「编辑虚拟机设置 → 网络适配器」:
-
网络连接模式:
- NAT :最省心,虚拟机通过宿主机上网,一般不会出现
NO-CARRIER; - 桥接(Bridged) :虚拟机直接接入物理网络。如果桥接绑定的物理网卡不对------比如宿主机用 WiFi 上网、桥接却绑在一块没插网线的有线网卡上------就会
NO-CARRIER; - 仅主机(Host-only) :只能和宿主机通信,上不了外网。
- NAT :最省心,虚拟机通过宿主机上网,一般不会出现
-
「已连接」和「启动时连接」两个复选框:确认都勾上了,有时候不小心取消勾选,网卡就会处于未连接状态。
如果坚持用桥接,去「编辑 → 虚拟网络编辑器」检查 VMnet0(桥接)绑定的物理网卡,是不是当前真正在用的那块(比如无线网卡)。
本次的处理很直接:把网络适配器从桥接改成 NAT。

改完再进系统看,ens33 已经是 UP、有载波了,但拿到一个奇怪的地址:
169.254.186.80 是 Link-Local 地址 (也叫 APIPA):系统向 DHCP 请求地址失败时,给自己分配的临时地址,只能在本地链路通信,不能上网 。拿到它说明 DHCP 请求没人回应。
NAT 模式下,VMware 会在宿主机上虚拟出 VMnet8 网段(通常是 192.168.x.0/24),由 VMware 的 DHCP 服务负责发地址。拿不到地址的原因无非三类:
- 宿主机上 VMware 的 NAT/DHCP 服务没启动;
- VMnet8 虚拟网络组件损坏或没安装好;
- 客户机侧没有一个在工作的 DHCP 客户端(网络配置或管理服务的问题)。
本次先排查第 3 类(客户机侧),因为之前动过 Netplan 配置,嫌疑最大。
备用排查:客户机侧没问题,再回宿主机看
-
Windows 上
Win + R输入services.msc,确认以下服务均在运行,没运行就右键启动:VMware DHCP ServiceVMware NAT ServiceVMware Authorization Service
-
「编辑 → 虚拟网络编辑器」里确认存在 VMnet8,且勾选了「NAT 模式」和「使用本地 DHCP 服务将 IP 地址分配给虚拟机」。如果列表里没有 VMnet8 或配置乱了,点左下角「还原默认设置」让 VMware 重建网络组件(注意:这会重置虚拟网络配置,虚拟机会重新分配 IP)。
第 4 步:检查 Netplan 配置 ------ 三份文件在冲突
先看客户机的网络配置文件:
bash
cat /etc/netplan/*.yaml
提示 Permission denied------/etc/netplan/ 目录权限很严,普通用户读不了,加 sudo:
bash
sudo cat /etc/netplan/*.yaml
这一看就发现问题了:系统里同时存在三份 Netplan 配置文件。
00-installer-config.yaml:安装系统时生成的默认配置;01-network-manager-all.yaml:桌面版常见配置,用于把网络交给 NetworkManager 管理;90-NM-14f59568-....yaml:NetworkManager 自动生成的配置(文件名里的NM就是 NetworkManager)。
Netplan 按文件名的数字顺序读取,后面的文件会覆盖前面的冲突项。 三份文件并存,很容易互相打架:00 里声明了某个网卡,90 里 NetworkManager 又按自己的方式去管它,最终网卡可能拿到一个不正常的地址。
再看 00 的内容:
00-installer-config.yaml 的内容是不完整的 :ens33: 下面只有 match 和 set-name(只用于把网卡认出来),没有任何 IP、DHCP、网关、DNS 配置------这份文件根本没告诉系统怎么获取 IP。
一份能正常工作的 Netplan 配置,至少应该是下面两种之一。
DHCP(自动获取,最省心):
yaml
network:
version: 2
ethernets:
ens33:
dhcp4: true
静态 IP:
yaml
network:
version: 2
ethernets:
ens33:
dhcp4: false
addresses: [192.168.1.100/24]
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [223.5.5.5, 8.8.8.8]
常踩的坑:
- YAML 对缩进极其严格:子项比父项多缩进 2 个空格,只能用空格,不能用 Tab;
nameservers和addresses是同级的,都缩进在网卡名下;- 网关用
to: default的写法(旧教程里的gateway4已废弃),缩进写错网关就不会生效; - 改完先用
sudo netplan try测试(未确认或超时会自动回滚,远程操作安全),确认没问题再sudo netplan apply。
第 5 步:netplan apply 报错 ------ systemd-networkd is not running
按 DHCP 方式把 00 改好、执行 netplan apply 后,直接报错:

kotlin
systemd-networkd is not running
Failed to reload network settings: Unit dbus-org.freedesktop.network1.service not found.
翻译一下:Netplan 想把配置交给一个叫 systemd-networkd 的服务执行,但这个服务没有运行。 没人执行配置,网卡自然拿不到 IP。
另外注意截图上半部分:nano 里显示的还是文件原来的内容(只有 match、set-name),说明刚才的修改可能没保存成功 ,netplan apply 用的还是旧配置。这也是排查时的经典坑:改完配置先 cat 确认一眼。
补课:Ubuntu 的两个网络管家
Ubuntu 管理网络有两个后端,桌面版和服务器版默认用的不一样:
| 后端 | 默认出现在 | 特点 |
|---|---|---|
| systemd-networkd | 服务器版 | 轻量,纯配置文件驱动 |
| NetworkManager | 桌面版 | 网络图标背后的服务,支持 nmcli 和图形界面 |
Netplan 自己并不干活 ,它只是个「配置翻译器」:读取 /etc/netplan/*.yaml,根据配置里的 renderer 字段决定翻译给哪个后端;不写 renderer 时默认是 systemd-networkd。
报错里的 dbus-org.freedesktop.network1.service 正是 systemd-networkd 的 D-Bus 别名。结合刚看过的 00 文件------里面 ens33 的条目没写 renderer,Netplan 默认按 systemd-networkd 渲染,而后端没运行,所以应用失败。
如果 Netplan 或网络服务的报错看不懂,可以看日志找线索:
sudo journalctl -u NetworkManager --no-pager | tail -30(把服务名换成systemd-networkd也行)。
第 6 步:确认 NetworkManager 在运行
既然是桌面版 Ubuntu,正确的后端本应是 NetworkManager。先确认它是否在运行:
lua
systemctl status NetworkManager
状态是 active (running),而且是 enabled(开机自启)------NetworkManager 活得好好的。
思路就清晰了:不用再跟 Netplan 的 YAML 和没在运行的 systemd-networkd 较劲,直接让 NetworkManager 接管 ens33。
如果 NetworkManager 不在运行:
sudo systemctl enable --now NetworkManager启动它。万一它确实不可用,再退回 systemd-networkd 路线:sudo systemctl enable --now systemd-networkd,然后sudo netplan apply。
第 7 步:nmcli 让 NetworkManager 接管 ------ 网络立刻恢复
执行:
bash
nmcli device set ens33 managed yes
只跑了这一条,网络就通了:
ping baidu.com 成功解析出 IP(110.242.74.102)并正常收到回复。
为什么这一条命令就够了? 回头复盘,最可能的原因是:
00-installer-config.yaml为ens33声明了配置(内容残缺、没写 renderer,Netplan 默认渲染给 systemd-networkd),相当于把这块网卡认领到了 systemd-networkd 名下;- 而 systemd-networkd 并没有运行;
- 于是两个网络管家谁都没真正管
ens33:没有 DHCP 客户端工作 → 没有 IP → 路由表为空 → 网络不可达,DNS 报错也只是连带反应。
nmcli device set ens33 managed yes 把 ens33 交回 NetworkManager,它接管后自动建立连接、跑完 DHCP,网络立刻恢复。之前折腾的 Netplan routes、nameservers,在没人管网卡的前提下当然都不会生效。
三、让配置永久生效
nmcli device set 是运行时调整,重启后不保证保留。按下面几步把配置固化:
1. 确认连接已自动创建
sql
nmcli connection show
应该能看到一个 ens33 相关的连接(名字可能是 ens33 或 Wired connection 1)。如果没有,手动创建:
bash
nmcli connection add type ethernet ifname ens33 con-name ens33 autoconnect yes
2. 确认开机自动连接
bash
nmcli connection modify ens33 connection.autoconnect yes
(连接名以上一步实际显示的为准。)
3. 处理掉残缺的 Netplan 配置
把那份没有 IP 配置的 00-installer-config.yaml 移出 Netplan 的读取范围------Netplan 只读 .yaml 结尾的文件,改扩展名即可:
bash
sudo mv /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.yaml.disabled
直接删掉也可以,但改成
.disabled更稳妥,出问题还能改回来。
再确认 01-network-manager-all.yaml 内容是让 NetworkManager 全权接管:
bash
cat /etc/netplan/01-network-manager-all.yaml
应该是:
yaml
network:
version: 2
renderer: NetworkManager
4. 生效并重启验证
bash
sudo netplan apply # 让改动立即生效(也可以直接重启)
reboot
重启后重新登录,直接 ping baidu.com。依然能通,说明配置已经持久化,问题彻底解决。
四、排查链路小结与经验
完整链路:
- 现象 :
ping全不通、「网络不可达」,路由表为空; - 定位链路层 :
ens33是NO-CARRIER+DOWN→ 问题在 VMware 侧,不在 Ubuntu 内部; - 换成 NAT 模式 :网卡
UP了,但只拿到169.254.x.x→ DHCP 无人响应; - 查客户机配置 :三份 Netplan 文件冲突,
00内容残缺; netplan apply报错:配置渲染给了没在运行的 systemd-networkd;- 转折点 :确认 NetworkManager 在运行 → 一条
nmcli device set ens33 managed yes→ 网络立刻恢复; - 固化:设置开机自动连接 + 禁用残缺配置 + 重启验证。
一句话总结:两个网络管家谁都没管这块网卡,把它交给正确的管家(NetworkManager)后,问题当场解决。
几个值得记住的点
- 先分流再排查 :
ping IP和ping 域名各来一条,一秒判断是网络层还是 DNS 问题。 nmcli device status是个好起点:网卡归谁管、有没有连上,一眼看清,很多时候比直接改 YAML 快得多。- 看到
169.254.x.x就是 DHCP 失败:这不是路由器正常分配的地址,说明地址获取环节出了问题。 NO-CARRIER说明问题不在客户机内部:先去查 VMware 的网络设置(连接模式、绑定的物理网卡、是否勾选「已连接」)。- Netplan 只是「配置翻译器」 :不写
renderer默认交给 systemd-networkd;桌面版应与 NetworkManager 配套。 - 多份 Netplan 文件按数字顺序覆盖 :
/etc/netplan/下只保留需要的那份,多余的移走(改扩展名)比删掉更安全。 - 改完配置先
cat确认保存成功,避免改了半天却没生效。 - 新版 Ubuntu 默认不再自带
dhclient;重新获取地址用nmcli connection up <连接名>或netplan apply即可。