Installing KVM Virtual Machines and Running Windows on a Mini Host

Due to a hard drive upgrade on my mini server, I had to reinstall KVM. I took this opportunity to document the installation process. In this article, I will be installing Windows Server 2019 on qemu+kvm with virt.(English version Translated by GPT-3.5, 返回中文)

Preparation

  1. First, check if your CPU supports virtualization (most modern host CPUs do).

    1
    cat /proc/cpuinfo | egrep 'vmx|svm'
  2. If you get any output (or even if you don’t), it means your CPU supports virtualization.

    1
    2
    3
    4
    5
    6
    7
    8
    flags : fpu vme de pse tsc ...... monitor ds_cpl vmx est tm2 ssse3 ......
    flags : fpu vme de pse tsc ...... monitor ds_cpl vmx est tm2 ssse3 ......
    flags : fpu vme de pse tsc ...... monitor ds_cpl vmx est tm2 ssse3 ......
    flags : fpu vme de pse tsc ...... monitor ds_cpl vmx est tm2 ssse3 ......
    flags : fpu vme de pse tsc ...... monitor ds_cpl vmx est tm2 ssse3 ......
    flags : fpu vme de pse tsc ...... monitor ds_cpl vmx est tm2 ssse3 ......
    flags : fpu vme de pse tsc ...... monitor ds_cpl vmx est tm2 ssse3 ......
    flags : fpu vme de pse tsc ...... monitor ds_cpl vmx est tm2 ssse3 ......
  3. If there is no output, it means your CPU does not support virtualization.

Install Base Packages

  1. Disable SELinux by changing SELinux=enforcing to SELinux=disabled in /etc/sysconfig/selinux. After making the change, it should look like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # This file controls the state of SELinux on the system.
    # SELINUX= can take one of these three values:
    # enforcing - SELinux security policy is enforced.
    # permissive - SELinux prints warnings instead of enforcing.
    # disabled - No SELinux policy is loaded.
    SELINUX=disabled // 更改这里
    # SELINUXTYPE= can take one of three values:
    # targeted - Targeted processes are protected,
    # minimum - Modification of targeted policy. Only selected processes are protected.
    # mls - Multi Level Security protection.
    SELINUXTYPE=targeted
  2. Run the following command:

    1
    yum -y install qemu-kvm libvirt virt-install bridge-utils
  3. It is recommended to restart the machine (although it is not necessary).

  4. Use the command lsmod | grep kvm to check if the kvm module is running. If you see the following output, it means the module has been successfully loaded:

    1
    2
    3
    [root@localhost ~]# lsmod | grep kvm
    kvm_intel 188688 0
    kvm 636931 1 kvm_intel

Set Network to Bridged Networking

This guide does not cover NAT networking configuration.

This step is recommended to be performed on the host machine, not via SSH, as it may cause network disconnection during the network configuration process.

  1. Go to the directory: /etc/sysconfig/network-scripts/

  2. Find your network card and edit it (you can use the ip addr command to identify the network card). For example, if you see the following output when running ip addr, your main network card would be enp1s0.

    1
    2
    3
    4
    5
    6
    7
    8
    [root@Ruter-Home ~]# ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    ...
    2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    inet 10.0.0.80/24 brd 10.0.0.255 scope global noprefixroute dynamic br0
    3: wlp2s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    ......

    Why is it not eth0? Since version 197 of systemd, the naming convention has changed. The old names starting with ethN have been changed to en[x][M]s[N], and the old wlanN names have been changed to wl[x][M]s[N]. As you can see from the example above, I have one network interface enp1s0 and one wireless interface wlp2s0.

    The detailed naming convention is as follows: Predictable Network Interface Names

    1. Names incorporating Firmware/BIOS provided index numbers for on-board devices (example: eno1)
    2. Names incorporating Firmware/BIOS provided PCI Express hotplug slot index numbers (example: ens1)
    3. Names incorporating physical/geographical location of the connector of the hardware (example: enp2s0)
    4. Names incorporating the interface’s MAC address (example: enx78e7d1ea46da)
    5. Classic, unpredictable kernel-native ethX naming (example: eth0)
  3. Backup your main network card configuration and run the following command (replace the network card name in the command with your own network card name):

    If you want to delete the bridge, refer to this website CentOS 7.4 Delete virbr0 Virtual Network Card

    1
    2
    3
    [root@Ruter-Home kvm]# virsh iface-bridge enp1s0 br0
    Created bridge br0 with attached device enp1s0
    ....
  4. If you do not encounter any errors here, that’s great! However, if you encounter an error like the following, you can make the following changes:

    1
    2
    3
    error: Failed to start bridge interface br0
    error: internal error: failed to create(start) interface br0: failed to execute external program - Running 'ifup br0' failed with exit code 1:
    Determining IP information for br0... failed: no link present. Check cable?
  5. It seems that there is an issue with assigning an IP to br0. I found a solution and made the following changes:

    Modify ifcfg-enp1s0: vi /etc/sysconfig/network-scripts/ifcfg-enp1s0

    1
    2
    3
    4
    5
       DEVICE="enp1s0"
    ONBOOT="yes"
    BRIDGE="br0"
    # 下面的BOOTPROTO是新增的, 值为None
    BOOTPROTO=none

    Modify ifcfg-br0 as follows: vi /etc/sysconfig/network-scripts/ifcfg-br0

    1
    2
    3
    4
    5
    6
    7
    8
    DEVICE="br0"
    ONBOOT="yes"
    TYPE="Bridge"
    BOOTPROTO="dhcp"
    # 注释了这1/2行
    #STP="on"
    # 注释了这2/2行
    #DELAY="0"
  6. Disable the network card, enable it again, and restart the network service:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    ifdown enp1s0
    ifdown br0

    ifup enp1s0
    ifup br0

    # 此时依然没有IP, 然后我重启了network, IP有了

    systemctl restart network
  7. Configuration completed, check the network configuration using ifconfig.

    1
    2
    3
    4
    5
    6
    7
    8
    br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 10.*.*.* netmask 255.255.255.0 broadcast 10.0.0.255
    inet6 ************ prefixlen 64 scopeid 0x20<link>
    ether ********* txqueuelen 1000 (Ethernet)
    RX packets 244 bytes 16938 (16.5 KiB)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 171 bytes 34132 (33.3 KiB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

Installing the Operating System

Before Proceeding, You Need These 2 Software:

Download VNC-Viewer VNC viewer software for connecting to the CentOS server for system installation.

Download virtio-win-0.1.173-2 Windows driver that is needed to recognize the virtual disk. Place this software on the KVM host in a specific location.

Don’t forget to prepare the ISO image of Windows. You can obtain it from MSDN我告诉你. The link provided gives you the ed2k address of the ISO image.

1
2
3
4
5
文件名: cn_windows_server_2019_updated_march_2019_x64_dvd_c1ffb46c.iso
SHA1: 1198eccdd944e49a8b981fb2c436c36a5b3ed301
文件大小: 4.98GB
发布时间: 2019-03-29
ed2k://|file|cn_windows_server_2019_updated_march_2019_x64_dvd_c1ffb46c.iso|5347280896|49FCF8C558517608537E0396854560D6|/

After preparing, create a virtual disk

The file suffix below does not have to be qcow2. It can be .img as well. You can create it in /mnt/kvm.

1
qemu-img create -f qcow2 kvm-winserver2019.qcow2 50G

Start the virtual machine using the command

Detailed explanation of the virt-install command:

-n –name: Name of the client virtual machine
-r –ram: Amount of RAM allocated to the client virtual machine
-u –uuid: UUID of the client, system will generate automatically if not specified
–vcpus: Number of virtual CPUs allocated to the client
-v –hvm: Full virtualization
-p –paravirt: Para-virtualization
-l –location=localdir: Installation source location, local, nfs, http, ftp are supported
–vnc: Use VNC, –vnclient=IP to specify the listening IP, –vncport=VNC listening port
-c –cdrom: Optical drive, installation source
–disk: Specify different options to use the disk as an installation medium
-w NETWORK, –network=NETWORK: Connect the client to the host network
-s –file-size: The size of the disk image, unit is GB
-f –file: The file to be used as the disk image
–cpuset: Set which physical CPU can be used by the virtual machine
–os-type=OS_TYPE: Optimize virtual machine configuration for a specific type of operating system (e.g. ‘linux’, ‘windows’)
–os-variant=OS_VARIANT: Further optimize virtual machine configuration for a specific operating system variant (e.g. ‘rhel6’, ‘winxp’, ‘win2k3’)
–host-device=HOSTDEV: Attach a physical host device to the guest. HOSTDEV is the libvirt node device name used with libvirt (displayed as the result of ‘virsh nodedev-list’)
–accelerate: KVM or KQEMU kernel acceleration, it is recommended to include this option. If both KVM and KQEMU are supported, KVM accelerator is preferred.
-x EXTRA, –extra-args=EXTRA: Append additional kernel command-line arguments to the installation program when performing client installation from a “–location” specified location
–nographics: By default, “virt-install” will use the “–vnc” option, specify “nographics” to assign no console to the client
————————————————
Copyright: This article is licensed under CC 4.0 BY-SA. Please include the original source link and this statement if you wish to reproduce it.
Original article: https://blog.csdn.net/zhaihaifei/article/details/51153402

1
2
3
4
5
6
7
8
9
10
11
12
13
virt-install \
--name kvm-winserver2019 \
--memory 4096 \
--vcpus sockets=1,cores=3,threads=6 \
--cdrom=/mnt/cn_windows_server_2019_updated_march_2019_x64_dvd_c1ffb46c.iso \
--os-type=windows \
--os-variant=auto \
--disk /mnt/kvm/kvm-winserver2019.qcow2,bus=virtio,size=50 \
--disk /mnt/kvm/virtio-win-0.1.173_amd64.vfd,device=floppy \
--network bridge=br0,model=virtio \
--graphics vnc,password=123456,listen=::,port=5910 \
--hvm \
--virt-type kvm

If you want to use NAT networking, change --network bridge=br0,model=virtio to --network network=default.

In the example, I used the name “kvm-winserver2019”. If you use a different name, remember to replace it in the command.

It will output the following content:

1
2
3
4
5
WARNING  Unable to connect to graphical console: virt-viewer not installed. Please install the 'virt-viewer' package.
WARNING No console to launch for the guest, defaulting to --wait -1

Starting install...
Domain installation still in progress. Waiting for installation to complete.

Open VNC viewer and connect to port 5910 of the machine

If you cannot connect to port 5910, it is likely that the CentOS firewall is blocking it. Run the following command to open port 5910:

[root@Ruter-Home ~]# firewall-cmd –zone=public –add-port=5910/tcp –permanent
success
[root@Ruter-Home ~]# firewall-cmd –reload
success

After entering the password “123456”, you will see a screen like this. The rest is a normal installation process, which will not be covered.

installing-kvm-winserver2019

If the hard drive is not detected during the installation process, install the drivers as shown below:

install-driver

Select the second option, and then the disk will appear. Proceed with the installation.

select-two

normal-installing

After installation, if there is no network card, go to Device Manager, manually update the driver, and choose the “win10” folder in the floppy drive. The network card will be installed after the update.

install-eth

If you want to see the real CPU name

If you see the CPU name as “Qemu Virtual CPU” and find it unsatisfactory, you can make the following configuration:

  1. Run virsh edit [your virtual machine name].

    1
    virsh edit kvm-winserver2019
  2. Change the first line to the following, adding xmlns:qemu:

    1
    <domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  3. Add the following between <domain> and </domain>:

    1
    2
    3
    4
    <qemu:commandline>  
    <qemu:arg value='-cpu'/>
    <qemu:arg value='host'/>
    </qemu:commandline>

Congratulations! The installation is complete. Here are some basic virsh operations.

View the list of virtual machines

1
2
3
4
5
6
virsh list

输出
Id Name State
----------------------------------------------------
5 kvm-winserver2019 running

Start and stop a virtual machine

1
2
3
virsh start 虚拟机名    # 启动虚拟机
virsh shutdown 虚拟机名 # 关闭虚拟机
virsh destroy 虚拟机名 # 直接关闭虚拟机电源

View/edit the virsh XML configuration (used when adding a new disk)

1
virsh edit 虚拟机名

Export XML configuration

1
virsh dumpxml 虚拟机名 > 导出到的文件名

If you want the virtual machine to auto-start

1
virsh autostart 虚拟机名

“””