Ubuntu Kvm 安装

Ubuntu 安装 KVM 使用 nmcli 配置桥接网络。

环境检查

安装 kvm-ok 命令,也可以直接查询 /proc/cpuinfo 中是否有自己硬件平台的虚拟化 flag 另外检查系统设备 /dev/kvm 是否存在。

1
sudo apt install cpu-checker -y

运行命令检查是否支持 KVM。

1
2
3
4
5
6
7
sudo kvm-ok

# 看到下面的提示表示可以支持
yw@yw-linux:~$ sudo kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used
yw@yw-linux:~$

通常硬件都会支持,如果不支持的话,检查 BIOS 是否打开响应的虚拟化支持。

安装软件包

1
sudo apt install -y qemu-kvm virt-manager libvirt-daemon-system virtinst libvirt-clients bridge-utils
  • qemu-kvm – 一个提供硬件仿真的开源仿真器和虚拟化包
  • virt-manager – 一款通过 libvirt 守护进程,基于 QT 的图形界面的虚拟机管理工具
  • libvirt-daemon-system – 为运行 libvirt 进程提供必要配置文件的工具
  • virtinst – 一套为置备和修改虚拟机提供的命令行工具
  • libvirt-clients – 一组客户端的库和 API,用于从命令行管理和控制虚拟机和管理程序
  • bridge-utils – 一套用于创建和管理桥接设备的工具

启动服务

1
2
sudo systemctl enable --now libvirtd
sudo systemctl start libvirtd

加入用户组(可选)

将当前登录用户加入 kvm 和 libvirt 用户组,以便能够创建和管理虚拟机。

1
2
sudo usermod -aG kvm $USER
sudo usermod -aG libvirt $USER

创建网桥(nmcli)

默认 KVM 安装完会自带一个 NAT 网络,有时候我们需要外部能访问虚拟机,所以需要一个桥接网络。下面使用 nmcli 创建一个桥接设备,如果你使用的不是 NetworkManager 管理网络,需要自行查询资料,创建一个桥接网卡。

⚠️注意:以下为踩坑经验:

  • 已测试 ESXI 的虚拟机,打开硬件虚拟化的情况下创建桥接网卡无法上网。
  • 已测试 CPU 为 AMD 的 Windows 11 开启了虚拟化,使用 Vmware 创建虚拟机没有打开虚拟化相关参数,创建桥接之后无法上网。
  • 已测试 CPU 为 Intel 的 Windows 10 未开启虚拟化,使用 Vmware 创建虚拟机并打开虚拟化相关参数,创建网桥之后可以正常联网。

备注:Windows 开启虚拟化的显著标志是你启用了 WSL (安装 Docker Desktop) 或者勾选了设置中的内核保护什么的。导致物理机系统变成一个虚拟机系统。

创建桥接连接和设备

这里命名新的桥接网卡名称为 br0。下面的命令会同时创建一个 br0 的网卡和链接。

1
sudo nmcli con add ifname br0 type bridge con-name br0

把物理网卡关联到桥接网卡

这里物理设备是 ens33,桥接网卡为 br0 (链接名)。

1
sudo nmcli con add type ethernet slave-type bridge con-name bridge-enp1s0-br0 ifname enp1s0 master br0

设置桥接网卡的 IP(可选)

因为我们直接桥接到物理网卡上,所以物理网卡之前的 IP 地址就没了。如果你原本物理网卡的 IP 地址是静态的,并且希望桥接后 IP 地址不变,就需要把静态的 IP 地址配置到我们的桥接链接上。

如果你原本是动态的 IP 地址,则可忽略这个操作使用默认的 DHCP 即可。

注意这里是设置 br0 链接的网络参数。

1
sudo nmcli con mod br0 ipv4.addresses 192.168.4.254/24 ipv4.gateway 192.168.4.1 ipv4.dns 114.114.114.114 ipv4.method manual

这里我们指定其静态的网络地址信息。

截止到这一步我们的网络链接配置应该如下:

1
2
3
4
5
6
7
8
yw@yw-linux:~$ sudo nmcli conn show
NAME UUID TYPE DEVICE
br0 6fb937cf-9040-492c-af3b-d8280368f7c2 bridge br0
Wired connection 1 d6776822-807e-3f43-afba-9a929a612c7b ethernet enp1s0
docker0 7d29a0bc-46b0-4dfe-b26c-db8a19a617aa bridge docker0
virbr0 093cc70b-f8ba-4b6b-b35f-678e2f063fbd bridge virbr0
bridge-enp1s0-br0 eb0cccee-a7bf-4fa1-ba59-a25b64bf56e8 ethernet --
yw@yw-linux:~$

桥接网络是否启动观察我们创建的 bridge-enp1s0-br0 链接是否激活就行。很明显这里还没进行激活。

启动(切换)桥接网络

注意此步骤切换链接之后,会短暂断网或者彻底断网,且两条命令必须合并为一条命令执行,如果出现任何网络问题,必须给服务器接上显示器进入终端恢复排查问题。命令如下:

1
2
3
4
sudo nmcli con down "有线连接 1" && sudo nmcli con up br0

# 如果你的系统默认激活的链接不是 "有线连接 1" 请自行替换,比如这里我的
sudo nmcli con down "Wired connection 1" && sudo nmcli con up br0

激活桥接不是 up 我们创建的 bridge-enp1s0-br0 而是激活 br0 链接。

执行命令后,SSH 卡顿等几秒重新连接打印相关信息,切换成功后配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
yw@yw-linux:~$ sudo nmcli con down "Wired connection 1" && sudo nmcli con up br0
Connection 'Wired connection 1' successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/1)
Connection successfully activated (master waiting for slaves) (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)
yw@yw-linux:~$
yw@yw-linux:~$
yw@yw-linux:~$
yw@yw-linux:~$ sudo nmcli conn show
NAME UUID TYPE DEVICE
br0 6fb937cf-9040-492c-af3b-d8280368f7c2 bridge br0
docker0 7d29a0bc-46b0-4dfe-b26c-db8a19a617aa bridge docker0
virbr0 093cc70b-f8ba-4b6b-b35f-678e2f063fbd bridge virbr0
bridge-enp1s0-br0 eb0cccee-a7bf-4fa1-ba59-a25b64bf56e8 ethernet enp1s0
Wired connection 1 d6776822-807e-3f43-afba-9a929a612c7b ethernet --
yw@yw-linux:~$

其他提醒

如果你的 Ubuntu 安装了图形化的界面,这时候就不要再去点无形化的网络开关了。这样图形化网络管理组件会自动切换桥接网卡为你默认的网卡链接。

多多使用 nmcli conn show 查看你的网络状态。

KVM 桥接网络配置(不确定)

⚠️注意:如果创建该配置后虚拟机无法桥接上网(上面桥接网络创建后,宿主机可以正常联网),删除该 KVM 桥接网络配置,可能会正常。

不确定此步是否需要是因为,网上查找资料都是配置了此步骤,笔者之前在虚拟机上测试成功了。但是在升级笔者自己的 NAS 时,最后的虚拟机无法正确获取 DHCP 分配的地址,尝试删除该 KVM 网络配置后就正常了。

当我们创建好桥接网卡之后,需要告诉 KVM 这个网卡是桥接网卡,可以使用了。如下创建配置文件,并执行命令:

1
2
3
4
5
6
<!-- 配置文件内容 bridge.xml -->
<network>
<name>br0</name>
<forward mode="bridge"/>
<bridge name="br0" />
</network>

注意配置中的 bridge namenmcli 中的设备名。

执行如下命令创建:

1
2
3
4
5
sudo virsh net-define ./bridge.xml

# 设置自动启动并启用
sudo virsh net-start br0
sudo virsh net-autostart br0

命令执行结果示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
yw@yw-linux:/opt/kvm$ sudo virsh net-define ./bridge.xml
Network br0 defined from ./bridge.xml

yw@yw-linux:/opt/kvm$ sudo virsh net-start br0
Network br0 started

yw@yw-linux:/opt/kvm$ sudo virsh net-autostart br0
Network br0 marked as autostarted

yw@yw-linux:/opt/kvm$ sudo virsh net-list --all
Name State Autostart Persistent
--------------------------------------------
br0 active yes yes
default active yes yes

yw@yw-linux:/opt/kvm$

创建磁盘

其他资源是创建虚拟机的时候参数指定分配的,但是磁盘文件需要预先创建,且该磁盘文件不可以存放到用户家目录

1
sudo qemu-img create -f qcow2 -o size=10G,preallocation=metadata test.qcow2

size 的大小自定义,末尾的文件名自定义。

创建虚拟机

⚠️注意:安装系统使用的镜像文件也不能放到用户家目录,否则可能存在无法读取镜像文件的权限问题。

1
2
3
4
5
6
7
sudo virt-install --name test \
--ram 2048 --vcpus 2 \
--disk path=/mnt/test.qcow2,bus=virtio,cache=writeback \
--cdrom /mnt/ubuntu-22.04.3-desktop-amd64.iso \
--network bridge=br0,model=virtio \
--graphics=vnc,password=123456,port=5955,listen=0.0.0.0 \
--noautoconsole
  • --name 指定虚拟机的名称
  • --ram 指定虚拟机内存的大小,单位 MB
  • --vcpus 指定虚拟 CPU 的核心数
  • --disk 指定磁盘文件位置,bus 指定为 virtio 半虚拟化,磁盘缓存策略设置为写缓存,写缓存可能存在一定的断电丢失数据,但是速度更快。可以更换为 cache=none (无缓存)或者 cache=directsync (直写同步缓存)来保证数据的安全性。
  • --cdrom 指定 ISO 文件位置
  • --network 指定虚拟机使用的网络,这里指定为我们创建的 br0 网络,并且指定模式也为半虚拟化。查看 KVM 网络使用 sudo virsh net-list --all
  • --graphics 指定虚拟机图形显示方式,主要用于设置远程访问。这里指定为 vnc 并设置了 vnc 相关的参数。
  • --noautoconsole 阻止自动启动虚拟机的控制台。需要通过 VNC 或其他方式连接到虚拟机以与其交互。如果不想使用 vnc 可以直接打开 virt-manager 的图形化工具,打开控制台,如果使用了上面的 vnc 配置,则会提示输入密码,密码就是 vnc 参数中指定的密码。