Ubuntu Kvm 安装

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

环境检查

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

sudo apt install cpu-checker -y

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

sudo kvm-ok

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

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

安装软件包

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 – 一套用于创建和管理桥接设备的工具

启动服务

sudo systemctl enable --now libvirtd
sudo systemctl start libvirtd

加入用户组(可选)

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

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 的网卡和链接。

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

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

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

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 链接的网络参数。

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

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

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

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 链接是否激活就行。很明显这里还没进行激活。

启动(切换)桥接网络

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

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 卡顿等几秒重新连接打印相关信息,切换成功后配置如下:

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 这个网卡是桥接网卡,可以使用了。如下创建配置文件,并执行命令:

<!-- 配置文件内容 bridge.xml -->
<network>
	<name>br0</name>
	<forward mode="bridge"/>
	<bridge name="br0" />
</network>

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

执行如下命令创建:

sudo virsh net-define ./bridge.xml

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

命令执行结果示例:

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$ 

创建磁盘

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

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

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

创建虚拟机

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

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 参数中指定的密码。