KVM Tutorial

To get started with KVM you need a machine, and you can use any flavor of Linux you like: but Ubuntu or a Debian derivative is the easiest to setup (in my preference) for the first time. So first off download the sources!

% wget -c http://kent.dl.sourceforge.net/sourceforge/kvm/kvm-77.tar.gz

# remember -c will continue an interrupted download handy to remember

You may be behind a proxy, so wget may not work, one thing to get around this is to:

% export http_proxy=”http://proxy:8080/”

The easiest way to install KVM I found is from source (Package Managers are using older version and sometimes don’t quite work right). So, you can check the KVM website for updates and links. Now lets untar the file

% tar zxvf kvm-77.tar.gz

Now we need to download the dependencies for this:

% apt-get install build-essential libsdl1.2-dev linux-headers-`uname -r` zlib1g-dev libncurses5-dev pkg-config libgnutls-dev libasound2-dev

% cd kvm-77
%./configure –prefix=/usr
% make
$ make install
$ /sbin/modprobe kvm
$ /sbin/modprobe kvm-intel
# Or: $/sbin/modprobe kvm-amd

Now Kvm should be installed you can check this by (this also returns the current kvm version):

$ dmesg | grep kvm

Setting up KVM/Qemu on another System like Suse or other wise may not be as simple as your host system needs to have a kvm kernel module installed so this may require you to compile to the latest kernel.

Virtual Disks

So to get started we need a virtual disk, simply to hold data like the virtual system’s OS.

$ mkdir virtual_disks #or some other location
$ cd virtual_disks
$ qemu-img create -f qcow2 <vdisk name>.img <size in GB>G

A useful command when you do alot of work with Virtual machines is:

$ qemu-img info <virtual disk img or host device>

Useful to know if you use format ‘raw’ you can mount this in your host system! Since it works like a file descriptor in /dev and you can point kvm to use the file descriptors in /dev so if you have access to a block device that isn’t your /root lol give it a try :)

When you specify the size, this won’t just create a file of size whatever you specified but it acts as a limit, but generally 8gb for home use will be fine. Well for a linux guest OS like debian anyways!

KVM – Start
So now we need to create the VM and start it to install the OS We do this by:

$ qemu-system-x86_64 -m 512 -cdrom /path/<OS you want to install>.iso -vnc :10 -hda <vdisk name>.img

notice the -vnc option, if you don’t supply this on your system an SDL window will come up with the same thing this requires an X server to be running on the server though. The Vnc option is more useful in that you could setup a virtual machine on a remote server and then go to a local machine and use VNC to set it all up. When you have the virtual machine running start another shell on your host system and do:

$  lsmod |  grep kvm
//this gave me the output of:
kvm_intel          53472 2
kvm              169632 1 kvm_intel
//this shows I was running 2 kvm virtual machines using kvm_intel module for hardware
acceleration

Or what you can do is in your virtual machine SDL/Vnc window is: ctrl-alt-2, to get to this qemu console and ctrl-alt-1 to get back to the virtual machine desktop in this console do info kvm to check kvm hardware acceleration is enabled. This is the basic setup of KVM/Qemu. There are a lot of advanced paravirtulisation features and networking features to take advantage of more on that later and ubuntu-vm-builder! If you have a dual boot of windows and linux one nice thing to test is this.. say you have them both on the same block device is probably the safest thing. What i do is

$ qemu -hda /dev/sda -net nic,macaddr=<> -net tap

pointing to the root block device and it should bring up your grub menu and you can choose windows like normal! But be careful you will need to add in options for networking and things to have a proper system. I do this to get access to some things at work like our interface communicator but thats it really evolution does a pretty good job at r/w to the exchange server! :)

Oh yeah you can also you block deivces instead of files for virtual machine hard disks! Which is cool!

KVM – Advanced Features – Paravirtualization ( virtio drivers )

-Hard-Drive

For SLES to make the virtual hard drive Para-virtualized to the guest system you will need to compile to a newer kernel some after (2.6.22 i think) i do it with 2.6.27 it contains the latest stable virtio etc, If your using ubuntu hardy (8.04+) in a guest OS you don’t need to do this step, as ubuntu puts in the kvm kernel module in their kernel now by default as well as virtio as modules also!

The Kernel Modules you need to make sure you compile are:

PARAVIRT_GUEST:
-> Processor type and features
-> Paravirtualized guest support
LGUEST_GUEST:
-> Processor type and features
-> Paravirtualized guest support
-> Lguest guest support
VIRTIO_PCI:
-> Virtualization (VIRTUALIZATION [=y])
-> PCI driver for virtio devices
VIRTIO_BLK:
-> Device Drivers
-> Block devices (BLK_DEV [=y])
-> Virtio block driver
VIRTIO_NET:
-> Device Drivers
-> Network device support (NETDEVICES [=y])
-> Virtio network driver

Once you have the new kernel in your guest system installed you need to:

Edit /boot/grub/device.map from “(hd0) /dev/hda” to “(hd0) /dev/vda”

Then on your qemu-system startup command for the virtual machine you need to append:

–drive file=<your_disk_image>,if=virtio

KVM – Extra Virtual CPU’s

With qemu it is possible for your guest virtual machine to have up to 255 virtual cpu’s which is the maximum the linux kernel can handle, but this isn’t so good with from what I have seen. KVM seems to support up to 16 virtual cpu’s. To enable this option you need you kernel to have the option for this by enabling SMP (Symetric Multiprocessing) in the guest kernel inside Processor Type and Features. Once this module is compiled in your guest kernel just append:

-smp n ( n = the number of processors )

QEMU – Memory Allocation

When specifying more than 3.2gb of ram for your virtual machine to use, this doesn’t seem to be picked up by the virtual machine in /proc/meminfo it still says 3.2gb – I am currently looking into this issue. This problem is due to the Host system running KVM is not running the Paravirtulised Guest Modules like KVM paravirtulised Clock and others. So you need to recompile your host’s kernel.

KVM Virtual Machine Migration

Two Identical machines, the virtual disk accessible to both machines, we done this via a local nfs share and mounted the nfs share to both machines via the /etc/fstab file. So next you have machine A and machine B both with access to this nfs share. So you will need to start the machine on A, let it start up and check it has network access. Next start the same virtual image with the exact same settings as A but append this line to the startup command:

-incoming tcp://0:4444 (or other PORT)

You will see the VM will just hang. So next on your vnc connection to Machine A do ctrl – alt – 2: You will see the qemu console and do:

migrate -d tcp://B:4444

Where B is the ip of the hypervisor There is also a Paravirtulised Network Interface virtio Driver this is much more complicated i only have this set up properly in a network bridge, and it only works in debian systems.

KVM virtio networks and Bridge Networking

First probably easiest is to do is, open up a text editor:

% emacs /etc/qemu-ifup

  1.  
  2. #!/bin/sh
  3. set -x
  4.  
  5. switch=br0
  6.  
  7. if [ -n "$1" ];then
  8.     /usr/bin/sudo /usr/sbin/tunctl -u `whoami` -t $1
  9.     /usr/bin/sudo /sbin/ip link set $1 up
  10.     sleep 0.5s
  11.     /usr/bin/sudo /usr/sbin/brctl addif $switch $1
  12.     exit 0
  13. else
  14.     echo "Error: no interface specified"
  15.     exit 1
  16. fi
  17.  

Put this script into /etc/qemu-ifup which handles all networking for the guest

chmod 755 /etc/qemu-ifup
chown …
chmod +x /etc/qemu-ifup

You need to setup and br0 eth device which is a network bridge: emacs /etc/network/interfaces

auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp

auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_fd 9
bridge_hello 2
bridge_maxage 12
bridge_stp off

% apt-get install bridge-utils

% /etc/init.d/networking restart

Now you should have eth0 as a bridge and eth0 wont have an ip but br0 does. Even better if you have 2 network cards you could bridge eth0/eth1 and leave the other normal :) Now your guest systems should start and get a uniqe ip instead of the internal NAT address, this is better for a proper standalone system as its seen to be a more complete system with its own ip :) And you can follow this wiki for virtio network i have only had it working in Debian systems properly it kind of works in SLES but hey Debian and ubuntu Rock! :D

http://kvm.qumranet.com/kvmwiki/Using_VirtIO_NIC