ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

VMware NAT服务僵死导致Ubuntu虚拟机无法上网的排查指南

VMware NAT服务僵死导致Ubuntu虚拟机无法上网的排查指南 早上到工位打开 VMware Workstation 里的 Ubuntu 虚拟机想先 ping 一下外网确认环境还活着结果一连串 timeout。第一反应都是“我昨天是不是把 Ubuntu 网络配置给弄坏了”又是查 netplan 又是看 NetworkManager折腾半小时一无所获。后来才反应过来——虚拟机 IP 明明还在网关却像死了一样问题根本不在 Ubuntu 里面而是 Windows 宿主机上的 VMware NAT 服务不知道什么时候卡死了。这篇文章就是写给被这个问题折磨过十分钟以上的人。我会从 NAT 模式的链路原理讲起给你一套一分钟的定位方法再给出 Windows 侧和 Ubuntu 侧的具体操作最后聊聊怎么减少复现、以及那剩下的 10% 到底该往哪查。干这行的都知道虚拟机能不上网和不能上网查错方向才是最大的浪费时间。1. vmnet 数据链路NAT 模式下一个网络包到底走了哪几步1.1 三种网络模式的本质区别VMware Workstation 给虚拟机提供了三种主流上网方式很多人从来没搞明白它们的差异排错的时候自然抓瞎。我先用一张表把底层逻辑说清楚。模式虚拟机的 IP 从哪来外网访问怎么实现典型适用场景桥接模式和宿主机同一网段由路由器 DHCP 分配虚拟机直接使用物理网卡就像局域网里独立的一台电脑需要被局域网其他机器直接访问NAT 模式由 VMware 内部 DHCP 分配通常是 192.168.x.0/24 网段通过宿主机上的 NAT 服务做地址转换后出去虚拟机只需要上网不需要被外部直接访问仅主机模式由 VMware 内部 DHCP 分配不能出外网只能和宿主机、同网段虚拟机通信本地测试隔离环境NAT 模式是绝大多数人默认在用的方案因为省事、不占局域网 IP而且宿主机切到断网环境时虚拟机之间的网络仍然可用。但省事往往意味着中间多了一层看不见的东西这层东西一旦出问题表现就是“IP 正常但出不去”。1.2 NAT 链路中谁是那个“门卫”NAT 模式下的完整数据链路是这样的Ubuntu 发出网络包 → 虚拟网卡 VMnet8 → VMware NAT ServiceWindows 宿主机上的一个服务进程→ 宿主机物理网卡 → 路由器 → 互联网。这个 VMware NAT Service 就是整个链路的“门卫”。它干两件事一是给 VMnet8 网段内的虚拟机分配 IP 地址配合 VMware DHCP Service二是做网络地址转换把 Ubuntu 发出的内网包源地址换成宿主机物理网卡的地址等外网返回之后再翻译回去交给对应的虚拟机。你可以把 NAT 服务想象成小区传达室的门卫。虚拟机是小区里的住户快递网络包送到门口时门卫得对着登记表看一眼该怎么派送。如果门卫生病请假了住户照样有门牌号、照样能在小区里走来走去但外面的快递就是送不进来里面的包裹也发不出去。这就是“虚拟机能拿到 IP但 ping 不通外网”时最典型的病理特征。关键点在于这个门卫住在 Windows 宿主机上不是 Ubuntu 里的任何进程。所以它在 Windows 侧罢工你在 Ubuntu 里改 IP、删路由、重配 DNS全是无用功。这也是为什么很多人折腾半天不得要领——对手根本不在那个战场上。2. 四条 ping 的定位术一分钟判断 NAT 服务是否真的卡死2.1 先看现象判断“像不像” NAT 卡死在动手敲任何命令之前先对照一下现象清单。NAT 服务卡死僵死时通常同时出现这几个特征Ubuntu 虚拟机里的网络图标显示正常ip addr能看到 192.168.x.x 的地址虚拟机 ping 外网域名、外网 IP 全部不通宿主机 Windows 本身能正常上网在 Windows 服务管理器里看 VMware NAT Service状态栏也许还写着“正在运行”重启 Ubuntu 虚拟机无效问题依旧。最后一条非常迷惑人。很多人 ping 不通外网后第一件事就是重启 Ubuntu结果发现开机后依然不行于是认定是 Ubuntu 系统坏了。实际上 VMware 的 NAT 服务卡死属于“僵尸状态”虚拟机重启多少次它都不会自己好必须从宿主机侧把它唤醒。还需要提醒一点服务状态显示“正在运行”不代表它工作正常。如果它内部的事件循环已经卡死状态列一样可以是绿的。所以排错不能只看服务状态要看实际的连通性。2.2 关键一 pingNAT 网关 192.168.x.2 vs 宿主机 192.168.x.1很多人排错时习惯去 ping 宿主机虚拟网卡的地址比如 192.168.88.1发现能通就觉得网络链路没问题。这是个巨大的误区。在 VMware 的 NAT 模式里VMnet8 网段的 IP 分配是有讲究的通常.1是宿主机虚拟网卡 VMnet8 自己的地址.2才是 NAT 网关。真正负责把包转出外网的是.2。换句话说你的虚拟机到宿主机这一段可以通因为 VMnet8 这个虚拟交换机还活着但网关不通意味着包根本没人帮你转出去。这就像你在小区里能走到门卫室门口但门卫室里没人你照样出不了小区大门。Ubuntu 里执行下面这组命令就能一眼看清ip route看一下默认路由的地址是不是 192.168.x.2。如果是那就直接 ping 这个网关ping -c 4 192.168.x.2如果这个网关 timeout而同时ping -c 4 192.168.x.1正常响应那我几乎可以断定就是 VMware NAT Service 的事。2.3 四步隔离把问题切成两半与其凭感觉猜不如用四层 ping 把故障位置框死。进入 Ubuntu 虚拟机后按顺序执行以下四类探测测试内容命令示例正常结果NAT 服务卡死时的典型表现宿主机虚拟网卡ping 192.168.88.1通通常仍然通NAT 网关ping 192.168.88.2通不通千分之千的 timeout公网 IPping 223.5.5.5通不通域名ping www.baidu.com通不通或提示 temporary failure这里的 192.168.88.x 只是示例网段实际以你自己的 VMnet8 网段为准。223.5.5.5 是阿里公共 DNS用来探测纯 IP 通断最合适因为不依赖域名解析。如果网关 ping 不通问题基本锁定在宿主机侧的 NAT 服务或虚拟网络组件剩下的章节接着讲。如果网关通、公网 IP 通、但域名不通那就完全是另一回事了——这是 DNS 解析问题和 NAT 服务没有关系别冤枉它。提示ping: www.baidu.com: temporary failure in name resolution这个报错的意思是“域名解析临时失败”不是网络断了。把焦点放到 /etc/resolv.conf、systemd-resolved 或 DHCP 下发的 DNS 服务器上别去重启 NAT 服务。2.4 在 Windows 宿主机上确认服务状态如果在 Ubuntu 侧已经高度怀疑 NAT 服务那就切到 Windows 宿主机用管理员身份打开命令提示符执行sc query VMware NAT Service sc query VMware DHCP Service看输出的 STATE 列。如果 VMware NAT Service 显示 STOPPED或者服务根本不存在问题就非常清晰了。如果显示 RUNNING但第二步的网关 ping 依然不通同样按卡死处理——这就好比我前面说的“僵尸状态”状态列骗人。再配合看一个信息Windows 下执行ipconfig /all找到 VMnet8 虚拟网卡以太网适配器 VMware Network Adapter VMnet8。正常情况下它应该有一个 192.168.x.1 的 IPv4 地址。如果它变成 169.254.x.x 这种 APIPA 地址说明 VMnet8 本身没有正常初始化需要处理的就不只是 NAT 服务可能还要重置虚拟网络组件这部分放到第 5 节说。3. 服务重启三板斧Windows 侧恢复Ubuntu 侧配合3.1 图形界面services.msc 里让它重新站岗最直观的方式自然是 Windows 服务管理器。Win R 输入services.msc回车在服务列表里找到“VMware NAT Service”右键选择“重启”。这里有个小坑如果你的 Windows 用户不是管理员权限右键菜单里的“重启”可能是灰的直接提示“拒绝访问”。这种情况别硬点关掉窗口在开始菜单里找到命令提示符或 PowerShell右键“以管理员身份运行”在里面输入services.msc打开的服务管理器就有足够权限操作了。如果“重启”按钮确实不可用那就分开操作先点“停止”等状态变成“已停止”后再点“启动”。一般来说 VMware NAT Service 重启过程非常快几秒钟就能完成。注意重启瞬间所有依赖 NAT 模式的虚拟机网络会闪断如果虚拟机里正在跑下载、SSH 会话、长时间编译任务先有心理准备。3.2 命令行一条命令解决的问题不要点鼠标我更推荐直接用命令行尤其是在远程桌面连宿主机的时候图形界面来回点很烦。管理员命令提示符里执行net stop VMware NAT Service net start VMware NAT Service ipconfig /flushdns如果系统提示找不到服务先列出所有 VMware 相关服务确认服务名sc query state all | findstr /i vmware看到的确切服务名后再执行上面的 stop/start。如果你懒得每次手敲可以做成一个批处理脚本保存成fix-vmware-nat.bat右键管理员运行echo off net stop VMware NAT Service nul 21 net start VMware NAT Service ipconfig /flushdns nul echo VMware NAT Service restarted. pause这个脚本我用了很长时间每次怀疑 NAT 卡死直接双击半小时寿命就回来了。别小看这种土办法干运维的都知道越简单的工具越顺手。3.3 Ubuntu 侧配合重拿一次网络配置Windows 侧服务重启完成后回到 Ubuntu 虚拟机。多数情况下网络会自己恢复因为 NAT 服务重启会重新初始化虚拟网络DHCP 租约通常也能续上。但如果你看到网络还是不通或者 IP 变成陌生网段说明 Ubuntu 侧的网络配置需要重新触发一次。桌面版 Ubuntu 最简单的方法点击右上角网络图标断开当前连接再重新连接。命令行环境则用 NetworkManager 的接口sudo nmcli networking off sudo nmcli networking on或者针对具体连接操作sudo nmcli connection down Wired connection 1 sudo nmcli connection up Wired connection 1用ip addr看一眼当前的连接名再替换。如果是 Ubuntu Server 且没装 NetworkManager可以试试重新请求 DHCPsudo dhclient -r sudo dhclient-r释放旧租约第二次执行重新获取。注意新版 Ubuntu 可能默认用了 systemd-networkd那就在/etc/netplan/下执行sudo netplan apply让配置重新生效。这几条属于“按需选用”哪个适合你的环境就用哪个。提示如果你在 Ubuntu 里发现 IP 已经恢复但 ping 外网还是很慢或者第一次必失败不要慌多 ping 两次。NAT 服务刚启动时内部地址映射表是空的第一个包往往用于“握手”第二个包开始就顺畅了。4. 病根在哪NAT 服务为什么总在关键时刻掉链子4.1 这些场景我亲测最容易触发卡死找到问题不难难的是弄明白它为什么反复出现。根据我自己的踩坑经验和社区里的反馈以下场景最容易触发 VMware NAT Service 卡死宿主机从睡眠或休眠状态唤醒后虚拟网卡和 NAT 服务之间经常“失联”电脑从无线切换到有线、或者反过来物理网卡发生变化导致 NAT 出口失效Windows 更新后网络堆栈被重建VMware 服务没有自动重新初始化VMware Workstation 长时间不退出NAT 内部维护的地址映射表累积异常某些安全类软件在后台扫描或拦截了 vmnet-nat.exe 的通信。用前面那个门卫的类比NAT 服务手里有一张访客登记表里面记着“哪个内网 IP 从哪个端口出去回来时该送到哪”。宿主机休眠唤醒、物理网卡切换之后网络环境等于变了但 NAT 服务手里的表和新的出口对不上于是所有从虚拟机出来的包都卡死在“翻译”环节。Windows 的快速启动是另一个常见诱因。快速启动本质上让 Windows 关机时进入一种混合休眠状态下次开机时恢复系统内核和驱动状态。VMware 服务在这种恢复过程中可能没有拿到完整的网络栈状态于是出现“服务显示运行、实际干不了活”的情况。4.2 能降低复现概率的几个操作明白了触发机制就能针对性做几件事来降频。不需要玄学都是系统层面的常规设置第一在 Windows 的“设备管理器 → 网络适配器 → 物理网卡 → 电源管理”里把“允许计算机关闭此设备以节约电源”勾掉。这个选项经常导致虚拟机网络睡死。第二关闭 Windows 的快速启动。“控制面板 → 电源选项 → 选择电源按钮的功能 → 更改当前不可用的设置”把“启用快速启动”取消勾选。第三给 VMware NAT Service 设置自动恢复。在 services.msc 里打开 VMware NAT Service 的“属性 → 恢复”选项卡把“第一次失败”“第二次失败”“后续失败”都改成“重新启动服务”重置失败计数改为 1 天。这样即使服务崩溃Windows 也会自动把它拉起来不至于默默卡死一天。第四别让 VMware Workstation 连续运行几个月不退出。没任务的时候定期关闭虚拟机、关掉 Workstation释放虚拟网络组件的资源。版本也尽量保持在较新的稳定版老版本的网络组件 bug 通常在新版修复。4.3 自动化兜底写个小脚本自己检测即便做了上面这些NAT 服务偶尔还是会犯病。想完全不管它可以写一个简单的监控脚本思路非常朴素定期 ping NAT 网关ping 不通就自动重启服务。echo off ping -n 2 192.168.88.2 nul 21 if errorlevel 1 ( net stop VMware NAT Service nul 21 net start VMware NAT Service )记得把 192.168.88.2 改成你实际的 VMnet8 网关地址。把这个脚本交给 Windows 任务计划程序设置成每分钟执行一次甚至可以设为“无论用户是否登录都运行”能最大程度避免人肉盯梢。不过我心里很清楚这只能是兜底真正的根治还得靠前面的设置。5. 重启服务依然不通剩下的 10% 按这个顺序排雷5.1 Ubuntu 内部配置的“最后一根稻草”如果你重启了 NAT 服务网关也通了但外网还是不通这时候才轮到 Ubuntu 的内部配置背锅。先按顺序自查ip addr ip route cat /etc/resolv.confip route里必须能看到default via 192.168.x.2这条默认路由。如果默认路由丢失或网关写错网络肯定出不去。/etc/resolv.conf里至少要有可用的 nameserver例如 223.5.5.5 或 114.114.114.114。如果你之前给 Ubuntu 配置过静态 IP更要检查网段是否和 VMnet8 一致。我见过有人把静态 IP 设成 10.0.0.x而 VMware NAT 网段是 192.168.88.x这种情况无论 NAT 服务多健康都救不回来。手动配置过 netplan 的跑一下sudo netplan apply如果一切网络配置都正常再考虑清理一下 NetworkManager 的缓存或重启 systemd-networkd。但必须说清楚这一步是在确认 NAT 服务没问题之后做的不要一上来就动 Ubuntu 内部的配置否则就是在错误的方向上使劲。5.2 虚拟网络编辑器里的 VMnet8 被你改坏了很多踩过坑的人可能都干过这件事在“虚拟网络编辑器”里乱改 VMnet8 的配置。改的时候界面很低风险实际上里面每一处都有关联。网段改了、DHCP 范围改了、NAT 设置里的网关地址改了任何一处和你 Ubuntu 内部配置对不上结果就是各种莫名其妙的网络问题。打开 VMware Workstation 的“编辑 → 虚拟网络编辑器”点击右上角“更改设置”获得管理员权限选中 VMnet8检查三个地方子网 IP 和子网掩码、DHCP 设置、NAT 设置里的网关 IP。正常情况这三个必须在同一网段内且网关 IP 和 Ubuntu 默认路由用的是同一个地址。如果你的配置已经乱得看不出规律干脆点左下角“恢复默认设置”。但做之前一定先把当前各 VMnet 的配置截图或记下来——这个操作会把所有自定义虚拟网络全部重置。恢复默认后重新建立 VMnet8再把 Ubuntu 这边改成 DHCP 自动获取基本能解决大部分自伤型故障。5.3 Windows 防火墙与安全软件的“课外作业”还有一种情况NAT 服务正常、Ubuntu 配置正常、网段没问题但网络就是不通。这时候往 Windows 防火墙和安全软件方向想。VMware 安装时会自动在 Windows 防火墙里放行 vmnet-nat.exe、vmnetdhcp.exe 等程序的通信。但如果你的 Windows 防火墙策略比较严格或者安全软件做了额外的网络防护这些规则可能被清除或拦截。检查方法Windows 安全中心 → 防火墙 → 允许应用通过防火墙确认 VMware Workstation 相关项是否勾选同时检查当前网络配置文件类型是“专用”还是“公用”专用网络下虚拟机网络通常更省心。某些安全软件还会禁止 VMware 服务开机自启或者在后台把 VMware NAT Service 给停了。去服务管理器里确认启动类型是否为“自动”如果被改成“手动”或“禁用”改回来并启动服务。5.4 终极三板斧按顺序做不要跳过如果上面所有思路都试过仍然不通那就是虚拟网络组件本身的异常。我给自己定过一个“终极三板斧”顺序不跳跃、不省略依次执行彻底退出 VMware Workstation 和所有虚拟机包括托盘图标右键退出以管理员身份打开“虚拟网络编辑器”点“恢复默认设置”等待虚拟网络组件重建完成重启 Windows。三步走完VMware 的虚拟网卡驱动和 NAT/DHCP 服务都会重新初始化绝大多数深层问题都能解决。如果还不通那就考虑卸载并重装 VMware Workstation建议同时卸载虚拟网络相关组件。我见过的最极端案例也就是走到这一步就恢复了。实际上我很少听说有人需要重装 Ubuntu 才能解决这类问题——只要 Windows 宿主的虚拟网络能吃Ubuntu 那边几乎都是无辜的。我在实际处理这个问题时已经养成了一套条件反射只要 Ubuntu 虚拟机 ping 不通外网我第一件事永远是切到宿主机重启 VMware NAT Service而不是打开 Ubuntu 的 terminal 一通乱查。这套流程帮我在各种线上线下场景里省下了大量时间。最后再分享一个小习惯虚拟机长时间挂机过夜之前先在 Ubuntu 里跑一次ping -c 3 www.baidu.com确认链路正常。第二天早上如果发现连不上不要犹豫直接重启 NAT 服务大概率立刻恢复。虚拟化这东西偶尔僵一下是常态与其纠结“为什么又犯病”不如把恢复动作练成肌肉记忆。省下来的时间去泡杯茶不好吗。
返回列表