vagrant nat网络问题-虚拟机同时存在两个IP,并且不能访问外网
nat网络问题
vagrant up 第二次时,用的nat网络,第一天用的192.168.156.100IP,但第二天启动时虽然IP配置的还是.100,但是实际上的IP时192.168.156.105,有两个IP情况并都能ping通,为什么?vagrant配置文件中的网络配置:config.vm.network “private_network”, ip: “192.168.56.100”
刨析
这是由 VirtualBox 的 Host-Only 网络适配器自动管理机制 引起的
vagrant 的配置:
config.vm.network “private_network”, ip: “192.168.56.100”
对应的是 VirtualBox 的 “Host-Only Adapter”,比如 vboxnet0。
关键点如下:
- VirtualBox DHCP Server 自动启用
当 VirtualBox 的 host-only 网络启用了 DHCP server(比如范围是 192.168.56.101-254),
而你的 VM 同时设置了静态 IP(.100),
VirtualBox 有时仍会给它分配一个 DHCP IP(例如 .105),结果就出现两个地址。
- Vagrant 会自动创建多个 Host-Only 网络
如果上次 vagrant up 时的 Host-Only 网络被删除或被改名,
Vagrant 发现配置不匹配,就会自动创建一个新的,比如 vboxnet1。
这时 VirtualBox 会分配新的 DHCP 范围,从而导致 IP 变化。
- NAT + Private Network(Host-Only) 共存是正常的
NAT 网络(10.0.2.x)用于访问外网;
Private Network(192.168.56.x)用于宿主机和虚拟机通信。
所以出现两个网卡是预期现象。问题在于第二个网卡的 IP 不是固定的。
解决方案
关闭 VirtualBox DHCP 服务(推荐)
在宿主机上执行:
VBoxManage list hostonlyifs
使用VBoxManage命令,需要在高级设置-系统环境变量-增加VBoxManage安装路径
找到你对应的 vboxnet0(或 vboxnet1)。
然后关闭 DHCP:
VBoxManage dhcpserver remove --netname HostInterfaceNetworking-vboxnet0
确认没有 DHCP 了:
VBoxManage list dhcpservers
(base) PS E:\centos\virtualboxvm\centos701> VBoxManage list dhcpservers
NetworkName: HostInterfaceNetworking-VirtualBox Host-Only
Ethernet Adapter Dhcpd IP: 192.168.56.100
LowerIPAddress: 192.168.56.101
UpperIPAddress: 192.168.56.254
NetworkMask: 255.255.255.0
Enabled: Yes
Global Configuration: minLeaseTime: default defaultLeaseTime: default maxLeaseTime: default Forced options: None Suppressed opts.: None 1/legacy: 255.255.255.0
Groups: None Individual
Configs: None
再执行:
vagrant reload
此时 VM 启动后就会固定为你设定的 .100。
解决具体分析dhcpservers
VirtualBox 的 Host-Only 网络(即 Vagrant 的 private_network 所用的那张)
DHCP 服务处于 启用状态(Enabled: Yes)DHCP 分配范围是:
192.168.56.101 → 192.168.56.254
🚨 问题原因
你在 Vagrantfile 中手动指定的静态 IP 是:
config.vm.network “private_network”, ip: “192.168.56.100”
而 DHCP 本身的网关地址就是 192.168.56.100(Dhcpd IP),
VirtualBox 会认为 .100 是它自己 DHCP 服务器的管理地址,
因此它拒绝让虚拟机真正使用 .100,而是自动为 VM 分配一个 .105(或别的)地址。
所以你看到的情况是:
你配置 .100
实际上虚拟机获得 .105(来自 DHCP)
两个 IP 同时存在(一个静态,一个动态)
✅ 解决方案
🔧 方法一:彻底禁用 VirtualBox DHCP(推荐)
执行以下命令(在 PowerShell 或 CMD 中):
VBoxManage dhcpserver remove --netname “HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter”
然后确认已经移除:
VBoxManage list dhcpservers
如果不再输出任何条目(或输出为空),表示 DHCP 已关闭。
接着执行:
vagrant reload
或者更彻底一点:
vagrant halt
vagrant up
此时你的虚拟机就会真正只使用 192.168.56.100。
删除DHCP后启动问题
删除DHCP后,(base) PS E:\centos\virtualboxvm\centos701> vagrant reload
==> default: Clearing any previously set network interfaces...==> default: Preparing network interfaces based on configuration...default: Adapter 1: nat default: Adapter 2: hostonly ==> default: Forwarding ports... default: 22 (guest) => 2222 (host) (adapter 1) There was an error while executing VBoxManage, a CLI used by Vagrant for controlling VirtualBox. The command and stderr is shown below. Command: ["modifyvm", "12ad75a0-b675-45b3-ae7a-f11fd8870d81", "--natpf1", "ssh,tcp,127.0.0.1,2222,,22"] Stderr: VBoxManage.exe: error: A NAT rule of this name already exists VBoxManage.exe: error: Details: code E_INVALIDARG (0x80070057), component NATEngineWrap, interface INATEngine, callee IUnknown VBoxManage.exe: error: Context: "AddRedirect(Bstr(strName).raw(), proto, Bstr(strHostIp).raw(), RTStrToUInt16(strHostPort), Bstr(strGuestIp).raw(), RTStrToUInt16(strGuestPort))" at line 2200 of file VBoxManageModifyVM.cpp
🧩 错误说明
错误信息:
VBoxManage.exe: error: A NAT rule of this name already exists
这句话的意思是:
VirtualBox 在为 NAT 网络添加端口转发规则(比如 ssh → 2222)时,发现已有一个同名规则存在。
也就是说:
Vagrant 想设置一个 NAT 端口转发:
Host 127.0.0.1:2222 → Guest 22
但是 VirtualBox 的 VM 中已经存在一个叫 ssh 的转发规则了。
⚙️ 原因
Vagrant 在创建虚拟机时,会自动添加一个 NAT 转发:
ssh,tcp,127.0.0.1,2222,22
用于 vagrant ssh 命令。
而当你执行 vagrant reload、vagrant up、vagrant halt 时,
Vagrant 有时不会完全清理旧的 NAT 规则,导致下次启动时冲突。
✅ 解决方案
让 Vagrant 自动修复 NAT 规则
执行:
vagrant halt
vagrant up --provision
这会强制 Vagrant 重新配置虚拟机网络,有时能自动清除冲突的 NAT 规则。
关键参数: --provision ,重置网络
✅ 注意
vagrant的配置和虚拟机中的网卡配置的IP需要相同
ip a 发现没有IP了?
ip a 竟然没有IP地址了??
1: lo: ...inet 127.0.0.1/8 ← 本地回环地址(正常)
2: eth0: ...link/ether 52:54:00:16:60:86 ← 没有 inet(说明没分配 IP)
3: eth1: ...link/ether 08:00:27:37:44:ed ← 也没有 inet(说明没分配 IP)
也就是说:
eth0(NAT)没有获取到 10.0.2.x;
eth1(Host-Only)也没有获取到你设定的 192.168.56.100;
DHCP 又被你禁用了;
所以现在两个网卡都没 IP。
🧩 这通常是因为:
Vagrant 没有正确写入虚拟机的网络配置(可能在 reload 时 DHCP 已关但未重新配置 ifcfg-* 文件)。
✅ 解决方法
检查网卡配置文件(永久修复)
在虚拟机中:
cd /etc/sysconfig/network-scripts/
ls ifcfg-*
你应该能看到:
ifcfg-eth0
ifcfg-eth1
打开 ifcfg-eth1:
cat ifcfg-eth1
如果内容中没有 BOOTPROTO=static 或 IPADDR=192.168.56.100,可以编辑:
vi ifcfg-eth1
修改为:
TYPE=Ethernet
BOOTPROTO=static
IPADDR=192.168.56.100
NETMASK=255.255.255.0
ONBOOT=yes
然后重启网络服务:
systemctl restart network
你以为这就完事了??天真了
vagrant up启动后 ip a 没有IP地址,但是vagrant reload/up --provision 启动后有ip地址
✅ 原因分析
Vagrant 在启动虚拟机时,分几个阶段配置网络:
- 阶段 1:VirtualBox 创建网卡(vboxnet / NAT)
这是 VirtualBox 层面;
只是分配了虚拟网卡,并未写入 Linux 的网络配置文件。
- 阶段 2:Guest OS 启动时加载 /etc/sysconfig/network-scripts/ifcfg-*
如果你第一次启动或 DHCP 被禁用,而 Vagrant 没来得及注入配置文件,
那么系统网络服务起不来,结果是:ip a 里没 IP。
- 阶段 3:Vagrant 的 “provisioner” 介入
当你执行 vagrant reload --provision 或 vagrant up --provision 时,
Vagrant 会触发内部脚本(通过 “guest capability”),
自动创建/修复 /etc/sysconfig/network-scripts/ifcfg-eth1。
💡 换句话说:
vagrant up 只启动虚拟机;
vagrant reload --provision 才真正重新配置网络。
✅ 为什么第二次会有 IP
因为第一次启动时 Vagrant 没写入配置文件,
第二次执行 --provision 时,Vagrant 检测到缺失的网络配置并补上了。
从那一刻起,虚拟机的 /etc/sysconfig/network-scripts/ifcfg-eth1 已经被写入:
TYPE=Ethernet
BOOTPROTO=static
IPADDR=192.168.56.100
NETMASK=255.255.255.0
ONBOOT=yes
之后的每次启动(只要文件没丢)都能正常拿到 IP。
🩹 永久解决办法(推荐)
为了让 vagrant up 第一次就有 IP,可以用以下方法之一:
✅ 方法 1:强制 Vagrant 每次都重新配置网络(使用这种)
在 Vagrantfile 中加入:
config.vm.provision "shell", run: "always", inline: <<-SHELLsystemctl restart network || systemctl restart NetworkManager
SHELL
作用:
每次 vagrant up 启动时,都会强制重新加载网络;
无论 DHCP 是否关闭,都能拿到配置好的 IP。
✅ 方法 2:确保网络接口持久化(适用于 CentOS)(但是已经之前已经配置,但是不好使)
进入虚拟机后确认 /etc/sysconfig/network-scripts/ifcfg-eth1 存在且内容如下:
TYPE=Ethernet
BOOTPROTO=static
IPADDR=192.168.56.100
NETMASK=255.255.255.0
ONBOOT=yes
DEVICE=eth1
如果文件存在且正确,那么下次 vagrant up 时不再需要 --provision。
那么问题解决,那我们深入研究下为什么会出现这种问题
深入刨析
灵魂拷问:问题解决了,但是我在vagrant配置文件是指定了私有静态IP,那问什么DHCP还生效?
🧩 核心答案(先说结论)
因为 VirtualBox 的 Host-Only 网络层面仍启用了 DHCP 服务,而 Vagrant 的“静态 IP”仅仅在虚拟机内部配置,并不会影响 VirtualBox 的 DHCP 行为。
换句话说:
Vagrant 负责告诉虚拟机:“你用 192.168.56.100 吧”;
VirtualBox 负责告诉所有连接到 vboxnet0 的机器:“如果你没 IP,我可以分配给你 192.168.56.101~254”;
两者互相独立。
所以,即使你设置了静态 IP,VirtualBox 的 DHCP 服务仍在运行(只是你的虚拟机没去申请它的 IP)。
🧠 详细解释机制
我们分成两层看:
- Vagrant 层(Guest 配置)
当你在 Vagrantfile 中写:
config.vm.network “private_network”, ip: “192.168.56.100”
Vagrant 会在虚拟机内部生成一个配置文件(例如 /etc/sysconfig/network-scripts/ifcfg-eth1):
BOOTPROTO=static
IPADDR=192.168.56.100
NETMASK=255.255.255.0
ONBOOT=yes
这仅影响 虚拟机内部。
- VirtualBox 层(Host 配置)
VirtualBox 在宿主机上有一个叫 “Host-Only Adapter” 的虚拟网卡,例如:
VirtualBox Host-Only Ethernet Adapter (vboxnet0)
这个网卡是宿主机和 VM 之间通信的桥梁。
在这个网卡上,VirtualBox 可能启用了 DHCP 服务:
VBoxManage list dhcpservers
NetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter
Dhcpd IP: 192.168.56.100
LowerIPAddress: 192.168.56.101
UpperIPAddress: 192.168.56.254
Enabled: Yes
只要 Enabled: Yes,那 DHCP 服务就在运行。
即便你的虚拟机不请求 DHCP,它依然会“提供”这个功能。
💡 那为什么有时 DHCP 会“干扰”静态 IP?
如果你:
指定的静态 IP 在 DHCP 范围内(比如 .100 刚好是 DHCP server IP),或
虚拟机在启动时先通过 DHCP 拿到一个地址(比如 .105),然后再写入 .100,
就可能导致:
系统同时存在两个 IP;
或 Vagrant 日志显示 eth1: DHCP assigned IP address.
这就是你之前遇到的“明明设了静态 IP 却变成 .105” 的根本原因。
✅ 如何验证现在 DHCP 仍在生效
在宿主机执行:
VBoxManage list dhcpservers
如果输出中仍有:
Enabled: Yes
就说明 DHCP 服务还开着
✅ 解决办法(如果你不想让 DHCP 干扰)
有两种做法:
🩹 方法 1:彻底关闭 VirtualBox DHCP(推荐)
VBoxManage dhcpserver remove --netname “HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter”
然后确认:
VBoxManage list dhcpservers
为空即可。
Vagrant 的静态 IP 就完全独立,不会再被分配到动态地址。
🩹 方法 2:保持 DHCP 但避开它的范围
假设 VirtualBox 的 DHCP 范围是:
192.168.56.101 - 192.168.56.254
你只需要把 Vagrant 的静态 IP 设为 .10 或 .50:
config.vm.network “private_network”, ip: “192.168.56.10”
这样 DHCP 还在运行,但永远不会分配 .10,不会冲突。
我们总结下
- 环境
vagrant ,VBoxManage 做虚拟环境,系统:centos7
- 网络
使用Nat环境网络,以防影响公司整体网络环境
- 问题
使用vagrant up第一次初始化虚拟系统环境没问题,配置的私有静态IP也能正常放,但是,第二次启动时,虚拟环境的IP变成另一个了,并且之前配置的静态IP也能够ping通,会出现同时出现两个IP
比如:vagrant配置的静态私有IP为:192.168.1.100,第二次启动变成了:192.168.1.104,但是也能ping通.100的IP
而且会出现访问不了外网,比如:ping www.baidu.com,会出问题
- 原因
究其根本原因是host-only网络是自动启动了DHCP(动态获取IP)
- 解决方案
我使用的第一种:彻底关闭 VirtualBox DHCP,当然也可以用第二种避开自动识别的网段
这下彻底踏实了,问题比较彻底查清楚了。
