QEMU+KVM - Tutorial
Overview
QEMU
- https://de.slideshare.net/ChiaweiWang3/qemu-introduction
- ISA: Instruction Set Architecture
- Virtualization:Emulation = (Host ISA = GuestISA):(Host ISA can be differ from Guest ISA)
- QEMU stands for Quick EMUlator.
- Guest ISA -> TCG (Tiny Code Generator, IR code) -> Host ISA
- Code-Block based Translation -> effective (not one to one translation)
- Translation Block cache is also the reason QEMU is “fast”.
- QEMU process memory: https://wiki.xenproject.org/wiki/Weekly-report:20170227-20170305
KVM
- https://searchservervirtualization.techtarget.com/feature/Whats-the-difference-between-Type-1-and-Type-2-hypervisors
- https://www.how2shout.com/linux/how-to-install-qemu-kvm-and-virt-manager-gui-on-ubuntu-20-04-lts/
- KVM stands for Kernel Virtual Machine.
- Type1 hypervisor and Type2 hypervisor.
- Type1 hypervisor runs directly on the host machines physical hardware.
- where type2 hypervisor typically is installed on top of an existing OS (hosted hypervisor).
- KVM is a virtualization module that can be installed in any Linux kernel, and allow it to function as a type 1 hypervisor.
- To managed KVM, command line is default. but we enable graphically with Virt-Manager (Virtual-Machine Manager).
- KVM runs as a backend of QEMU to speed-up.
https://wiki.ubuntuusers.de/QEMU/ <- need to check
Hands-on
Install
Install QEMU/KVM on Ubuntu20.04:
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils
Install Virt-Manager GUI:
sudo apt install -y virt-manager
I restart machine here. About the issue, refer to the appendix.
Create VM
- Download ISO file.
- Run Virtual Machine Manager.
- Create VM.
Network
The default network was NAT “Virtual Network ‘default’: NAT”
On host machine:
$ ip a
...
2: wlp0s20f3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 18:cc:18:98:3e:1a brd ff:ff:ff:ff:ff:ff
inet 192.168.0.30/24 brd 192.168.0.255 scope global dynamic noprefixroute wlp0s20f3
valid_lft 602149sec preferred_lft 602149sec
inet6 fe80::9d2f:a94f:4cdd:621e/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 52:54:00:3e:16:ed brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
...
$ ip route
...
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
The network of guest machine was configured by DHCP.
On the gust machine:
$ ip a
...
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:5e:d0:a3 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.232/24 brd 192.168.122.255 scope global dynamic enp1s0
valid_lft 3531sec preferred_lft 3531sec
inet6 fe80::5054:ff:fe5e:d0a3/64 scope link
valid_lft forever preferred_lft forever
$ ip route
default via 192.168.122.1 dev enp1s0 proto dhcp src 192.168.122.232 metric 100
192.168.122.0/24 dev enp1s0 proto kernel scope link src 192.168.122.232
192.168.122.1 dev enp1s0 proto dhcp scope link src 192.168.122.232 metric 100
you can ssh from host to 192.168.122.232
Even you close the window, VM runs at background.
route from guest
$ tracepath -n www.google.com
1?: [LOCALHOST] pmtu 1500
1: 192.168.122.1 0.177ms
1: 192.168.122.1 0.150ms
2: 192.168.0.1 4.348ms
3: {{ my_global_IP }} 15.625ms
create new vm vm2 difference is localip 122.231.
Memo
- Default location of images (storages):
/var/lib/libvirt/images/
- The name of image is
{{ Name_of_your_image }}.qcow2
. qcow
stands for “QEMU Copy-On-Write”.
QEMU CLI snippets
$ qemu-img check myimage.qcow2
No errors were found on the image.
240813/1600000 = 15.05% allocated, 87.23% fragmented, 86.00% compressed clusters
Image end offset: 6347948032
$ qemu-system-x86_64 -h
QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.18)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
usage: qemu-system-x86_64 [options] [disk_image]
'disk_image' is a raw hard disk image for IDE hard disk 0
Standard options:
-h or -help display this help and exit
-version display version information and exit
....
https://drewdevault.com/2018/09/10/Getting-started-with-qemu.html
$ curl -O https://nl.alpinelinux.org/alpine/v3.8/releases/x86_64/alpine-standard-3.8.0-x86_64.iso
$ qemu-img create -f qcow2 alpine.qcow2 16G
$ qemu-system-x86_64 \
-enable-kvm \
-m 2048 \
-nic user,model=virtio \
-drive file=alpine.qcow2,media=disk,if=virtio \
-cdrom alpine-standard-3.8.0-x86_64.iso \
-display gtk
But, there was no internet connection in the VM…
I deleted -nic
option (copied from VMM), but in this case, it returned coredump
$ qemu-system-x86_64 \
> -enable-kvm \
> -m 2048 \
> -netdev tap,fd=33,id=hostnet0,vhost=on,vhostfd=34 \
> -drive file=alpine.qcow2,media=disk,if=virtio \
> -cdrom alpine-standard-3.8.0-x86_64.iso \
> -display gtk
qemu-system-x86_64: /build/qemu-A1914X/qemu-4.2/util/oslib-posix.c:247: qemu_set_nonblock: Assertion `f != -1' failed.
Aborted (core dumped)
bridge https://qemu-discuss.nongnu.narkive.com/rNgxmrbk/missing-bridge-conf
sudo qemu-system-x86_64 \
-enable-kvm \
-m 2048 \
-net bridge,br=virbr0 -net nic,model=virtio \
-drive file=alpine.qcow2,media=disk,if=virtio \
-cdrom alpine-standard-3.8.0-x86_64.iso \
-display gtk
And, it works!
sudo qemu-system-x86_64 -machine type=pc,accel=kvm -name mytest -m 4096M -drive file=myimage.qcow2 -nographic -vnc none,ipv4 -device virtio-net,netdev=user.0 -netdev user,id=user.0,hostfwd=tcp::58888-:22 -snapshot -enable-kvm -cpu host
(Deprecated) Export QEMU command arguments to Virsh Domain XML
According to the RedHat:
But, domxml-from-native
command was deprecated.
https://stackoverflow.com/questions/58938125/qemu-native-to-libvirt-xml
Troubleshootings
After apt install command
The reason I rebooted my machine is, it returns the error as follows when I tried to run Virtual Machine Manager.
Unable to connect to libvirt qemu:///system.
Verify that the 'libvirtd' daemon is running.
Libvirt URI is: qemu:///system
Traceback (most recent call last):
File "/usr/share/virt-manager/virtManager/connection.py", line 956, in _do_open
self._backend.open(connectauth.creds_dialog, self)
File "/usr/share/virt-manager/virtinst/connection.py", line 172, in open
conn = libvirt.openAuth(self._open_uri,
File "/usr/lib/python3/dist-packages/libvirt.py", line 104, in openAuth
if ret is None:raise libvirtError('virConnectOpenAuth() failed')
libvirt.libvirtError: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied
-snap
option
Temporary snapshot in qemu (-snapshot)
https://programmer.ink/think/temporary-snapshot-in-qemu-snapshot.html
It is found that it was actually unlinked at open time, unlink was deleted from the file system but not from the disk file.This is a security consideration for QEMU.
In this post, he/she referred the QEMU code base.
https://github.com/qemu/qemu/blob/871c71b1bad2d2647641500603a2236869135c7f/block.c#L831
He/She tracked the file descriptor of the QEMU process and found deleted file.
qemu-img
command takes several options and the value of them are file names.
If we want to take a snapshot of a QEMU image which is running with -snapshot
option, we should first find the way to put this temporary file back to host’s file system.