Virtualization With KVM On Ubuntu 8.10 - Page 2

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
2008-12-10 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. Because we must modify the template, we create a copy and modify that one:

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

Now we open ~/vm1/mytemplates/libvirt/libvirtxml.tmpl...

vi ~/vm1/mytemplates/libvirt/libvirtxml.tmpl

... and change the network section from

[...]
    <interface type='network'>
      <source network='default'/>
    </interface>
[...]

to

[...]
    <interface type='bridge'>
      <source bridge='br0'/>
    </interface>
[...]

because we want the VM to use our network bridge.

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...

apt-get 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=intrepid --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

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).

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 2008-12-10 15:26 networks
-rw------- 1 root root  963 2008-12-10 16:25 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 402804
-rw-r--r-- 1 root root 240963584 2008-12-10 16:37 disk0.qcow2
-rw-r--r-- 1 root root 171094016 2008-12-10 16:37 disk1.qcow2
root@server1:~/vm1#

 

4 Creating A Second VM

If you want to create a second VM (vm2), here's a short summary of the commands:

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

vi ~/vm2/mytemplates/libvirt/libvirtxml.tmpl

vi ~/vm2/vmbuilder.partition

vi ~/vm2/boot.sh

cd ~/vm2/
vmbuilder kvm ubuntu --suite=intrepid --flavour=virtual --arch=amd64 --mirror=http://192.168.0.100:9999/ubuntu -o --libvirt=qemu:///system --tmpfs=- --ip=192.168.0.102 --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=vm2

(Please note that you don't have to create a new directory for the VM (~/vm2) if you pass the --dest=DESTDIR argument to the vmbuilder command - it allows you to create a VM in a directory where you've already created another VM. In that case you don't have to create new vmbuilder.partition and boot.sh files and don't have to modify the template, but can simply use the existing files:

cd ~/vm1/
vmbuilder kvm ubuntu --suite=intrepid --flavour=virtual --arch=amd64 --mirror=http://192.168.0.100:9999/ubuntu -o --libvirt=qemu:///system --tmpfs=- --ip=192.168.0.102 --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=vm2 --destdir=vm2-kvm

)

Share this page:

9 Comment(s)

Add comment

Comments

From: Jim Dennis at: 2009-05-16 21:45:47

 

The first problem I encountered while going through this HOWTO was in trying to follow the example for the configuration of br0 in the /etc/network/interfaces examples.

Like many readers my existing configuration was being managed by NetworkManager ... and is using DHCP.  Naturally my attempt to follow the example past this point (thinking I was creating a new virtual network and chosing an suitable RFC1918 block of static addresses to assign to that) left my system disconnected from the 'net.

It appears that all I needed to do was:

  1. Add an entry for eth0 identifying it as "inet manual" (presumably meaning: "managed by the bridge-utils").
  2. Replace all the static addressing directives in the example with  an "inet dhcp" entry for br0
     

The results look like:

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

iface   eth0    inet manual
        # managed by bridge-utils?

Perhaps adding an alternative for those on DHCP and a link to the best info we can find on bridge-utils would help.

 The best info I was able to find so far is at: LinuxFoundation: Net:Bridge. But I didn't have to dive far into it before I figured out what I was supposed to be doing by taking a closer look at the before and "after" examples.

 I hope the maintainer of this HOWTO will read this.

 

 

From: at: 2009-02-16 21:12:27

If virtualization does not show up after

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

 You may have to enable virtualization in the bios, I have found that this function is disabled by default in Dell servers and may also be in others.

From: Matt Mossholder at: 2009-03-06 02:40:35

Canonical recommends that you not use the following:

  • sudo su
  • sudo /bin/<insert shell here>
  • ...etc.

The recommended way of getting a root shell is:

sudo -i

 

    --Matt

 

From: Tom at: 2011-10-09 16:29:07

Nice article. Very good explanations.

There are a lot management tools will make KVM deployment much easier:
http://www.linux-kvm.org/page/Management_Tools

Since IBM and Redhat start to support KVM, many companies are deploying KVM cloud farms now.

From: Rainbof at: 2009-03-20 06:47:35

when you get

during creating the VM, following error appeared:

in file ~/vm1/mytemplates/libvirt/libvirtxml.tmpl must be this

<interface type='bridge'>
<source bridge='br0'/>
</interface>

The error from vmbuilder really should have been "No <source> 'bridge' attribute[...]".

From: Anonymous at: 2009-03-06 13:12:35

If you get an error like this:

  /proc/misc: No entry for device-mapper found

while running vmbuilder, you need to install the device mapper kernel module:

  modprobe dm_mod

 

From: Anonymous at: 2009-03-07 11:20:31

Great site ! and good tips.

Please include what the user has to type if the chipset is a i386.

--arch=i386

From: Seppe De Loore at: 2009-02-25 08:34:32

This is a great tutorial. Just had to iron out a small "bridge" error:

there seems to be an error in the vmbuiler documentation and the template ( mytemplates/libvirt/libvirtxml.tmpl) should be adapted to read:

<interface type='bridge'>
<source bridge='br0'/>
</interface>

 The interface type should also be changed to 'bridge' instead of network.

Further installing a more complete PERL (I added perl-debug) will remove the PERL error messages the vmbuilder script spawns.

Anyway, I got my KVM server running. Thank you.

From: Anonymous at: 2010-02-10 11:01:12

You can omit the config file entirely and instead use the command line option --bridge=br0