Rails, Firefox, Anime, Mac
These instructions have been tested on Ubuntu 9.10 (Karmic) 64-bit. Skip right to the instructions if you’re short on time.
After being a happy Xen user for several years now, I’ve recently had to switch to an alternative virtualization solution. My colleague Arun (@iamclovin) actually struggled for a week with Xen VMs that locked up on Hardy; we’ve had much success with Hardy and Xen before, so we attributed it to a hardware problem since these were our first blade servers.
Out of ideas, we tried Karmic (Ubuntu 9.10) only to discover that Xen support via the apt package system is gone. I went down the path of compiling a paravirt_ops Dom0 kernel (this article was very useful) but ended up deciding the process took far too long despite being successful.
With KVM gaining official support from Ubuntu as the virtualization solution, I ended up ditching Xen and switching to KVM for these new servers on Karmic. The rest of the entry is a step-by-step guide on setting up KVM VMs on a Ubuntu server; I’m putting this down because like all wikis, the Ubuntu KVM wiki has grown a little too organically to be useful.
aptitude update && aptitude dist-upgrade
egrep '(vmx|svm)' --color=always /proc/cpuinfo
You should see lines with either “vmx” or “svm” highlighted.
aptitude install kvm libvirt-bin ubuntu-vm-builder bridge-utils
If you see a FATAL: Error inserting kvm_intel message during installation, it means that virtualization is not enabled in your machine’s BIOS. You’ll need to reboot your machine, enter the BIOS setup and enable virtualization (you’ll have to hunt for the option).

After enabling virtualization in the BIOS and rebooting, run:
modprobe kvm-intel
There should be no error shown (in fact, no console response).
aptitude install virt-top
virsh -c qemu:///system list
You should see something like this:
Connecting to uri: qemu:///system
Id Name State
----------------------------------
/etc/network/interfaces so it looks like this (use your own IPs):
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet manual
auto br0
iface br0 inet static
address 192.168.1.222
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.167
bridge_ports eth0
bridge_stp off
bridge_fd 9
bridge_hello 2
bridge_maxage 12
bridge_maxwait 0
/etc/init.d/networking restart
ifconfig. You should see 2 entries like these:
br0 Link encap:Ethernet HWaddr 00:11:22:33:44:55
inet addr:192.168.1.215 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::223:aeff:fefe:1f14/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1099 errors:0 dropped:0 overruns:0 frame:0
TX packets:50 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:74665 (74.6 KB) TX bytes:6223 (6.2 KB)
eth0 Link encap:Ethernet HWaddr 00:66:77:88:99:00
inet6 addr: fe80::223:aeff:fefe:1f14/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4939 errors:0 dropped:0 overruns:0 frame:0
TX packets:39 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:532798 (532.7 KB) TX bytes:5585 (5.5 KB)
Interrupt:36 Memory:da000000-da012800
vmbuilder:
vmbuilder kvm ubuntu \
-v \
--suite=karmic \
--libvirt=qemu:///system \
--arch=amd64 \
--cpus=2 \
--mem=2048 \
--swapsize=4096 \
--rootsize=20480 \
--flavour=server \
--hostname=billiejean \
--ip=192.168.1.240 \
--mask=255.255.255.0 \
--net=192.168.1.0 \
--bcast=192.168.1.255 \
--gw=192.168.1.167 \
--dns='202.157.163.157 202.157.131.118' \
--bridge=br0 \
--mirror=http://archive.ubuntu.com/ubuntu \
--components='main,universe' \
--addpkg=openssh-server \
--user=administrator \
--pass=icanhaspasswd \
--dest=/root/vm-billiejean \
--tmpfs=-
The options you need to care about are:
suite: Version of Ubuntu to install (e.g. karmic, hardy).cpus: Number of CPUs to assign to VM.mem: Amount of RAM in MB to assign to VM.swapsize: Size of swap in MB of VM.rootsize: Size of root filesystem in MB of VM.flavour: The “flavour” of kernel to use in the VM. Either “virtual” or “server”.hostname: Hostname of VM.ip: IP address of VM.mask: Netmask of VM.net: Network of VM.bcast: Broadcast address of VM.gw: Gateway of VM.dns: DNS server(s) for VM.addpkg: APT packages to install in the VM. openssh-server is needed so that we can login to the VM to setup the virsh console.user and pass: User account that’s setup for you to access the VM.dest: Destination directory on server where VM disk image will reside./etc/libvirt/qemu/ (e.g. /etc/libvirt/qemu/billiejean.xml), and a disk image in the directory specified in the --dest option (e.g. /root/vm-billiejean/disk0.qcow2).
virsh start billiejean
Now, we have the VM setup but it’s running off a disk image. For better performance, running the VM off a LVM logical volume will optimize disk IO.
vmbuilder is supposed to support the --raw option to write the VM to a block device (such as a LVM logical volume), but I’ve had no success with it (as does Mark Imbriaco, sysadmin of 37signals: http://twitter.com/markimbriaco/status/7437688341 and http://twitter.com/markimbriaco/status/7437699338). We’re going to convert the disk images using qemu-img and write the bits into a LVM logical volume instead.
virsh shutdown billiejean
qemu-img convert disk0.qcow2 -O raw disk0.raw
lvcreate -L24GB -n <logical_volume_name> <volume_group_name>
dd if=disk0.raw of=/dev/<volume_group_name>/<logical_volume_name> bs=1M
This will take awhile (the bigger your image, the longer it takes).
virsh edit billiejean
Change <disk> to point to the logical volume:
<disk type='block' device='disk'>
<source dev='/dev/<volume_group_name>/<logical_volume_name>'/>
<target dev='hda' bus='ide'/>
</disk>
disk0.qcow2 image first just to make sure your VM isn’t still using it.Now, we have to setup the VM so that virsh console works. This is a console to the VM from the host server that works even when the networking in the VM is not.
virsh edit billiejean
In the <devices> block, add:
<serial type='pty'>
<target port='0'/>
</serial>
virsh start billiejean
/etc/init/ttyS0.conf:
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
respawn
exec /sbin/getty -8 38400 ttyS0 vt102
Start the tty with:
start ttyS0
aptitude install acpid
virsh console billiejean
You may have to hit “Enter” before you see any console output.
That’s it, your VM is ready! You’ll probably want to do these:
vmbuilder.dpkg-reconfigure tzdata.Copyright (c) 2003-2010 redemption in a blog
Heavily modified Compositio Theme created by: Design Disease brought to you by PremiumThemes.com
5 Responses to Setting up virtualization on Ubuntu with KVM
Links 2/2/2010: Oracle/Sun Analysis | Boycott Novell
February 3rd, 2010 at 12pm
[...] Setting up virtualization on Ubuntu with KVM [...]
Tim
February 3rd, 2010 at 5pm
Thanks for the great & very detailed tutorial!
Raghu
March 1st, 2010 at 11am
Thanks for writing up a concise tutorial.
I needed to add –libvirt=qemu:///system option to the vmbuilder command for having the VMs XML conf file created in /etc/libvirt/qemu directory and registered with virsh.
Benedikt
March 6th, 2010 at 7am
Hey,
thanks for the part “Getting a console to your VM from the Host Server”, I’d have preferred a solution where you don’t need to change anything on the vm but at least it works now. Again, thanks.
B
JohnP
March 12th, 2010 at 7am
Many of us prefer to avoid the complexities of LVM2, but are unhappy with the performance of qcow2 file systems. In my experience, the qcow2 files require about 25% of a dual core while just running without a login.
By converting from qcow2 into an img/raw format, the performance drops to less than 1% as shown in virtual machine manager. I made no other changes. After the conversion, I had to “define” the VM again for the changes to be picked up.
$ sudo vi /etc/libvirt/qemu/vm1.xml and change the file names. No other changes were required.
$ sudo virsh define /etc/libvirt/qemu/vm1.xml
I’ve also elected to migrate from Xen to KVM. Getting KVM performance similar to Xen is an ongoing challenge.
A quick search for the flavours returned nothing useful. Does anyone know exactly what the differences are between “server” and “virtual” flavours?