Linux下如何使用KVM安装Windows虚拟机

本文记录在Vmware Ubuntu Server 22.04虚拟机环境下,使用KVM安装windows 10虚拟机的过程。

安装KVM

先来介绍一下Hypervisor,也被称为:虚拟机监控器(Virtual Machine Monitor,VMM)。hypervisor分为两类,I型和II型。I型也被称为原生型/裸机型hypervisor,直接运行在宿主机硬件上,来控制宿主机硬件和管理客操作系统,代表就是KVM、Esxi。II型被称为寄居型或托管型hypervisor,运行于操作系统之上,代表是Vmware Workstation Pro、Qemu、Virtual Box。

两种hypervisor示意

客操作系统(guest OS)跟我们常用的虚拟机(virtual machine)、实例(instance)、域(Domain)都是同一个概念。例如在云计算的环境中,常用实例的概念,在PC的VmWare Workstation Pro中常用虚拟机的概念,本文中用virsh管理KVM环境中,用的是Domain的概念。

KVM与Qemu与Xen与Libvirt

  1. KVM全称Kernel-based Virtual Machine,是Linux内核的一个组件,提供x86硬件上的完整虚拟化解决方案。自linux kernel 2.6.20版本起已被包含在主线中,所以当前各主流发行版本都已集成。

  2. Qemu是一套自由软件,提供完全的虚拟化解决方案,有完整的包括处理器虚拟化、内存虚拟化以及IO设备虚拟化的功能,所以Qemu本身并不依赖KVM。因为Qemu的架构是由纯软件实现,来自客户机的硬件级请求需要Qemu转译给硬件,因此性能较差。 但KVM对处理器和内存的虚拟化性能更好,通过将二者整合,把CPU和内存的虚拟化交给内核级的KVM去做,对IO的模拟以及对虚拟设备的调度和管理交给Qemu负责,就成了最流行的虚拟化解决方案:QEMU-KVM。

  3. Xen也是一种提供原生虚拟化的解决方案,跟KVM属于“竞品”关系,如前文所述,当前主流Linux已使用KVm作为了默认的硬件虚拟化技术,Xen已经较少被使用。

  4. Libvirt是一种对各种虚拟化平台进行管理的库,由RedHat所支持开发的开源API。如下图所示,向下,可以适配多种虚拟化解决方案,管理多种虚拟化平台的虚拟机,例如:KVM、Xen;向上,可以为用户提供多种管理接口,例如通过命令行管理虚拟机的工具virsh,通过GUI管理虚拟机的工具virt-manager等。

libvirt示意图

KVM工具栈

KVM工具栈示意图

现在把视角切回KVM,通过上面的介绍,就可以更容易理解KVM工具栈这张图。大的类别上,这些管理工具可以分为两类,libvirt类和qemu类。本次在Ubuntu Server上创建虚拟机主要使用的就是libvirt类的virsh命令行工具。

安装KVM工具

既然KVM是Linux自带的,内核组件之一,自然也就没有安装一说,但是启用KVM需要硬件支持虚拟化,如果是在裸机上可能需要在主板bios上进行设置,如果本就是虚拟机环境下,需要启用“虚拟化 Intel VT-x/EPT或AMD-V/RVI”来进行嵌套虚拟化的支持。

通过执行命令:grep -Eoc "vmx|svm" /proc/cpuinfo,若出现大于0的数字,表明已经支持虚拟化。另一个方法是使用cpu-checker软件。sudo apt update; sudo apt install cpu-checker;kvm-ok,支持虚拟化会打印“INFO: /dev/kvm exists\ KVM acceleration can be used”。

接下来安装KVM在用户空间的管理工具,本文是在Vmware中安装的Ubuntu Server 22.04。

sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager

qemu-kvm - 为 KVM 管理程序提供硬件模拟的软件程序
libvirt-daemon-system - 将 libvirt 守护程序作为系统服务运行的配置文件
libvirt-clients - 用来管理虚拟化平台的软件
bridge-utils - 用来配置网络桥接的命令行工具
virtinst - 用来创建虚拟机的命令行工具
virt-manager - 提供一个易用的图形界面,并且通过libvirt 支持用于管理虚拟机的命令行工具

安装好后,通过下面的命令验证libvirt是否自动启动,sudo systemctl is-active libvirtd,正常启动将会输出“active”。

若要使当前用户(非root)能够创建和管理虚拟机,需要把当前用户加入到libvirt和kvm的用户组中,命令如下:sudo usermod -aG libvirt $USER; sudo usermod -aG kvm $USER

配置网桥

这一步将创建一个桥接网卡,桥接在原来的网卡上,令创建新的虚拟机都将是桥接到宿主同网络上,便于管理。

安装完KVM工具后会自动安装一个网卡,一般为virbr0,可以通过ip link来查看。

sudo vim /etc/sysctl.d/bridge.conf,内容如下:

1
2
3
net.bridge.bridge-nf-call-ip6tables=0
net.bridge.bridge-nf-call-iptables=0
net.bridge.bridge-nf-call-arptables=0

sudo vim /etc/udev/rules.d/99-bridge.rules,内容为:

ACTION=="add", SUBSYSTEM=="module", KERNEL=="br_netfilter", RUN+="/sbin/sysctl -p /etc/sysctl.d/bridge.conf"

上面第一个文件用来配置桥接参数,第二个文件指定了一个规则集,作用是当内核模块“br_netfilter”被加载时,重新加载特定的网络桥接配置,并使相关配置生效。

删除默认网卡:sudo virsh net-destroy default; sudo virsh net-undefine default

如果还有,手动删除,例如:ip link delete virbr0-nic

接下来修改桥接网卡的配置文件:sudo vim /etc/netplan/00-installer-config.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
network:
  ethernets:
    ens33:
      dhcp4: false
      dhcp6: false
  bridges:
    br0:
      interfaces: [ ens33 ]
      addresses: [192.168.153.140/24]
      gateway4: 192.168.153.1
      mtu: 1500
      nameservers:
        addresses: [8.8.8.8,8.8.4.4]
      parameters:
        stp: true
        forward-delay: 4
      dhcp4: no
      dhcp6: no
  version: 2

上面的文件要根据自身网络情况来配置。 ens33:当前上网的有线网卡 address:宿主机的IP地址 gateway4:宿主机上网的网关地址

笔者网络环境

sudo netplan apply应用设置,br0网卡将会被创建。

接下来创建kvm网桥:vim host-bridge.xml

1
2
3
4
5
<network>
  <name>host-bridge</name>
  <forward mode="bridge"/>
  <bridge name="br0"/>
</network>
1
2
3
sudo virsh net-define host-bridge.xml
sudo virsh net-start host-bridge
sudo virsh net-autostart host-bridge

使用virsh net-list --all来查看是否创建成功;

1
2
3
Name          State    Autostart   Persistent
------------------------------------------------
host-bridge   active   yes         yes

使用KVM安装Windows10

上面完成了KVM工具的安装以及桥接网卡的配置,接下来安装Windows操作系统。需要windows操作系统的镜像和virtio镜像文件,virtio镜像文件可以在这里下载:https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/

创建虚拟磁盘

sudo qemu-img create -f qcow2 /kvm/img/win10.img 60G

创建虚拟机

virt-install --name win10 --ram 4096 --vcpus=2 --disk path=/kvm/img/win10.img,format=qcow2,size=60,bus=virtio,cache=none --accelerate --network bridge=br0 --os-type=windows --cdrom /kvm/iso/cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24.iso --graphics vnc,listen=0.0.0.0,port=5900 --noautoconsole

根据自身服务器的具体情况,选择镜像的存储位置;创建成功后,可通过VNC连接宿主机的5900端口,可视化地安装windows操作系统。

虚拟机创建成功

安装windows

安装windows的过程中,会遇到找不到磁盘的情况,需要挂载virtio镜像来加载磁盘驱动。通过其他教程,命令"virsh change-media win10 hda /kvm/iso/virtio-win-0.1.215.iso"来做到。virsh change-media是改变光盘媒介的命令。

直接执行可能是不会成功的,因为我们的光盘设备名称可能不是hda,所以要先查看当前虚拟机上设备的名称。使用命令virsh domblklist win10,如下:

于是:virsh change-media win10 sda /kvm/iso/virtio-win-0.1.240.iso,成功,将会提示“Successfully updated media”

之后,在windows安装流程界面,选择“加载驱动程序”,“浏览”,选择virtio驱动器目录下的“amd64/w10”,之后选择下一步,就能扫描到磁盘了。

加载驱动

成功扫描到磁盘

此时依然是不能安装,因为我们已经把windows镜像给替换成了驱动的,用来发现磁盘。现在已经识别出了磁盘,所以现在需要再把windows镜像换回来,之后点击刷新,“无法在此驱动器上安装windows”的提示信息也会消失,后续按正常的windows安装步骤即可。

参考文章

https://www.cnblogs.com/qiuhom-1874/p/13499801.html

https://cloud.tencent.com/developer/article/1471036

使用 Hugo 构建
主题 StackJimmy 设计