Virtualization With KVM On Ubuntu 9.10

Want to support HowtoForge? Become a subscriber!
 
Submitted by falko (Contact Author) (Forums) on Thu, 2009-12-17 17:56. :: KVM | Ubuntu | Virtualization

Virtualization With KVM On Ubuntu 9.10

Version 1.0
Author: Falko Timme <ft [at] falkotimme [dot] com>
Follow me on Twitter
Last edited 12/16/2009

This guide explans how you can install and use KVM for creating and running virtual machines on an Ubuntu 9.10 server. I will show how to create image-based virtual machines and also virtual machines that use a logical volume (LVM). KVM is short for Kernel-based Virtual Machine and makes use of hardware virtualization, i.e., you need a CPU that supports hardware virtualization, e.g. Intel VT or AMD-V.

I do not issue any guarantee that this will work for you!

 

1 Preliminary Note

I'm using a machine with the hostname server1.example.com and the IP address 192.168.0.100 here as my KVM host.

Because we will run all the steps from this tutorial with root privileges, we can either prepend all commands in this tutorial with the string sudo, or we become root right now by typing

sudo su

 

2 Installing KVM And vmbuilder

First check if your CPU supports hardware virtualization - if this is the case, the command

egrep '(vmx|svm)' --color=always /proc/cpuinfo

should display something, e.g. like this:

root@server1:~# egrep '(vmx|svm)' --color=always /proc/cpuinfo
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext
 fxsr_opt rdtscp lm 3dnowext 3dnow rep_good nopl pni cx16 lahf_lm cmp_legacy svm extapic cr8_legacy 3dnowprefetch
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext
 fxsr_opt rdtscp lm 3dnowext 3dnow rep_good nopl pni cx16 lahf_lm cmp_legacy svm extapic cr8_legacy 3dnowprefetch
root@server1:~#

If nothing is displayed, then your processor doesn't support hardware virtualization, and you must stop here.

To install KVM and vmbuilder (a script to create Ubuntu-based virtual machines), we run

aptitude install ubuntu-virt-server python-vm-builder

General type of mail configuration: <-- Internet Site
System mail name: <-- server1.example.com

Afterwards we must add the user as which we're currently logged in (root) to the group libvirtd:

adduser `id -un` libvirtd

You need to log out and log back in for the new group membership to take effect.

To check if KVM has successfully been installed, run

virsh -c qemu:///system list

It should display something like this:

root@server1:~# virsh -c qemu:///system list
Connecting to uri: qemu:///system
 Id Name                 State
----------------------------------

root@server1:~#

If it displays an error instead, then something went wrong.

Next we need to set up a network bridge on our server so that our virtual machines can be accessed from other hosts as if they were physical systems in the network.

To do this, we install the package bridge-utils...

aptitude install bridge-utils

... and configure a bridge. Open /etc/network/interfaces:

vi /etc/network/interfaces

Before the modification, my file looks as follows:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static
        address 192.168.0.100
        netmask 255.255.255.0
        network 192.168.0.0
        broadcast 192.168.0.255
        gateway 192.168.0.1

I change it so that it looks like this:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet manual

auto br0
iface br0 inet static
        address 192.168.0.100
        network 192.168.0.0
        netmask 255.255.255.0
        broadcast 192.168.0.255
        gateway 192.168.0.1
        bridge_ports eth0
        bridge_fd 9
        bridge_hello 2
        bridge_maxage 12
        bridge_stp off

(Make sure you use the correct settings for your network!)

Restart the network...

/etc/init.d/networking restart

... and run

ifconfig

It should now show the network bridge (br0):

root@server1:~# ifconfig
br0       Link encap:Ethernet  HWaddr 00:1e:90:f3:f0:02
          inet addr:192.168.0.100  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::21e:90ff:fef3:f002/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:14 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1046 (1.0 KB)  TX bytes:1560 (1.5 KB)

eth0      Link encap:Ethernet  HWaddr 00:1e:90:f3:f0:02
          inet6 addr: fe80::21e:90ff:fef3:f002/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:21971 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11749 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:32162163 (32.1 MB)  TX bytes:948375 (948.3 KB)
          Interrupt:28 Base address:0x8000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

virbr0    Link encap:Ethernet  HWaddr 72:64:57:c0:b0:03
          inet addr:192.168.122.1  Bcast:192.168.122.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

root@server1:~#

 

3 Creating An Image-Based VM

We can now create our first VM - an image-based VM (if you expect lots of traffic and many read- and write operations for that VM, use an LVM-based VM instead as shown in chapter 6 - image-based VMs are heavy on hard disk IO).

We will create a new directory for each VM that we want to create, e.g. ~/vm1, ~/vm2, ~/vm3, and so on, because each VM will have a subdirectory called ubuntu-kvm, and obviously there can be just one such directory in ~/vm1, for example. If you try to create a second VM in ~/vm1, for example, you will get an error message saying ubuntu-kvm already exists (unless you run vmbuilder with the --dest=DESTDIR argument):

root@server1:~/vm1# vmbuilder kvm ubuntu -c vm2.cfg
2009-05-07 16:32:44,185 INFO     Cleaning up
ubuntu-kvm already exists
root@server1:~/vm1#

We will use the vmbuilder tool to create VMs. (You can learn more about vmbuilder here.) vmbuilder uses a template to create virtual machines - this template is located in the /etc/vmbuilder/libvirt/ directory. First we create a copy:

mkdir -p ~/vm1/mytemplates/libvirt
cp /etc/vmbuilder/libvirt/* ~/vm1/mytemplates/libvirt/

Now we come to the partitioning of our VM. We create a file called vmbuilder.partition...

vi ~/vm1/vmbuilder.partition

... and define the desired partitions as follows:

root 8000
swap 4000
---
/var 20000

This defines a root partition (/) with a size of 8000MB, a swap partition of 4000MB, and a /var partition of 20000MB. The --- line makes that the following partition (/var in this example) is on a separate disk image (i.e., this would create two disk images, one for root and swap and one for /var). Of course, you are free to define whatever partitions you like (as long as you also define root and swap), and of course, they can be in just one disk image - this is just an example.

I want to install openssh-server in the VM. To make sure that each VM gets a unique OpenSSH key, we cannot install openssh-server when we create the VM. Therefore we create a script called boot.sh that will be executed when the VM is booted for the first time. It will install openssh-server (with a unique key) and also force the user (I will use the default username administrator for my VMs together with the default password howtoforge) to change the password when he logs in for the first time:

vi ~/vm1/boot.sh

# This script will run the first time the virtual machine boots
# It is ran as root.

# Expire the user account
passwd -e administrator

# Install openssh-server
apt-get update
apt-get install -qqy --force-yes openssh-server

Make sure you replace the username administrator with your default login name.

(You can find more about this here: https://help.ubuntu.com/community/JeOSVMBuilder#First%20boot)

(You can also define a "first login" script as described here: https://help.ubuntu.com/community/JeOSVMBuilder#First%20login)

Whenever vmbuilder builds a new VM, it has to download all packages from an Ubuntu mirror which can take quite some time. To speed this up, we install apt-proxy...

aptitude install apt-proxy

... to cache the downloaded packages so that subsequent VM installations will be a lot faster.

Now open /etc/apt-proxy/apt-proxy-v2.conf...

vi /etc/apt-proxy/apt-proxy-v2.conf

... and replace the default Ubuntu mirror with a mirror close to you (e.g. http://de.archive.ubuntu.com/ubuntu if you are in Germany):

[...]
[ubuntu]
;; Ubuntu archive
backends = http://de.archive.ubuntu.com/ubuntu
min_refresh_delay = 15m
[...]

Then we restart apt-proxy:

/etc/init.d/apt-proxy restart

apt-proxy listens on port 9999, so we can pass our local apt-proxy "mirror" as an argument to the vmbuilder script.

Now take a look at

vmbuilder kvm ubuntu --help

to learn about the available options.

To create our first VM, vm1, we go to the VM directory...

cd ~/vm1/

... and run vmbuilder, e.g. as follows:

vmbuilder kvm ubuntu --suite=karmic --flavour=virtual --arch=amd64 --mirror=http://192.168.0.100:9999/ubuntu -o --libvirt=qemu:///system --tmpfs=- --ip=192.168.0.101 --part=vmbuilder.partition --templates=mytemplates --user=administrator --name=Administrator --pass=howtoforge --addpkg=vim-nox --addpkg=unattended-upgrades --addpkg=acpid --firstboot=boot.sh --mem=256 --hostname=vm1 --bridge=br0

Most of the options are self-explanatory. --part specifies the file with the partitioning details, relative to our working directory (that's why we had to go to our VM directory before running vmbuilder), --templates specifies the directory that holds the template file (again relative to our working directory), and --firstboot specifies the firstboot script. --libvirt=qemu:///system tells KVM to add this VM to the list of available virtual machines. --addpkg allows you to specify Ubuntu packages that you want to have installed during the VM creation (see above why you shouldn't add openssh-server to that list and use the firstboot script instead). --bridge sets up a bridged network; as we have created the bridge br0 in chapter 2, we specify that bridge here.

In the --mirror line I have specified my local apt-proxy mirror (http://192.168.0.100:9999/ubuntu) - I have used my publically accessible IP address instead of localhost or 127.0.0.1 because this mirror will be used in the VM's /etc/apt/sources.list file as well, and of course, the VM won't be able to connect to 127.0.0.1 on the host. Of course, you can as well specify an official Ubuntu repository in --mirror, e.g. http://de.archive.ubuntu.com/ubuntu. If you leave out --mirror, then the default Ubuntu repository (http://archive.ubuntu.com/ubuntu) will be used.

The build process can take a few minutes.

Afterwards, you can find an XML configuration file for the VM in /etc/libvirt/qemu/ (=> /etc/libvirt/qemu/vm1.xml):

ls -l /etc/libvirt/qemu/

root@server1:~/vm1# ls -l /etc/libvirt/qemu/
total 8
drwxr-xr-x 3 root root 4096 2009-12-16 15:34 networks
-rw------- 1 root root 1111 2009-12-16 15:49 vm1.xml
root@server1:~/vm1#

The disk images are located in the ubuntu-kvm/ subdirectory of our VM directory:

ls -l ~/vm1/ubuntu-kvm/

root@server1:~/vm1# ls -l ~/vm1/ubuntu-kvm/
total 418072
-rw-r--r-- 1 root root 336068608 2009-12-16 15:48 disk0.qcow2
-rw-r--r-- 1 root root  92274688 2009-12-16 15:49 disk1.qcow2
root@server1:~/vm1#


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by Rudolf Leitgeb (not registered) on Tue, 2010-05-11 10:51.

Under Ubuntu Lucid Lynx the vmbuilder command became a little bit more finicky with its command line arguments. It no longer supports the --tmpfs option and the --firstboot option only works without the = sign.

 

The command line must now look like this to work:

 vmbuilder kvm ubuntu --suite=karmic --flavour=virtual --arch=amd64 --mirror=http://192.168.0.100:9999/ubuntu -o --libvirt=qemu:///system --ip=192.168.0.101 --part=vmbuilder.partition --templates=mytemplates --user=administrator --name=Administrator --pass=howtoforge --addpkg=vim-nox --addpkg=unattended-upgrades --addpkg=acpid --firstboot boot.sh --mem=256 --hostname=vm1 --bridge=br0

 

Note the absent = sign between --firstboot and boot.sh and the absent option --tmpfs

Submitted by valter (registered user) on Wed, 2009-12-23 12:45.
KVM is short for Keyboard, Video and Mouse and is hardware device.
Submitted by phubert (not registered) on Wed, 2009-12-30 08:25.

The dual-use of acronyms is widespread, especially considering the different disciplines that make use of them. But, to have the same acronym found within the same discipline shouldn't be too surprising, either, considering that technology continues to advance, hence the potential application for new acronyms continues to increase.

 In this case, both acronyms (one hardware one software) both simply make sense. So we understand by the context! Languages are even worse, by the way!

Submitted by nutznboltz (not registered) on Thu, 2009-12-24 17:07.

Yes, regrettably, the selection of "KVM" to mean "Kernel Virtual Machine" was done without regard to the prevalence of KVM's use as an acronym of "Keyboard, Video, Mouse".