VMware 虚拟机 Ubuntu 无法连接网络

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

截图里有两个关键点:

  1. ens33 没有 IP :只有 link/ether(MAC 地址),没有 inet 开头的 IPv4 地址。
  2. 状态是 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) :只能和宿主机通信,上不了外网。
  • 「已连接」和「启动时连接」两个复选框:确认都勾上了,有时候不小心取消勾选,网卡就会处于未连接状态。

如果坚持用桥接,去「编辑 → 虚拟网络编辑器」检查 VMnet0(桥接)绑定的物理网卡,是不是当前真正在用的那块(比如无线网卡)。

本次的处理很直接:把网络适配器从桥接改成 NAT。

改完再进系统看,ens33 已经是 UP、有载波了,但拿到一个奇怪的地址:

169.254.186.80 是 Link-Local 地址 (也叫 APIPA):系统向 DHCP 请求地址失败时,给自己分配的临时地址,只能在本地链路通信,不能上网 。拿到它说明 DHCP 请求没人回应。

NAT 模式下,VMware 会在宿主机上虚拟出 VMnet8 网段(通常是 192.168.x.0/24),由 VMware 的 DHCP 服务负责发地址。拿不到地址的原因无非三类:

  1. 宿主机上 VMware 的 NAT/DHCP 服务没启动;
  2. VMnet8 虚拟网络组件损坏或没安装好;
  3. 客户机侧没有一个在工作的 DHCP 客户端(网络配置或管理服务的问题)。

本次先排查第 3 类(客户机侧),因为之前动过 Netplan 配置,嫌疑最大。

备用排查:客户机侧没问题,再回宿主机看
  • Windows 上 Win + R 输入 services.msc,确认以下服务均在运行,没运行就右键启动:

    • VMware DHCP Service
    • VMware NAT Service
    • VMware 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。依然能通,说明配置已经持久化,问题彻底解决。

四、排查链路小结与经验

完整链路:

  1. 现象 :ping 全不通、「网络不可达」,路由表为空;
  2. 定位链路层 :ens33 是 NO-CARRIER + DOWN → 问题在 VMware 侧,不在 Ubuntu 内部;
  3. 换成 NAT 模式 :网卡 UP 了,但只拿到 169.254.x.x → DHCP 无人响应;
  4. 查客户机配置 :三份 Netplan 文件冲突,00 内容残缺;
  5. netplan apply 报错:配置渲染给了没在运行的 systemd-networkd;
  6. 转折点 :确认 NetworkManager 在运行 → 一条 nmcli device set ens33 managed yes → 网络立刻恢复;
  7. 固化:设置开机自动连接 + 禁用残缺配置 + 重启验证。

一句话总结:两个网络管家谁都没管这块网卡,把它交给正确的管家(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 即可。
相关推荐
酬谢神明则必安2 小时前
git学习记录01
linux·git·学习
Ruiery2 小时前
Linux 6.6内核 CPU 深度解析(五):CPU 空闲状态机 cpuidle
linux·运维·服务器
殷色玫瑰3 小时前
C语言编译和链接:从 .c到 .exe,程序到底经历了什么?
linux·c语言·c++·算法
菜鸟~noob2333 小时前
【太空电子战】午夜锤行动中的电磁静默区:可逆干扰的实战验证【含matlab代码】
linux·开发语言·matlab·电子战
Fcy6484 小时前
Linux下 传输层协议TCP详解
linux·网络·tcp/ip
BIM云平台开发4 小时前
DAZ里,如何保存现在姿势,如果调错了,可以重新导回
linux·服务器·前端·daz基础教程
栖凤4 小时前
多 Agent 工作流实践:从单打独斗到协同作战
java·linux·服务器
羔羊++5 小时前
20_实验十九_内核源码准备与配置
linux
askama005 小时前
Ubuntu安装Anaconda并配置环境
linux·python