无法开启OVS的情况下使用原生Linux Bridge网络实现创建虚拟机
Linux Bridge 与 Open vSwitch (OVS) 对比
基本概念
| 维度 | Linux Bridge | Open vSwitch (OVS) |
|---|---|---|
| 本质 | Linux 内核原生提供的二层网络设备(虚拟交换机) | 一个开源的、支持 SDN 的多层虚拟交换机软件 |
| 诞生背景 | 随 Linux 内核一同发展,是内核网络栈的一部分 | 由 Nicira Networks 开发(后被 VMware 收购),用于云计算场景 |
| 定位 | 简单、稳定、内核原生 | 功能丰富、可编程、跨平台 |
功能对比
| 功能特性 | Linux Bridge | Open vSwitch (OVS) |
|---|---|---|
| 二层转发(MAC 学习) | ✅ 原生支持 | ✅ 支持 |
| VLAN 隔离 | ⚠️ 基础支持(需通过子接口配置) | ✅ 原生支持(802.1Q) |
| 链路聚合 (LAG) | ❌ 不支持 | ✅ 支持 |
| QoS / 流量限速 | ❌ 需借助 tc 命令手动配置 | ✅ 原生支持,粒度精细 |
| OpenFlow / SDN | ❌ 不支持 | ✅ 核心功能,完全支持 |
| VXLAN / GRE 隧道 | ❌ 不支持 | ✅ 原生支持 |
| 流表 (Flow Table) | ❌ 不支持 | ✅ 支持,可编程流量控制 |
| 流量监控 / sFlow | ❌ 不内置 | ✅ 原生支持 |
| STP / RSTP | ✅ 支持 | ✅ 支持 |
| NetFlow / IPFIX | ❌ 不内置 | ✅ 原生支持 |
| Bonding 端口绑定 | ❌ 需额外配置 | ✅ 原生支持 |
优缺点分析
Linux Bridge 优点
- 内核原生:与 Linux 网络栈深度集成,无需额外安装,零依赖
- 极简稳定:代码量少、逻辑简单,经过数十年验证,几乎不会出错
- 零学习成本:使用方式与物理交换机逻辑一致,即配即用
- 性能优秀:数据包直接由内核处理,无用户态/内核态切换开销
- KVM 默认首选:libvirt 默认网络后端,生态兼容性最好
- 资源开销极低:几乎不占用额外 CPU/内存
Linux Bridge 缺点
- 功能单一:仅提供基础的二层交换能力
- 无 SDN 支持:无法通过 OpenFlow 等协议进行集中式网络编排
- 网络隔离能力弱:跨主机 Overlay 网络(VXLAN/GRE)需外部方案
- 运维监控不便:没有内置的流量统计、可视化面板
- QoS 配置繁琐:限速、流量整形需借助 tc 命令,配置复杂
Open vSwitch 优点
- 功能全面:VLAN、VXLAN/GRE 隧道、QoS、LAG 等高级特性一应俱全
- SDN 就绪:完整支持 OpenFlow 协议,可对接 SDN 控制器实现集中管理
- 精细化流量控制:通过流表(Flow Table)实现颗粒度极高的转发策略
- 丰富的可观测性:内置 sFlow、NetFlow、IPFIX 等监控协议支持
- 多平台支持:不仅支持 Linux,还支持 ESXi、Hyper-V、KVM 等虚拟化平台
- 热迁移友好:支持网络状态迁移,VM 迁移时网络连接不中断
Open vSwitch 缺点
- 部署复杂:需要额外安装 ovs 内核模块和用户态组件
- 稳定性欠佳:历史上出现过 kernel panic、ovs-switched 段错误、广播风暴等问题
- 性能损耗:部分数据路径需经过用户态处理,相较内核原生 bridge 有一定性能开销
- 故障排查困难:流表规则链较长时,定位网络问题比较困难
- 学习曲线陡峭:ovs-vsctl、ovs-ofctl 等工具链需要专门学习
- 资源占用高:需要额外的内存和 CPU 来运行 ovs-vswitchd 守护进程
选型建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 家庭/小型实验室 | Linux Bridge | 简单够用、零运维成本 |
| 生产环境的 KVM 虚拟化 | Linux Bridge | 稳定第一,功能足够 |
| 嵌套虚拟化测试 | Linux Bridge | 降低复杂度,避免 OVS 潜在问题 |
| 大型云计算平台(OpenStack) | OVS | 需要 SDN 编排和多租户网络隔离 |
| SDN 研究与开发 | OVS | OpenFlow 是刚需 |
| 跨主机 Overlay 网络 | OVS | VXLAN/GRE 隧道原生支持 |
| 需要精细化 QoS/流量控制 | OVS | QoS 配置灵活且易管理 |
本文档记录了在飞牛NAS(Debian 12)上通过 Linux Bridge 将虚拟机网络桥接到宿主机物理网卡的操作流程,使得嵌套 VM 能够直接获取宿主机所在局域网 IP 地址,实现与局域网内其他设备的无障碍通信。
适用场景
- 在飞牛NAS(KVM/QEMU)中创建嵌套 VM,需要 VM 直接接入宿主机局域网
- 需要嵌套 VM 拥有独立的局域网 IP(非 NAT 转换)
- 需要嵌套 VM 对外提供网络服务
架构示意图
宿主机网卡 (enp1s0)
│
▼
Linux Bridge (br0) ← 192.168.10.27/24
│
├── 宿主机自身网络通信
└── libvirt 桥接网络 (br0-network)
│
└── 嵌套 VM 网卡 (virtio)
一、Linux Bridge 桥接创建
1.1 准备工作
确认当前环境中的网络管理工具:
# 查看网络设备
ip a
# 查看当前使用的网络管理器
dpkg -l | grep -E "bridge-utils|network-manager|systemd-networkd"
# 查看已有 bridge
brctl show
1.2 通过 NetworkManager 创建桥接
# 创建 bridge 接口 br0
sudo nmcli con add type bridge ifname br0 con-name bridge-br0
# 配置 br0 的 IP 地址(原网卡 IP)
sudo nmcli con mod bridge-br0 ipv4.addresses 192.168.10.27/24
# 配置网关
sudo nmcli con mod bridge-br0 ipv4.gateway 192.168.10.1
# 配置 DNS
sudo nmcli con mod bridge-br0 ipv4.dns "222.88.88.88 222.85.85.85"
# 设置为手动 IP 模式
sudo nmcli con mod bridge-br0 ipv4.method manual
# 将物理网卡 enp1s0 作为从端口添加到 bridge
sudo nmcli con add type ethernet slave-type bridge con-name bridge-port-br0 ifname enp1s0 master br0
1.3 切换激活桥接
# 禁用原有线连接(防止自动重连冲突)
sudo nmcli con mod "Wired connection 1" connection.autoconnect no
# 激活桥接
sudo nmcli con up bridge-br0
# 激活桥接端口
sudo nmcli con up bridge-port-br0
# 删除旧连接(可选,确认桥接正常运行后执行)
sudo nmcli con delete "Wired connection 1"
1.4 验证桥接
# 查看桥接状态 - 确认 enp1s0 在 br0 下
brctl show
# 预期输出示例:
# bridge name bridge id STP enabled interfaces
# br0 8000.025ce85dd21f yes enp1s0
# 查看 IP 地址 - 确认 IP 已迁移到 br0
ip -4 addr show br0
# 测试网关连通性
ping -c 3 192.168.10.1
# 测试外网连通性
ping -c 3 8.8.8.8
# 测试 DNS 解析
nslookup baidu.com
二、libvirt 桥接网络配置
2.1 创建 libvirt 桥接网络
创建一个 XML 配置文件,定义桥接网络:
cat > /tmp/br0-network.xml << 'EOF'
<network>
<name>br0-network</name>
<forward mode="bridge"/>
<bridge name="br0"/>
</network>
EOF
注意:
forward mode='bridge'表示直接桥接到已有的 Linux bridge,这是嵌套 VM 获取局域网 IP 的关键。
2.2 定义并启动网络
# 定义网络
sudo virsh net-define /tmp/br0-network.xml
# 启动网络
sudo virsh net-start br0-network
# 设为自动启动
sudo virsh net-autostart br0-network
# 查看网络列表
sudo virsh net-list --all
三、为虚拟机添加网卡
3.1 查看现有虚拟机
sudo virsh list --all
3.2 查看虚拟机配置
sudo virsh dumpxml <虚拟机名称>
3.3 添加网卡(推荐方式)
sudo virsh attach-interface <虚拟机名称> \
--type network \
--source br0-network \
--model virtio \
--persistent \
--config
参数说明:
| 参数 | 说明 |
|---|---|
--type network | 网络类型为 libvirt 网络 |
--source br0-network | 连接到 br0-network |
--model virtio | 使用 VirtIO 半虚拟化网卡(性能最佳) |
--persistent | 配置持久化(重启后保留) |
--config | 修改离线配置(VM 关机时使用) |
3.4 验证网卡
# 查看虚拟机的网络接口
sudo virsh domiflist <虚拟机名称>
# 预期输出示例:
# Interface Type Source Model MAC
# ---------- -------- ------------ ------- -----------------
# - network br0-network virtio 52:54:00:b0:e0:c6
也可以导出 XML 验证:
sudo virsh dumpxml <虚拟机名称> | grep -A 10 '<interface'
3.5 为运行中的虚拟机添加网卡
如果虚拟机正在运行,去掉 --config 参数即可热添加:
sudo virsh attach-interface <虚拟机名称> \
--type network \
--source br0-network \
--model virtio \
--persistent \
--live
3.6 移除网卡
# 通过 MAC 地址移除
sudo virsh detach-interface <虚拟机名称> --type network --mac <MAC地址> --persistent
3.7 创建新 VM 时直接指定桥接网络
virt-install \
--name my-vm \
--memory 2048 \
--vcpus 2 \
--disk pool=vm-pool,size=20 \
--network network=br0-network \
--cdrom /path/to/iso \
--os-variant virtual
四、Windows VM 特别说明
4.1 需要 VirtIO 驱动
Windows 系统默认不包含 VirtIO 驱动,安装系统或启动后需要加载。VirtIO 驱动 ISO 可从以下地址获取:
4.2 挂载 VirtIO 驱动 ISO
# 查看当前磁盘配置找到 CDROM
sudo virsh dumpxml <VM名称> | grep -A 10 disk
# 添加 VirtIO 驱动 ISO
sudo virsh attach-disk <VM名称> /path/to/virtio-win.iso \
--type cdrom \
--mode readonly \
--target sdb \
--persistent
4.3 Windows 内安装驱动
- 启动 Windows
- 打开 设备管理器 → 找到带黄色感叹号的 以太网控制器
- 右键 → 更新驱动程序 → 浏览我的电脑以查找驱动程序
- 选择 VirtIO 驱动 ISO 挂载的光驱目录
- 勾选 包括子文件夹 → 安装驱动
五、问题排查
5.1 SSH 连接断开
切换到桥接网络时,如果旧连接断开太快,SSH 会话可能中断。解决方案:
- 提前启用 root SSH 登录并设置密码
- 等待 NetworkManager 完成切换后重新连接
5.2 桥接后网络不通
# 检查桥接状态
brctl show
# 检查 enp1s0 是否在 br0 中(不在的话不会通)
# 重启 NetworkManager
sudo systemctl restart NetworkManager
# 检查 iptables 规则是否阻止了桥接流量
sudo iptables -L FORWARD
5.3 libvirt 启动失败
# 查看 libvirtd 日志
sudo journalctl -u libvirtd -n 50
# 检查网络配置
sudo virsh net-dumpxml br0-network
5.4 Windows VM 无法获取 IP
- 确认网卡类型是
virtio且驱动已正确安装 - 在 Windows 内运行
ipconfig /renew强制获取 IP - 检查局域网 DHCP 服务是否正常
6.5 总结
对于本教程的飞牛NAS嵌套虚拟化场景,我们选择 Linux Bridge 的原因很简单:够用、稳定、零额外复杂度。嵌套虚拟化本身已经引入了额外的性能层级,如果再叠加 OVS 的用户态处理路径,会进一步增加性能损耗和排障难度。而 Linux Bridge 作为内核原生的二层转发设备,能够以最小的开销完成任务,且与 libvirt/KVM 的配合最为成熟。
如果你的后续需求涉及到跨主机 Overlay 网络、SDN 编排或大规模多租户环境,届时再考虑迁移到 OVS 也不迟。
七、相关命令速查
| 命令 | 用途 |
|---|---|
brctl show | 查看 Linux bridge 状态 |
virsh net-list --all | 查看所有 libvirt 网络 |
virsh net-dumpxml <网络名> | 查看 libvirt 网络配置 |
virsh list --all | 查看所有虚拟机 |
virsh domiflist <VM名> | 查看虚拟机网卡列表 |
virsh dumpxml <VM名> | 导出虚拟机完整配置 |
nmcli con show | 查看 NetworkManager 连接 |
nmcli dev status | 查看 NetworkManager 设备状态 |
ovs-vsctl show | 查看 OVS 网桥状态(已安装 OVS 时可用) |
ovs-ofctl dump-flows <网桥名> | 查看 OVS 流表规则 |