This page documents how to set up Windows Server 2019 under QEMU/KVM on Ubuntu 18.04. I suspect the procedure is identical for Windows 10 and somewhat newer Ubuntu versions.
What you will need:
- An Ubuntu 18.04 server
- QEMU/KVM installed on it. This is good documentation: https://help.ubuntu.com/community/KVM/Installation
- A Windows Server 2019 or Windows 10 ISO. You can download them from Microsoft for free and try them for 180 days. Good enough for a test lab.
- The virtio driver iso, which you can download here [deeplink].
ISO locations
It is customary to put boot ISOs in /var/lib/libvirt/boot/ and the disk images in /var/lib/libvirt/images. Other places are fine but if you choose to put your disk images in a different location keep in mind you should tell Apparmor about it lest you get bothered with permissions issues.
This document will not describe backing up and restoring of VMs, nor will it explain snapshotting. Both are interesting in their own right and you should learn about them if you haven’t. I wanted to document specifically the process of installing and configuring a Windows Server 2019/Windows 10 guest.
Overview
1. Setting up the network interface
2. Installing the virtual machine
3. Installing drivers and the guest agent
4. Non-related tips
Setting up the network interface
I’m setting up a bridge interface for the VMs to use. By doing this the VMs will show up in my LAN on a regular LAN IP address. My subnet is 192.168.178.0/24. My host’s IP address is 192.168.178.18.
Open the file /etc/netplan/01-netcfg.yaml, or whatever .yaml file is in /etc/netplan.
Mine looked like this:
network: version: 2 renderer: networkd ethernets: eno1: dhcp4: no addresses: [192.168.178.18/24] gateway4: 192.168.178.1 nameservers: addresses: [192.168.178.1]
Edit the file to look like this:
network: version: 2 renderer: networkd ethernets: eno1: dhcp4: no dhcp6: no bridges: br0: interfaces: [eno1] dhcp4: no addresses: [192.168.178.18/24] gateway4: 192.168.178.1 nameservers: addresses: [192.168.178.1]
Be careful when editing this file; it’s easy to lock yourself out. Things to be aware of:
- netplan is very picky about indentations. You need to get this right.
- Instead of # netplan apply do netplan try <file>:
root@z230:/etc/netplan# netplan try 01-netcfg.yaml Do you want to keep these settings? Press ENTER before the timeout to accept the new configuration Changes will revert in 120 seconds
If all goes well do
# netplan apply.
You will end up with a physical interface that provides both the host and the VMs access to your LAN.
In case you have a separate network interface for your VMs try this configuration (enp7s0 and enp4s0f1 are both interfaces on my server; I want the VMs to use interface enp4s0f1 and use enp7s0 for management of the host machine itself):
network: ethernets: enp7s0: dhcp4: no dhcp6: no addresses: [192.168.178.14/24] gateway4: 192.168.178.1 nameservers: addresses: [192.168.178.1] enp5s0f1: dhcp4: no version: 2 bridges: br0: interfaces: [enp5s0f1] dhcp4: no
Installing the VM
# virt-install --name=W2K19 --ram=2048 --cpu host --hvm --vcpus=2 --os-type=windows --os-variant=win10 --disk /var/lib/libvirt/images/W2K19.img,size=40,bus=virtio --disk /var/lib/libvirt/boot/17763.737.190906-2324.rs5_release_svc_refresh_SERVER_EVAL_x64FRE_en-us_1.iso,device=cdrom,bus=ide --disk /var/lib/libvirt/boot/virtio-win-0.1.171.iso,device=cdrom,bus=ide --network bridge=br0 --graphics vnc,listen=0.0.0.0,port=5904 --check all=off
Note:
When I tried this on Ubuntu 20.04 with a Windows 10 VM I got a bunch of warning and errors and needed to do this:
virt-install --name=win10 --ram=4096 --cpu host --hvm --vcpus=2 --os-type=windows --os-variant= win10 --disk /var/lib/libvirt/images/win10.img,size=40,bus=virtio --cdrom /var/lib/libvirt/boot/Windows10.iso --disk /var /lib/libvirt/boot/virtio-win.iso,device=cdrom --network bridge=br0 --graphics vnc,listen=0.0.0.0,port=5904 --check all=of f --boot cdrom
The difference is the –cdrom specification instead of the –disk one. Also it now seems to require a –boot parameter. The rest of this article continues from the previous command, not the one in this note.
Let me break that down.
First of all, run the command as root or do sudo. The command for installing new VMs is virt-install. Do read its man page.
--name=W2K19
The VM’s name. In KVM terms this is called it’s domain. please note this name is case sensitive.
--ram=2048
The amount of ram in kilobytes
--cpu host
Tells KVM to use the host’s cpu specifications for caching. If you’re planning on using clustering or live migration read up on this part in virt-install’s man page.
--hvm
Do full instead of para virtualisation, if available
--vcpus=2
Give the VM two virtual CPU cores. Again, read the man file for interesting values, like auto.
--os-type=windows
The VM will be optimized for this OS type.
--os-variant=win10
Do
# apt install libosinfo-bin # osinfo-query os
for a full list of supported OS variants. Pick the closest one.
--disk /var/lib/libvirt/images/W2K19.img,size=40,bus=virtio
Create a disk at this location with this name. I tend to use the .img extension but .qcow2 is also common. The size is in gigabytes. Because we’re using Qemu we’ll be using the virtio bus driver. Note that we will need to install this driver in order to install Windows on the disk.
--disk /var/lib/libvirt/boot/17763.737.190906-2324.rs5_release_svc_refresh_SERVER_EVAL_x64FRE_en-us_1.iso,device=cdrom,bus=ide
We’re connecting the Windows ISO file to a CD ROM device here.
--disk /var/lib/libvirt/boot/virtio-win-0.1.171.iso,device=cdrom,bus=ide
This is the driver CD ROM ISO file. This contains the driver for the drive we’ll be installing Windows on.
--network bridge=br0
Which network interface to install on the VM.
--graphics vnc,listen=0.0.0.0,port=5904
Tell the VM what to do with graphics output. In this case we’ll send it through a VNC interface listening on any address (0.0.0.0) on port 5904. Check the man page for more options. 5900 is VNC’s default port but I’m already running something on that port so I’m specifying a different number.
--check all=off
Do not verify if the CD ROM is already in use by another VM.
Let’s kick off the installation and connect using your favourite VNC client. I used this one.
Connect VNC to your HOST’s IP address followed by the port you specified. The warning is because we didn’t specify a VNC password. That’s ok for now.
The Windows installer will inform you that there are no drives to install on and would like to add a driver?
Choose the virtio scsi driver. In my case the CD ROM ISO was mounted on e:.
Proceed as normal. At one point the installer will reboot and the connection will get lost. Reconnect and continue the installation.
Installing drivers and the guest agent
The guest agent facilitates communication between host and guest. Among other things this will make the VM shutdown gracefully when rebooting or shutting down the host.
After installation shut down the VM and do
# virsh edit W2K19
This will allow you to directly edit the VM’s definition in the form of an XML file. Look up the <devices> section and within it add this section:
<channel type='unix'> <source mode='bind' path='/var/lib/libvirt/qemu/win10.agent'/> <target type='virtio' name='org.qemu.guest_agent.0'/> <address type='virtio-serial' controller='0' bus='0' port='1'/> </channel>
The W2K19.agent part (second line) must be unique per server. Again, the path can be anything but if you deviate from this standard you must tell Apparmor about it. I suggest you stick to the path above.
Start the server:
# virsh start W2K19
In the VM start the Device Manager. Note there are two devices that lack drivers. Rightclick them, choose Update driver and have the wizard search e: and subfolders.
One is the virtio Balloon Drivers, which allows for memory thin provisioning. The other is the virto serial driver, which is used by the virtio guest agent to facilitate communication between host and guest.
Shut down the VM and restart it with
# virsh start W2K19
To test agent communication, do
# virsh qemu-agent-command W2K19 '{"execute":"guest-info"}'
This should result in quite a bit of information.
If communication cannot be established your will see “error: argument unsupported: QEMU guest agent is not configured”.
Non-related tips
- Use tmux, a terminal multiplexer like screen. It allows you to do more than one thing at a time on your terminal and is highly customizable.
- Use BgInfo to easily see which VM you are managing.
- Learn about KVM snapshots and backups.
“Look up the section and within it add this section:”
Looks like you forgot to specify ” section. Otherwise, very useful article.
Ah, I see. The blog engine has discarded the angular quotes. «devices»
So, to sum up my two previous comments, this part:
“Look up the section and within it add this section:”
should be:
“Look up the <devices> section and within it add this section:”
Please remove my previous comments.
Thanks!
BLDC hub motors are а typical trendy design.
Considering KVM is owned by Redhat their list of supported os’s is quite short, I’m just wondering if there is some unofficial list I’m not aware of that includes recent Windows.
Hi! I’ve been following your website for a while now and finally ggot the courage to ggo ahead
and give you a shout out from New Caney Tx! Just wanted to mention ksep up the goodd job!