1. 问题背景与场景分析
在嵌入式Linux开发过程中,NFS(Network File System)挂载根文件系统是常见的开发调试方式。但很多开发者会遇到一个典型困境:当开发板通过NFS挂载Ubuntu虚拟机的根文件系统时,如果虚拟机使用NAT模式网络,虽然可以访问外网,却无法与开发板通信;而切换到桥接模式后,虽然能与开发板通信,但又失去了外网连接能力。
这个问题本质上源于网络拓扑冲突。NAT模式下虚拟机通过宿主机进行地址转换访问外网,而桥接模式下虚拟机与开发板处于同一局域网。当两者IP段重叠时(如都是192.168.81.0/24),系统路由表会出现混乱,导致无法同时满足两个需求。
2. 双网卡方案设计原理
2.1 网络架构设计
解决这个问题的核心思路是:为Ubuntu虚拟机配置双网卡,分别采用不同网络模式:
-
网卡1(ens33):桥接模式(Bridged)
- 直接连接到物理网络
- 与开发板处于同一局域网(如192.168.81.0/24)
- 负责NFS文件共享和开发板通信
-
网卡2(ens37):NAT模式
- 使用VMnet8虚拟网络(如192.168.100.0/24)
- 通过宿主机进行地址转换
- 专用于外网访问
2.2 关键配置要点
必须确保两个网卡处于不同IP段。常见错误是NAT网卡(VMnet8)与桥接网络使用相同网段(如都是192.168.81.0/24),这会导致:
- 路由表无法正确选择出口
- ARP请求响应混乱
- 数据包可能被错误网卡处理
重要提示:如果发现VMnet8默认使用192.168.81.0/24网段,必须修改其子网地址(如改为192.168.100.0/24),否则双网卡无法正常工作。
3. 详细配置步骤
3.1 虚拟机网络设置
-
关闭Ubuntu虚拟机
- 在VMware中完全关闭虚拟机电源(非挂起状态)
-
添加第二块网卡
- VMware菜单 → 虚拟机 → 设置 → 添加 → 网络适配器 → 完成
- 默认会添加名为"网络适配器2"的新网卡
-
配置网卡模式
- 网络适配器1:桥接模式(勾选"复制物理网络连接状态")
- 网络适配器2:NAT模式(使用VMnet8)
3.2 修改NAT网络配置
-
打开VMware虚拟网络编辑器
- VMware菜单 → 编辑 → 虚拟网络编辑器
- 需要管理员权限,点击"更改设置"
-
修改VMnet8参数
- 选择VMnet8 → NAT模式
- 修改子网IP为不冲突的网段(如192.168.100.0)
- 子网掩码保持255.255.255.0
-
配置NAT网关
- 点击"NAT设置"
- 修改网关IP为同网段地址(如192.168.100.2)
- 确认端口转发规则为空
-
调整DHCP范围
- 点击"DHCP设置"
- 起始IP设为192.168.100.128
- 结束IP设为192.168.100.254
- 租用时间保持默认
3.3 Ubuntu网络配置
-
启动虚拟机并检查网卡
bash复制ip link show应看到两个网络接口(通常ens33和ens37)
-
释放并更新IP配置
bash复制sudo dhclient -r ens33 # 释放原有IP sudo dhclient ens33 # 重新获取IP sudo dhclient -r ens37 sudo dhclient ens37 -
验证IP分配
bash复制
ip addr show- ens33应获取桥接网络的IP(如192.168.81.x)
- ens37应获取NAT网络的IP(如192.168.100.x)
4. 路由表优化配置
4.1 查看当前路由
bash复制ip route show
典型输出示例:
code复制default via 192.168.81.1 dev ens33 proto dhcp metric 100
192.168.81.0/24 dev ens33 proto kernel scope link src 192.168.81.130
192.168.100.0/24 dev ens37 proto kernel scope link src 192.168.100.128
4.2 添加永久路由规则
为避免重启后配置丢失,需编辑网络配置文件:
bash复制sudo nano /etc/netplan/01-netcfg.yaml
添加如下内容(根据实际接口名调整):
yaml复制network:
version: 2
renderer: networkd
ethernets:
ens33:
dhcp4: yes
routes:
- to: 0.0.0.0/0
via: 192.168.81.1
metric: 100
ens37:
dhcp4: yes
routes:
- to: 0.0.0.0/0
via: 192.168.100.2
metric: 200
应用配置:
bash复制sudo netplan apply
5. NFS服务配置与测试
5.1 安装NFS服务器
bash复制sudo apt update
sudo apt install nfs-kernel-server
5.2 配置共享目录
编辑exports文件:
bash复制sudo nano /etc/exports
添加如下行(根据实际路径调整):
code复制/home/yourname/nfs_root *(rw,sync,no_root_squash,no_subtree_check)
5.3 重启NFS服务
bash复制sudo systemctl restart nfs-kernel-server
sudo exportfs -av
5.4 开发板挂载测试
在开发板U-Boot或Linux命令行中:
bash复制mount -t nfs 192.168.81.130:/home/yourname/nfs_root /mnt -o nolock
成功挂载后应能访问共享文件。
6. 常见问题与解决方案
6.1 网络接口不显示
现象:执行ip link show看不到ens37接口
排查:
- 检查虚拟机设置确认已添加第二网卡
- 查看内核日志:
bash复制
dmesg | grep -i eth - 可能需要手动加载驱动:
bash复制sudo modprobe e1000
6.2 NAT网络无法上网
现象:ens37获取到IP但ping不通外网
解决步骤:
- 检查VMnet8的NAT网关设置
- 验证宿主机防火墙是否放行
- 测试基础连接:
bash复制ping 192.168.100.2 # NAT网关 ping 8.8.8.8 # 测试外网
6.3 NFS挂载失败
典型错误:Connection timed out
排查方法:
- 确认开发板与Ubuntu桥接IP互通
- 检查NFS服务状态:
bash复制sudo systemctl status nfs-kernel-server - 验证端口开放:
bash复制sudo rpcinfo -p
6.4 路由冲突问题
现象:部分网络请求走错接口
解决方案:
- 添加策略路由:
bash复制
ip rule add from 192.168.81.0/24 table 100 ip route add default via 192.168.81.1 dev ens33 table 100 - 或使用更精确的路由规则
7. 性能优化建议
-
MTU调整:对于大文件传输,可尝试增大MTU
bash复制sudo ip link set ens33 mtu 9000 -
NFS版本选择:建议使用NFSv4,性能更好且更安全
bash复制
mount -t nfs4 192.168.81.130:/path /mnt -
网络绑定:对于高性能需求,可考虑bonding模式
yaml复制# /etc/netplan/01-netcfg.yaml bonds: bond0: interfaces: [ens33, ens37] addresses: [192.168.81.150/24] routes: - to: 0.0.0.0/0 via: 192.168.81.1 parameters: mode: active-backup
在实际开发中,我发现保持桥接网络与开发板静态IP能提高稳定性。例如将Ubuntu的ens33设为192.168.81.100,开发板设为192.168.81.101,避免DHCP租约变化带来的中断。同时,定期检查路由表(ip route show)可以及时发现异常路由条目。