在运行官方 Ubuntu 20.04 映像的 Raspberry Pi 4 8GB 上,我无法让客户虚拟机内的网络与 KVM 配合使用。据我所知,我的网络配置正确。我真的希望有人能告诉我我做错了什么,并能给我指出更好的文档。我看过 netplan 的文档、十几个关于 KVM 设置的不同教程,甚至还查看了一些与 CPU 配置相关的 QEMU 文档,因为我发现 QEMU 对 aarch64 的构建远不如对 x86_64 的构建好。
我按照在十几个教程中找到的相同方法安装了 KVM:
$ sudo apt install qemu qemu-kvm libvirt-clients libvirt-daemon-system virtinst bridge-utils
$ sudo systemctl enable libvirtd
$ sudo systemctl start libvirtd
这是我的网络计划:
$ cat /etc/netplan/01-netcfg.yaml
network:
ethernets:
eth0:
dhcp4: false
dhcp6: false
optional: true
nameservers:
addresses: [1.1.1.1, 1.0.0.1]
wifis:
wlan0:
dhcp4: true
dhcp6: false
optional: true
access-points:
"censored":
password: "censored"
bridges:
br0:
interfaces: [eth0]
nameservers:
addresses: [1.1.1.1, 1.0.0.1]
parameters:
stp: true
forward-delay: 4
dhcp4: true
dhcp6: false
version: 2
renderer: networkd
然后我为 KVM 域定义了它:
$ sudo mkdir -p /opt/kvm
$ sudo nano /opt/kvm/host-bridge.xml
<network>
<name>host-bridge</name>
<forward mode="bridge"/>
<bridge name="br0"/>
</network>
$ virsh net-define /opt/kvm/host-bridge.xml
$ virsh net-start host-bridge
$ virsh net-autostart host-bridge
然后我检查它确实存在并且配置正确:
$ virsh net-list --all
Name State Autostart Persistent
--------------------------------------------------
default inactive no yes
host-bridge active yes yes
开始创建虚拟机后,我检查其 vnet0 是否正确添加到网桥:
$ sudo virt-install --name Test-VM --ram=2048 --vcpus=2 --cpu max --hvm --disk path=/opt/vhd/test-vhd,size=16 --cdrom /opt/iso/ubuntu-20.04.1-live-server-arm64.iso --network bridge=br0 --graphics vnc
$ virsh domiflist Test-VM
Interface Type Source Model MAC
-----------------------------------------------------------
vnet0 bridge br0 virtio 52:54:00:64:58:9e
$ brctl show
bridge name bridge id STP enabled interfaces
br0 8000.dca632b43f5b yes eth0
vnet0
docker0 8000.0242aa58079a no
docker1 8000.024296884d89 no veth239b4dd
veth76e81fc
vethdffe7c7
vethef20e5a
但是,经过所有这些操作后,我的客户机内部的网络似乎无法正常工作。它只是不停地尝试获取 IP 地址,但始终无法获取。我是不是错过了什么?
我还检查了虚拟机是否确实正在使用桥接接口,看起来似乎是这样的:
$ virsh edit Test-VM
...
<interface type='bridge'>
<mac address='52:54:00:64:58:9e'/>
<source bridge='br0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</interface>
...
这是客户机正在旋转的屏幕。如您所见,我通过主机上的桥接接口拥有完整的网络功能,可以通过 VNC 连接到 KVM。 截屏
答案1
好吧,我一直忽略的一件事是我的防火墙。防火墙阻止了我的客户通过网桥进行通信。我不完全了解问题所在,但至少我通过这个错误报告知道发生了什么:https://bugs.launchpad.net/ubuntu/+source/ufw/+bug/573461
为了解决这个问题,我这样做了:
$ sudo nano /etc/default/ufw
然后改变这个
IPT_MODULES=""
对此
IPT_MODULES="bridge"
然后我转到这个文件:
$ sudo nano /etc/ufw/sysctl.conf
并将其附加到其末尾:
# Don't filter packets to our libvirt guests
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
然后重新加载防火墙:
$ sudo ufw reload
现在,我的客人可以像物理机器一样完全访问我的网络,而我的主机仍能保持适当的防火墙保护。
如果有人对我在这里所做的事情有一个“简单”的解释,请随时分享。我能想到的最好的办法是,这会告诉 UFW,即使它在网络配置之前加载,也要预料到会有桥接,并且不要过滤它们。或者至少我认为它正在这样做。