重启 Docker 导致 VMware 虚拟机断网:一次完整的故障排查记录
关键词: Docker · VMware NAT · iptables · ens33 NO-CARRIER · Xshell 断连
一、背景
在进行 Docker Harbor 私有镜像仓库的部署实验时,按照实验要求需要将 Harbor 的 HTTP 地址加入 Docker 的信任列表。具体操作是编辑 /etc/docker/daemon.json,添加 insecure-registries 字段后执行:
bash
systemctl restart docker
命令执行后,虚拟机卡顿了数秒,Xshell 随即断连,整个 Hadoop 集群的节点也全部失联。由于只能通过 VMware 控制台直接操作虚拟机,排查就此开始。
二、第一步排查:是否网段冲突?
第一反应是 Docker 的 docker0 网桥与 VMware 网段发生了冲突。Docker 默认使用 172.17.0.0/16 作为虚拟网桥网段,若与 VMware 的虚拟网络重叠,会导致路由混乱进而断网。
通过控制台登录虚拟机,执行:
bash
ip addr show docker0
ip route
输出关键信息如下:
IP address: 192.168.121.10 ← VMware ens33 主网卡
IP address: 192.168.122.1 ← virbr0 虚拟网桥
IP address: 172.17.0.1 ← docker0 网桥
docker0: inet 172.17.0.1/16
default via 192.168.121.2 dev ens33 ... linkdown ← 异常!
192.168.121.0/24 dev ens33 ... linkdown ← 异常!
结论: VMware 使用 192.168.121.x,Docker 使用 172.17.x.x,两者完全不重叠,排除网段冲突。但发现了新的关键异常:ens33 的状态是 linkdown。
三、第二步排查:NO-CARRIER 说明了什么?
尝试手动拉起网卡:
bash
ip link set ens33 up
ip addr show ens33
输出显示:
ens33: <NO-CARRIER, BROADCAST, MULTICAST, UP> state DOWN
NO-CARRIER 的含义是:网卡在操作系统层面已启用(UP),但没有检测到物理链路信号。这说明问题不在 Linux 内部的软件层,而是虚拟网卡与宿主机之间的链路断开了。
随后尝试 dhclient ens33 重新获取 IP,由于链路本身不通,dhclient 无响应,只能手动中断(Ctrl+C)。
结论锁定:问题在 Windows 宿主机侧,而非虚拟机内部。
四、第三步排查:VMware 图形设置是否正常?
打开 VMware 虚拟机设置 → 网络适配器,检查结果:
- 设备状态:已连接 ✓、启动时连接 ✓
- 网络连接:NAT 模式 ✓
VMware 图形化配置完全正常,问题进一步锁定在 Windows 宿主机上运行的 VMware NAT 后台服务本身。
五、解决方案
在 Windows 宿主机按 Win + R 输入 services.msc 打开服务管理器,找到以下两个服务,右键选择「重新启动」:
- VMware NAT Service(负责虚拟机与宿主机之间的网络地址转换)
- VMware DHCP Service(负责为虚拟机自动分配 IP)
两个服务重启完成后,回到虚拟机控制台验证:
bash
ping 192.168.121.2 -c 3
ping 通后,Xshell 重新连接 192.168.121.10 成功,Hadoop 集群各节点也全部恢复正常通信。整个恢复过程不足一分钟。
六、根本原因分析
Docker 与 VMware 都深度依赖 Linux 内核的 iptables 防火墙规则来实现网络转发。问题的触发链条如下:
执行 systemctl restart docker
↓
Docker 重建 docker0 网桥,刷新 iptables 的 FORWARD / MASQUERADE 转发规则
↓
iptables 规则的刷新干扰了 VMware NAT Service 依赖的数据包转发链路
↓
VMware NAT Service 转发异常,虚拟网卡 ens33 失去链路信号
↓
ens33 状态变为 NO-CARRIER,Xshell 连接超时断开
↓
Hadoop 集群节点间通信全部中断
本质上,这是 Docker 和 VMware 两个虚拟化工具共用宿主机网络转发机制时产生的规则竞争问题。Docker 刷新 iptables 时覆盖了 VMware NAT 的依赖规则,而 VMware NAT Service 没有感知到这一变化并自动恢复,导致持续失效直至手动重启服务。
七、预防建议
建议一:重启 Docker 前,在 Xshell 另开一个窗口持续 ping 网关
bash
ping 192.168.121.2
一旦发现断连,立刻去 Windows 的 services.msc 重启 VMware NAT Service,30 秒内即可恢复,比在虚拟机内部排查快得多。
建议二:在 daemon.json 中固定 docker0 的网段
json
{
"insecure-registries": ["http://192.168.116.101:80"],
"bip": "192.168.200.1/24"
}
明确固定 docker0 的网段,减少与 VMware 路由规则产生干扰的概率。
建议三:若问题频繁出现,检查 VMware NAT Service 的启动类型
将其设置为「自动(延迟启动)」,使其在系统和 Docker 稳定后再初始化 NAT 规则,可降低冲突概率。
八、总结
这次故障排查经历了三个阶段:
- 怀疑网段冲突 → 排除(两者网段不重叠)
- 发现
ens33 NO-CARRIER→ 定位到链路层,问题在宿主机侧 - 确认 VMware NAT Service 失效 → 找到根本原因,重启服务解决
在同一台 Windows 主机上同时运行 Docker 与 VMware Workstation 时,两者对 iptables 的竞争是一个已知的潜在冲突点。遇到 Xshell 突然断连的情况,优先去 Windows 宿主机检查 VMware 服务状态,往往比在虚拟机内部反复排查效率高得多。