1. 为什么要在虚拟机里折腾双网卡
把一台最小化安装的 CentOS 7 跑在 VirtualBox 里,是很多人搭本地实验环境、跑中间件、练运维命令的常规操作。但真到联网这一步,不少人会卡住:默认的 NAT 模式确实能让虚拟机访问外网,可宿主机想反过来连虚拟机就费劲了;换成桥接模式吧,又受限于当前网络环境,换个地方 IP 就变,甚至根本拿不到地址。折腾几轮之后,比较稳妥的方案就浮出水面——NAT 加 Host-Only 双网卡。
这套组合的逻辑其实很直白。NAT 网卡负责“出去”,让虚拟机可以访问外部网络、下载软件包、同步时间;Host-Only 网卡负责“进来”,给宿主机和虚拟机之间拉一条专属的内部通道,SSH、Web 服务、数据库连接都走这条路。两块网卡各司其职,互不干扰,虚拟机 IP 还相对固定,不用每次换环境都重新配一遍。
我前后在好几台机器上重复过这套配置,也踩了不少坑。有些坑是 VirtualBox 版本差异带来的,有些是 CentOS 7 网络管理器自身的脾气,还有些纯粹是自己想当然导致的。这篇就把整个配置过程、背后的原理、以及那些文档里不会写的细节,完整梳理一遍。不管你是刚接触虚拟机的新手,还是配过几次但总有小毛病的老手,应该都能从中找到点有用的东西。
2. 双网卡方案的整体设计与选型考量
2.1 NAT 与 Host-Only 各自扮演什么角色
先把这个方案的核心思路讲透。VirtualBox 提供的网络模式有好几种,每种都有自己的适用场景,选错了后面全是麻烦。
NAT 模式的本质,是 VirtualBox 在宿主机上跑了一个虚拟的 NAT 设备。虚拟机发出的数据包,源地址被替换成宿主机的地址发出去,回来的包再还原给虚拟机。对虚拟机来说,它以为自己在一个能上网的局域网里;对外部网络来说,流量看起来是从宿主机发出的。这个模式最大的好处是零配置就能上网,宿主机在什么网络环境下都不影响,咖啡馆、家里、公司都能用。代价是外部网络无法主动连进来,因为虚拟机藏在 NAT 后面,没有独立的外部可达地址。
Host-Only 模式则是在宿主机上创建一块虚拟网卡,所有用这个模式的虚拟机都和宿主机连在这块虚拟网卡构成的内部网络上。这个网络完全封闭在宿主机内部,不和外部网络发生关系。它的价值在于宿主机和虚拟机之间可以双向通信,而且 IP 段由我们自己掌控,稳定可控。
把两者结合,就得到了一个很舒服的状态:虚拟机通过 NAT 上网,通过 Host-Only 被宿主机访问。我平时用 SSH 连虚拟机、在宿主机浏览器里打开虚拟机跑的 Web 服务、用数据库客户端连虚拟机里的库,走的全是 Host-Only 这条线。而虚拟机内部执行软件包安装、拉取依赖,走的是 NAT。
2.2 为什么不用桥接模式替代
有人会问,桥接模式不是也能让宿主机访问虚拟机吗,为什么还要搞两块网卡这么麻烦。
桥接模式确实能让虚拟机直接接入宿主机所在的物理网络,拿到一个和宿主机同网段的地址,双向通信都没问题。但它有几个现实问题。第一,依赖当前网络环境,如果所在网络对未知设备有限制,或者 IP 地址是动态分配且数量有限,虚拟机可能拿不到地址。第二,IP 会变,换一个网络环境,虚拟机地址就变了,之前配好的 SSH 配置、服务地址全得改。第三,暴露在局域网中,虚拟机上的服务对整个局域网可见,做实验时不太希望这样。
Host-Only 就没有这些顾虑。它的网段是我们自己定的,比如 192.168.56.0/24,虚拟机地址固定,不管宿主机换到哪个网络,这条内部通道始终存在。所以 NAT 加 Host-Only 的组合,本质上是拿 NAT 解决“出网”,拿 Host-Only 解决“稳定可控的内部通信”,比单纯桥接更灵活。
2.3 网卡顺序与地址规划
这里有个容易被忽略的细节:网卡顺序会影响默认路由。VirtualBox 里网卡 1、网卡 2 的编号是有意义的。通常的做法是:
- 网卡 1 设为 NAT,负责出网
- 网卡 2 设为 Host-Only,负责内部通信
这样 CentOS 启动后,默认路由会指向 NAT 网卡对应的网关,出网正常。如果反过来,把 Host-Only 放网卡 1,可能会出现默认路由指向 Host-Only 网关的情况,导致上不了网。当然这个也可以通过手动调整路由表解决,但一开始就按合理顺序配置,能省掉很多麻烦。
地址规划上,Host-Only 网段建议避开常见的家庭和公司网段,比如 192.168.56.0/24 就是 VirtualBox 默认的 Host-Only 网段,用这个就行。虚拟机 Host-Only 网卡给个固定地址,比如 192.168.56.101,宿主机那块虚拟网卡通常是 192.168.56.1。这样两边就在同一个网段里,直接通信。
3. VirtualBox 侧的配置细节与实操
3.1 创建 Host-Only 虚拟网卡
在 VirtualBox 里配置 Host-Only 网络,入口在“管理”菜单下的“主机网络管理器”。打开之后,如果之前没建过,列表里可能是空的,点“创建”就会生成一块虚拟网卡。
这里有几个参数需要留意。IPv4 地址默认是 192.168.56.1,子网掩码255.255.255.0。这个地址就是宿主机在这块虚拟网卡上的地址,后面虚拟机要和它通信,就得配在同一网段。DHCP 服务器那一栏,默认可能是启用的,但我建议关掉。原因很简单,我们要给虚拟机配固定 IP,DHCP 开着反而可能造成地址冲突或者拿到非预期的地址。关掉 DHCP,手动分配,一切尽在掌握。
注意:如果宿主机上已经存在其他虚拟化软件创建的虚拟网卡,网段可能冲突。创建前先确认 192.168.56.0/24 这个段没被占用,有冲突就换一个,比如 192.168.100.0/24。
创建完成后,在宿主机的网络连接列表里应该能多出一块虚拟网卡。Windows 下通常叫“VirtualBox Host-Only Network”,Linux 或 macOS 下名字类似。这块网卡的状态不影响宿主机正常上网,它只负责内部通信。
3.2 给虚拟机挂上两块网卡
选中虚拟机,进“设置”,找到“网络”选项卡。这里有四个网卡槽位,我们只用前两个。
网卡 1:勾选“启用网络连接”,连接方式选“NAT 网络”。界面名称那一栏,如果下拉里有默认的 NAT 网络就选它,没有的话保持默认也行。高级选项里,适配器类型建议选Intel PRO/1000 MT Desktop,这个兼容性最好,CentOS 7 自带驱动,不用额外装。混杂模式保持“拒绝”,接入网线那个勾保持勾上。
网卡 2:同样勾选启用,连接方式选“仅主机(Host-Only)网络”。界面名称选刚才创建的那块虚拟网卡。适配器类型同样选 Intel PRO/1000 MT Desktop。高级里的其他选项默认即可。
配置完点确定。这时候虚拟机的硬件层面就有两块网卡了,但 CentOS 里面还没认全,需要进去配置。
3.3 网卡顺序对默认路由的影响
前面提过网卡顺序的事,这里再展开说一下为什么重要。
CentOS 7 启动时,网络管理器会根据网卡发现的顺序和配置,决定默认路由走哪块网卡。如果 NAT 在网卡 1,Host-Only 在网卡 2,通常默认路由会正确指向 NAT 的网关。但如果顺序反了,可能出现默认路由指向 Host-Only 网关的情况,而 Host-Only 网络是不通外网的,结果就是虚拟机 ping 不通外网地址。
判断方法很简单,进系统后执行ip route看 default 那一行指向哪个网关。如果指向的是 Host-Only 网段的网关,就需要手动调整。调整方式有两种:一是回到 VirtualBox 设置里把网卡顺序换过来;二是在 CentOS 里改路由配置,把默认路由指到 NAT 网卡。前者更省事,推荐优先用前者。
4. CentOS 7 内部的网络配置全流程
4.1 确认网卡名称与状态
CentOS 7 默认使用一致性网络设备命名,网卡名不一定是 eth0、eth1,可能是 enp0s3、enp0s8 这种形式。进系统后先执行:
ip addr或者
nmcli device status看当前识别到了几块网卡,名字分别是什么。通常第一块是 NAT 对应的,第二块是 Host-Only 对应的。如果只看到一块,说明另一块没被识别,可能是 VirtualBox 里没启用,或者适配器类型不兼容。
也可以用ls /etc/sysconfig/network-scripts/看配置文件,里面 ifcfg- 开头的文件对应各块网卡。新装的最小化系统,可能只有一块网卡的配置文件,另一块需要手动创建。
4.2 配置 NAT 网卡走 DHCP
NAT 网卡这块,最省事的做法是让它通过 DHCP 自动获取地址。VirtualBox 的 NAT 网络内置了 DHCP 服务,虚拟机会自动拿到一个 10.0.2.x 段的地址,网关是 10.0.2.2,DNS 也是 10.0.2.3。这些都不用我们操心。
对应的配置文件大概是这样的:
TYPE=Ethernet BOOTPROTO=dhcp DEFROUTE=yes NAME=enp0s3 DEVICE=enp0s3 ONBOOT=yes关键就是BOOTPROTO=dhcp和ONBOOT=yes。DEFROUTE=yes表示允许这块网卡承载默认路由,NAT 网卡需要这个。
改完配置文件后,重启网络服务:
systemctl restart network然后ip addr看这块网卡有没有拿到 10.0.2.x 的地址。拿到了就说明 NAT 这块通了。
4.3 给 Host-Only 网卡配静态地址
Host-Only 网卡要配静态地址,这样每次启动地址都一样,SSH 配置不用改。假设我们规划虚拟机地址为 192.168.56.101,配置文件这样写:
TYPE=Ethernet BOOTPROTO=static DEFROUTE=no NAME=enp0s8 DEVICE=enp0s8 ONBOOT=yes IPADDR=192.168.56.101 NETMASK=255.255.255.0这里有几个点要特别注意。DEFROUTE=no很关键,表示这块网卡不承载默认路由,默认路由还是走 NAT 那块。如果不写或者写成 yes,可能导致默认路由被抢到 Host-Only 这边,结果上不了网。不配 GATEWAY,Host-Only 网络不需要网关,配了反而可能出问题。不配 DNS,DNS 走 NAT 那边就行。
如果这块网卡的配置文件不存在,就手动创建一个,文件名对应网卡名,比如ifcfg-enp0s8。创建后同样重启网络服务。
4.4 重启网络服务与验证连通性
配置改完后,执行:
systemctl restart network然后依次验证几件事。
第一,看两块网卡地址是否都正确:
ip addrNAT 网卡应该有 10.0.2.x 的地址,Host-Only 网卡应该有 192.168.56.101。
第二,看路由表:
ip routedefault 那一行应该指向 10.0.2.2,也就是 NAT 的网关。192.168.56.0/24 那一行应该指向 Host-Only 网卡。
第三,测试外网连通性:
ping -c 4 223.5.5.5能通说明 NAT 出网正常。
第四,在宿主机上测试连虚拟机:
ping 192.168.56.101能通说明 Host-Only 通道正常。如果宿主机 ping 不通,先检查宿主机那块虚拟网卡是不是启用了,地址是不是 192.168.56.1。
5. 那些年我踩过的坑与排查实录
5.1 网卡配置文件缺失或名字不对
最小化安装的 CentOS 7,有时候只生成了一块网卡的配置文件。第二块网卡虽然在系统里能看到,但没有对应的 ifcfg 文件,网络服务自然管不到它。这时候需要手动创建配置文件,文件名必须和网卡名严格对应,比如网卡叫 enp0s8,文件就得叫ifcfg-enp0s8,放在/etc/sysconfig/network-scripts/下。
还有一种情况是网卡名和预期不一致。比如 VirtualBox 里换了适配器类型,网卡名可能从 enp0s3 变成 eth0 之类。这时候要么改配置文件里的 DEVICE 和 NAME 去匹配实际网卡名,要么用 udev 规则把名字固定下来。我一般选择前者,简单直接。
5.2 默认路由跑偏导致上不了网
这是最常见的问题之一。表现是 Host-Only 能通,但外网 ping 不通。进系统ip route一看,default 指向了 192.168.56.1 而不是 10.0.2.2。
原因通常是 Host-Only 网卡的配置文件里DEFROUTE没设成 no,或者两块网卡的启动顺序导致 Host-Only 先拿到默认路由。解决办法就是确保 NAT 网卡DEFROUTE=yes,Host-Only 网卡DEFROUTE=no,然后重启网络服务。如果还不行,可以手动删掉错误的默认路由再加正确的:
ip route del default via 192.168.56.1 ip route add default via 10.0.2.2但这只是临时生效,重启就没了,根本解决还是改配置文件。
5.3 NetworkManager 与 network 服务的冲突
CentOS 7 里有两套网络管理机制:传统的 network 服务和 NetworkManager。默认情况下 NetworkManager 是启用的,它也会去管网卡配置。有时候用systemctl restart network重启后配置没生效,就是因为 NetworkManager 在中间插了一脚。
我的做法是,如果习惯用 network 服务管理,就把 NetworkManager 停掉并禁用:
systemctl stop NetworkManager systemctl disable NetworkManager systemctl enable network systemctl start network这样网络配置就完全由 network 服务接管,行为可预期。当然如果你习惯用 nmcli 管理,那就反过来,但两种方式不要混用,容易出怪问题。
5.4 宿主机 ping 不通虚拟机的排查思路
宿主机 ping 不通虚拟机,按下面这个顺序排查,基本能定位到问题。
| 排查项 | 检查方法 | 常见问题 |
|---|---|---|
| 虚拟机网卡是否启用 | ip addr看 Host-Only 网卡有无地址 | 配置文件没写 ONBOOT=yes |
| 虚拟机防火墙 | systemctl status firewalld | 防火墙拦截了 ICMP |
| 宿主机虚拟网卡 | 宿主机网络连接里看状态 | 网卡被禁用或地址不对 |
| 网段是否一致 | 对比两边地址和掩码 | 配到了不同网段 |
| VirtualBox 设置 | 看网卡 2 是否启用 Host-Only | 忘了勾选启用 |
防火墙这块特别容易忽略。CentOS 7 默认 firewalld 是开着的,虽然它默认放行 ICMP,但如果你之前改过规则,可能就被拦了。临时关掉测试一下:
systemctl stop firewalld如果关掉就能通,说明是防火墙问题,再去细调规则。
5.5 虚拟机克隆后网络异常
用 VirtualBox 的克隆功能复制虚拟机后,新虚拟机可能网络不正常。原因是克隆出来的虚拟机网卡 MAC 地址变了,但 CentOS 里的网卡配置文件还绑着旧的 MAC,或者 udev 规则里记着旧网卡。表现就是网卡起不来,或者名字变成了 enp0s8_1 这种。
解决办法是进系统后检查/etc/sysconfig/network-scripts/下的配置文件,把HWADDR那一行删掉或者改成新 MAC。同时检查/etc/udev/rules.d/下有没有 70-persistent-net.rules 之类的文件,有的话删掉,重启让系统重新生成。克隆前先把这些清理掉,克隆后能省不少事。
6. 日常使用中的经验与优化建议
6.1 用 SSH 配置简化连接
Host-Only 通道建好后,日常操作基本都可以通过 SSH 完成,不用在 VirtualBox 窗口里敲命令。在宿主机的~/.ssh/config里加一段:
Host centos-dev HostName 192.168.56.101 User youruser Port 22之后直接ssh centos-dev就能连上。如果配了密钥登录,连密码都不用输。这样用起来和连一台远程服务器没区别,体验好很多。
6.2 共享文件夹作为补充
有时候需要在宿主机和虚拟机之间传文件。除了用 scp 走 Host-Only 通道,还可以用 VirtualBox 的共享文件夹功能。在虚拟机设置里添加共享文件夹,然后在 CentOS 里挂载。不过共享文件夹需要装增强功能包,最小化安装的系统可能缺一些依赖,装起来略麻烦。我一般直接用 scp,简单可靠,不依赖额外组件。
6.3 快照与配置备份
网络配置调通之后,建议打个快照。VirtualBox 的快照功能可以保存当前虚拟机状态,后面折腾坏了随时回滚。另外把/etc/sysconfig/network-scripts/下的配置文件备份一份,换机器或者重装时直接拷过去改改就能用。
6.4 关于 DNS 的一个小细节
NAT 网卡通过 DHCP 拿到的 DNS 是 10.0.2.3,这个地址是 VirtualBox 内置的 DNS 转发器,它会把请求转发给宿主机的 DNS。一般情况下没问题,但如果宿主机 DNS 本身有问题,虚拟机里域名解析就会失败。这时候可以手动在 NAT 网卡的配置文件里加DNS1=223.5.5.5之类的公共 DNS,绕过 VirtualBox 的转发。不过要注意,这个 DNS 只在 NAT 网卡上配,Host-Only 网卡不要配 DNS。
6.5 性能与资源的小调整
双网卡对性能影响微乎其微,但如果虚拟机里跑的服务多,可以适当调整 VirtualBox 的网络高级设置。比如把适配器类型从 Intel PRO/1000 换成 virtio-net,性能会更好,但需要 CentOS 里有 virtio 驱动。最小化安装的 CentOS 7 一般自带 virtio 驱动,可以试试。不过如果遇到识别问题,换回 Intel PRO/1000 最稳妥。
我个人在实际操作中的体会是,这套 NAT 加 Host-Only 的方案一旦配通,后续使用非常省心。虚拟机地址固定,宿主机随时能连,出网也不受影响。真正花时间的往往是第一次配置时的各种小坑,把上面这些细节都注意到,基本能一次搞定。后面再建新虚拟机,照着这个流程走,十分钟就能配好一套可用的环境。