Ubuntu 24.04 使用 Virt-Manager 并设置网桥

缘由

昨晚用户反馈了一个 DaRemote 的 bug,说在 Windows 上获取信息失败了。以前都是在 Vultr 上创建的 Windows 服务器,这次想趁此机会在本地重新把虚拟机运行起来,于是翻出早先备份的 Windows10.vdi,又在 Ubuntu 24.04 上下载了 VirtualBox,结果启动的时候报 VERR_VMX_IN_VMX_ROOT_MODEGemini 说是有另一个虚拟程序占用硬件控制,导致 VirtualBox 无法进入“根模式”来接管 CPU

Gemini 给出了一些列处理方法,最后来了一句:

如果你打算长期在 Ubuntu 上通过远程桌面运行虚拟机,VirtualBox 并不是最佳选择

  • 更好的方案:使用 Ubuntu 自带的 **Virt-Manager (KVM/QEMU)**。
  • 原因:KVM 是内核原生的,它和 Ubuntu 的远程桌面环境、系统服务兼容性极好,永远不会出现 VMX_ROOT_MODE 这种“抢位置”的报错,因为大家都在用同一个“位置”。
    你想让我教你如何把现有的 VDI 磁盘无损转换到 KVM (Virt-Manager) 中运行吗?这样以后远程使用会顺滑得多。

既然都这么说了,我就从善如流,试试看 Virt Manger 怎么样。

安装 Virt-Manager

sudo apt update
sudo apt install virt-manager qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils
sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER

一步一步配置,挂载 vdi,一切顺利,很快进了系统,网络也有了。然后我看了一些一下网络,发现走的 NAT,而我希望能和开发机在同一个局域网。

于是开始配置网桥。

配置网桥

Gemini 给了我一堆在终端下配置的步骤,但我不准备听它的。虽然它警告我:

虽然有 GUI,但很多教程倾向于使用 Netplan(命令行)的原因是:

  • 稳定性:在服务器环境或远程登录模式下,GUI 可能会因为权限问题无法修改正在使用的物理网卡。
  • 透明度:Netplan 配置文件(YAML)一目了然,而 GUI 操作在后台生成的配置有时比较混乱。

但是 Ubuntu 的尿性我了解,在终端下配置网络很可能会不生效。我决定不听 Gemini 的建议,选择 GUI 工具。

打开 nm-connection-editor (即 Advanced Network Configuration)的时候,我觉得很快就能搞定。也确实很简单:创建网桥br0,添加物理网卡,点击保存。结果进入虚拟机,获取不到 ip,手动设置后也连接不了网络。

再次询问 Gemini,告诉我看下网桥是否挂在了网卡:

brctl show br0

如果 interfaces 这一列是空的,说明网桥只是一个空壳,没有连接到外网,虚拟机自然拿不到 IP。
这通常是因为在 Ubuntu 24.04 的 GUI 或是 Netplan 配置中,物理网卡被原有的连接(Wired Connection)占用了,导致它无法加入新创建的 br0

我一看,interfaces 下果然是空的。再次追问怎么办,它推荐使用 nmcli 进行强制绑定:

# 找到物理网卡的连接名
nmcli connection show

# 将物理网卡绑定到 br0 (假设物理连接名是 'Wired connection 1')
sudo nmcli connection modify "Wired connection 1" master br0 slave-type bridge

# 重新激活连接
sudo nmcli connection up br0
sudo nmcli connection up "Wired connection 1"

上面这步操作之后,br0 还是无法使用网卡。多次沟通后,它祭出终极手段:

彻底删除冲突的旧连接定义: 既然 enp3s0 这个连接名一直在干扰网桥,我们把它删掉,让系统只能通过网桥连接。

sudo nmcli connection delete enp3s0
# 一次启动网桥连接
sudo nmcli connection up "Wired connection 1"
sudo nmcli connection up "br0"
# 再次连接网卡
sudo nmcli device connect enp3s0
sudo nmcli connection modify "Wired connection 1" ethernet.mac-address ""
# 手动创建了 br-slave 连接
sudo nmcli connection add type ethernet slave-type bridge con-name br-slave ifname enp3s0 master br0

这几个命令下去,网桥终于工作了!

$ nmcli device status
DEVICE TYPE STATE CONNECTION
br0 bridge connected br0
enp3s0 ethernet connected br-slave
docker0 bridge connected (externally) docker0
lo loopback connected (externally) lo
virbr0 bridge connected (externally) virbr0
vethaec7531 ethernet unmanaged --

因为使用了最后手动创建的 br-slave 连接,所以 Wired connection 1 可以删除。

总结

只要用对了方法,创建网桥还是很简单的,也就是几条命令而已,我也就花了……嗯……三个多小时。