1. 为什么你的虚拟机需要两张“网卡”?
最近在折腾一个本地开发环境,我遇到了一个挺典型的场景:我在VirtualBox里装了一个Ubuntu 22.04的虚拟机,用来跑一个Web服务。这个服务呢,我既希望它能从我的Windows宿主机上直接访问,方便我调试前端页面,又希望这个虚拟机本身能畅通无阻地上网,去下载各种依赖包、更新系统。听起来是不是很合理?但VirtualBox默认只给虚拟机配一张网卡,而且通常是NAT模式。这个模式有个特点,虚拟机上网很方便,像自带了一个“路由器”,但宿主机想主动访问虚拟机里的服务,就像进了一个没有门牌号的房子,根本找不到路。
我当时就卡在这里了,虚拟机里的服务跑起来了,curl localhost 能通,但宿主机浏览器死活连不上。查了一圈资料,发现很多教程要么只讲桥接,要么只讲主机模式,对于我这种“既要又要”的需求,说得不够透。后来我摸索出了“双网卡”这个方案,一张卡(NAT)负责让虚拟机冲浪,另一张卡(主机模式)负责在虚拟机和宿主机之间搭一座专属的“内部桥梁”。实测下来,这个方案非常稳,配置一次就一劳永逸。
所以,这篇文章就是把我踩过的坑和验证过的步骤,用最直白的方式分享给你。无论你是刚接触虚拟机的开发者,还是需要搭建复杂网络环境的学习者,只要跟着步骤走,半小时内就能搞定这个“内外兼修”的网络环境。我们不光讲操作,还会聊聊这背后的网络小知识,让你知其然也知其所以然。
2. 先搞懂VirtualBox的“网络江湖”
在动手配网卡之前,我们得先摸清楚VirtualBox提供的几种网络模式都是干嘛的。你可以把它们想象成不同的“社交方式”,决定了你的虚拟机如何与外界(宿主机、其他虚拟机、互联网)打交道。
NAT(网络地址转换):这是VirtualBox默认的,也是最省心的模式。它给你的虚拟机分配一个私有IP(比如10.0.2.x),然后通过宿主机的网络接口去上网。你可以理解为,虚拟机住在一个有门卫(NAT设备)的小区里,它要收快递(访问外网),门卫会帮它代收;但外面的人想给虚拟机寄快递(从宿主机访问虚拟机),门卫不认识这个地址,快递就送不进来。所以,NAT模式单向出网的特性,非常适合只需要上网、不需要被主动访问的虚拟机。
桥接模式:这个模式相当于给你的虚拟机在宿主机的物理网络上“开了一个口子”,虚拟机会获得一个和宿主机同网段的真实IP地址。就像虚拟机搬出了独立小区,直接住进了你家的局域网,成为和你电脑平起平坐的一台“真实”设备。它既能上网,也能被局域网内其他设备(包括宿主机)直接访问。但问题来了,如果你的公司或学校网络有IP绑定或者严格的准入控制,桥接可能会遇到问题,而且它把虚拟机完全暴露在局域网里,安全性需要考虑。
内部网络:这个模式创建了一个完全封闭的虚拟网络,只有处于同一内部网络中的虚拟机之间可以互相通信,宿主机和外部网络都无法接入。它就像给几台虚拟机建了一个秘密会议室,专门用于内部集群测试,比如搭建一个Hadoop或者K8s的学习环境。
主机模式:这是我们今天的主角之一。VirtualBox会虚拟出一张虚拟网卡(比如叫VirtualBox Host-Only Ethernet Adapter)安装在你的宿主机上,并创建一个独立的私有网络(默认网段是192.168.56.x)。虚拟机如果连接到这个网络,就和宿主机上的这张虚拟网卡处于同一个局域网内。这样一来,宿主机和虚拟机就成了这个私有网络里的“邻居”,可以互相访问,但虚拟机无法通过这张网卡上外网。 它完美解决了“宿主机访问虚拟机”这个核心需求。
看到这里,你应该明白了。单一的NAT模式无法被宿主机访问,单一的桥接模式可能有环境限制,而单一的“主机模式”又上不了网。所以,“NAT + 主机模式”双网卡组合,就成了一个取长补短、灵活高效的黄金方案:NAT网卡负责连接广阔互联网,主机模式网卡负责构建稳固的本地通信通道。
3. 手把手配置VirtualBox双网卡
理论清楚了,我们开始实战。我假设你已经安装好了VirtualBox和Ubuntu 22.04的虚拟机。请先关闭你的Ubuntu虚拟机,因为我们要在“关机状态”下修改硬件设置。
3.1 第一步:检查并创建主机模式网络
首先,我们需要确保VirtualBox已经准备好了“主机模式”这张虚拟网卡。
- 打开VirtualBox,不要启动虚拟机,直接点击软件界面上方的 “管理” 菜单,选择 “主机网络管理器”。
- 在弹出的窗口里,你会看到已有的主机网络列表。通常,VirtualBox在安装时会自动创建一个,名字可能是
VirtualBox Host-Only Ethernet Adapter。如果列表是空的,别慌,点击右上角的 “创建” 按钮,一个新的虚拟网卡就会生成。 - 选中这个网络适配器,我们可以查看和修改它的属性。我建议保持默认设置即可,尤其是 IPv4地址 和 IPv4网络掩码。默认的地址通常是
192.168.56.1,掩码是255.255.255.0。这意味着这个私有网络的网段是192.168.56.0/24,宿主机自己占用了这个网段的第一个IP(.1)。我们后续给虚拟机分配的IP,比如192.168.56.101,就需要在这个网段内。
这个步骤就像是在你的电脑里虚拟出了一个迷你交换机,并给这个交换机(宿主机端)设置了一个管理IP。
3.2 第二步:为虚拟机添加两张网卡
现在,为我们已经创建好的Ubuntu 22.04虚拟机添加硬件。
- 在VirtualBox主界面,选中你的Ubuntu虚拟机,点击右侧的 “设置” 按钮。
- 进入设置窗口后,点击左侧的 “网络” 选项。你会看到“网卡1”默认是启用状态,并且连接方式可能是“NAT”。很好,我们保留它。
- 接下来,启用 “网卡2”。勾选“启用网络连接”前面的复选框。
- 在“连接方式”的下拉菜单中,选择 “仅主机(Host-Only)网络”。
- 在“界面名称”或“高级”下拉菜单中,选择我们刚才在主机网络管理器中看到或创建的那个适配器,比如
VirtualBox Host-Only Ethernet Adapter。 - 重要提示:留意一下“网卡1”和“网卡2”的“混杂模式”和“接入网线”是否都已勾选。通常保持默认的“拒绝”和勾选状态即可。
至此,虚拟机的硬件层面配置就完成了。你的虚拟机现在拥有了两块虚拟网卡:一块通过NAT连接外网,另一块通过主机模式与宿主机直连。你可以把这两块网卡想象成虚拟机主板上的两个网口,一个插了通往外网的路由器线,一个插了连接宿主机内部交换机的线。
4. 进入Ubuntu,搞定网络配置
启动你的Ubuntu 22.04虚拟机。系统启动后,我们需要在Ubuntu内部,告诉它这两块网卡分别该怎么工作。Ubuntu 22.04默认使用 netplan 来管理网络配置,这是一个用YAML语法写配置文件的工具,比以前的/etc/network/interfaces更现代、更清晰。
4.1 确认网卡设备名
首先,我们需要知道系统给那两块虚拟网卡分配了什么名字。打开终端,输入命令:
ip link show
或者用老命令:
ifconfig -a
你会看到类似 enp0s3、enp0s8、ens33 这样的名字。在VirtualBox的典型命名规则下,网卡1(NAT)通常对应 enp0s3,网卡2(主机模式)通常对应 enp0s8。请务必记下你的系统中对应的设备名,我们后面配置要用。
4.2 编写Netplan配置文件
Ubuntu的网络配置文件位于 /etc/netplan/ 目录下,里面通常有一个以 .yaml 结尾的文件,比如 01-network-manager-all.yaml。我们备份原文件后,编辑它。
在终端中输入:
sudo nano /etc/netplan/01-network-manager-all.yaml
如果你更喜欢用 vim,把 nano 替换掉就行。
接下来,我们将配置文件内容替换为以下配置。请务必将 enp0s3 和 enp0s8 替换成你上一步查到的实际网卡名!
network:
version: 2
renderer: NetworkManager
ethernets:
enp0s3: # 这是NAT网卡,用于上外网
dhcp4: true # 启用DHCP,自动从VirtualBox的NAT服务获取IP
optional: true # 设置为可选,避免系统启动时因网络未就绪而等待超时
enp0s8: # 这是主机模式网卡,用于与宿主机通信
dhcp4: no # 关闭DHCP,我们手动设置静态IP
dhcp6: no
addresses: [192.168.56.101/24] # 设置静态IP地址,需在主机模式网段内
# 可以添加路由,但本例中非必须,因为默认路由会通过NAT网卡出去
# routes:
# - to: 0.0.0.0/0
# via: 192.168.56.1
# metric: 100
nameservers:
addresses: [8.8.8.8, 1.1.1.1] # 设置DNS服务器,这里用了谷歌和Cloudflare的
让我解释一下这个配置的关键点:
- enp0s3 (NAT):我们使用
dhcp4: true,让VirtualBox内置的DHCP服务器自动给它分配IP(通常是10.0.2.15)和网关。这样它就能自动上网了。optional: true是个好习惯,避免系统启动时如果这张网卡没立刻拿到地址就卡住。 - enp0s8 (主机模式):我们设置一个静态IP
192.168.56.101。这个地址必须在宿主机虚拟网卡所在的网段(192.168.56.0/24)内,且不能和宿主机(.1)冲突。子网掩码/24对应255.255.255.0。我们没有为它设置默认网关(via),因为系统的默认路由(去往外网的路)应该交给NAT网卡。如果我们在这里也设置了网关指向192.168.56.1,可能会导致路由冲突,外网流量可能走错门。DNS服务器我们统一设置一下。
4.3 应用配置并测试
编辑保存配置文件后(在nano中是Ctrl+O保存,Ctrl+X退出),在终端执行命令让配置生效:
sudo netplan apply
这个命令会立即应用新的网络配置,通常不需要重启。
现在,开始我们的验收测试:
-
测试外网连接:
ping -c 4 baidu.com如果看到类似
64 bytes from ...的回复,恭喜你,NAT网卡工作正常,虚拟机可以上网了。 -
测试与宿主机的连接: 回到你的Windows宿主机,打开命令提示符(CMD),先看看宿主机的虚拟网卡IP:
ipconfig找到
VirtualBox Host-Only Ethernet Adapter,记下它的IPv4地址,大概率是192.168.56.1。 然后在Ubuntu虚拟机终端里,ping这个地址:ping -c 4 192.168.56.1如果能通,说明主机模式的通道建立成功了。
-
测试宿主机访问虚拟机: 在Windows宿主机的浏览器中,尝试访问
http://192.168.56.101:端口号(如果你在Ubuntu上启动了Web服务)。或者在CMD里ping 192.168.56.101。如果通,那么我们的核心目标——宿主机访问虚拟机服务——就完美实现了。 -
查看最终网络状态: 在Ubuntu终端里输入
ip addr show或ifconfig,你可以清晰地看到两张网卡都获得了正确的IP地址,各司其职。
5. 进阶技巧与排坑指南
配置基本成功,但实际使用中可能会遇到一些小问题。这里分享几个我踩过的坑和对应的解决办法。
5.1 路由优先级与策略路由
在双网卡环境下,Linux系统默认只有一个默认网关(default route)。通常,哪个网卡先获取到网关,或者最后执行netplan apply的配置中定义的网关,就会成为默认网关。在我们的配置里,NAT网卡(enp0s3)通过DHCP获得了网关(如10.0.2.2),而主机模式网卡(enp0s8)我们没有设置网关。你可以用 ip route show 命令查看,默认路由应该指向 10.0.2.2。
这通常没问题,因为所有去往互联网(0.0.0.0/0)的流量都会走NAT。去往 192.168.56.0/24 这个本地主机的流量,系统会根据更精确的路由规则(192.168.56.0/24 dev enp0s8)走主机模式网卡。
但是,如果你发现网络异常,比如宿主机能ping通虚拟机,但虚拟机ping不通宿主机以外的地址,可能是路由乱了。可以尝试在主机模式网卡配置中明确不设置网关,并确保NAT网卡的DHCP正常。
5.2 防火墙问题
有时候,网络通了,但服务访问不了,很可能是防火墙在“作祟”。
-
在Ubuntu虚拟机内:Ubuntu 22.04默认使用
ufw防火墙,可能是关闭状态。如果开启了,你需要放行相应端口。例如,放行80端口:sudo ufw allow 80/tcp或者,如果你是做测试,可以暂时关闭防火墙(生产环境不推荐):
sudo ufw disable -
在Windows宿主机:同样,检查Windows Defender防火墙是否阻止了入站连接。你可以暂时关闭防火墙测试,或者针对VirtualBox的虚拟网卡创建入站规则。
5.3 服务绑定地址
你在Ubuntu上运行的服务(比如Nginx、Python的http.server、数据库),需要注意它的监听地址。如果服务绑定在 127.0.0.1(localhost),那么只有虚拟机自己能访问。为了让宿主机能访问,服务需要绑定在 0.0.0.0 或者虚拟机的具体IP(如 192.168.56.101)上。
例如,用Python启动一个简单的HTTP服务器:
# 只在本地访问
python3 -m http.server 8000
# 允许所有网络接口访问(包括宿主机)
python3 -m http.server 8000 --bind 0.0.0.0
5.4 网卡顺序与设备名变化
如果你在VirtualBox设置里调整了网卡的顺序(比如把主机模式网卡设为“网卡1”),或者以后添加了更多网卡,Ubuntu系统内的设备名(enp0s3, enp0s8)可能会发生变化。这时,你需要用 ip link show 重新确认设备名,并更新 /etc/netplan/ 下的配置文件。
一个更稳健的方法是使用网卡的MAC地址来匹配配置。在VirtualBox的网络设置里可以看到每个网卡的MAC地址,然后在netplan配置中使用 match: 和 macaddress: 来指定,这样即使设备名变了,配置也能正确应用。
6. 双网卡方案的典型应用场景
搞定了配置,我们来看看这个“双网卡”方案能用在哪些地方,这能帮你更好地理解它的价值。
场景一:本地全栈开发与调试
这是最经典的场景。你在虚拟机里运行后端API服务(比如Spring Boot、Django),在宿主机上用IDE写前端代码。通过主机模式网卡,宿主机浏览器可以直接访问 http://192.168.56.101:8080 来调用后端接口,实现前后端联调。同时,虚拟机可以自由地通过NAT网卡访问互联网,下载Maven包、npm包或者Docker镜像,两不耽误。
场景二:搭建隔离的微服务学习环境 你想学习Kubernetes或Docker Compose,在虚拟机里搭建了一个多节点的迷你集群。主机模式网络为集群内部提供了稳定、高速的通信通道,宿主机则可以通过固定的IP访问到集群的Dashboard(如K8s的Dashboard)或者某个服务的NodePort,方便监控和管理。而NAT网络则让集群内的容器能够拉取外部镜像。
场景三:安全测试与网络实验 你需要一个既能连接互联网获取工具和更新,又能从宿主机进行精细控制和监控的测试环境。双网卡提供了完美的隔离:测试流量通过主机模式在可控范围内进行,而普通上网行为则通过NAT完成。
配置完成后,我自己的体验是,整个世界都清净了。开发时再也不用在桥接模式的各种网络问题里折腾,也不用忍受端口转发带来的麻烦。这个方案把两种网络模式的优点结合得恰到好处,几乎成了我在VirtualBox中配置Ubuntu虚拟机的标准动作。如果你在后续使用中遇到任何问题,回头检查一下这几个关键点:网卡设备名对不对、IP地址是否在同一网段、防火墙有没有阻拦、服务监听地址是否正确。多动手试几次,这些概念就会变得非常直观。
268



被折叠的 条评论
为什么被折叠?



