Feb. 22, 2011, 2:19 a.m.
posted by void
Create an Ubuntu/Xen Virtual Machine
Install Ubuntu into a virtual-machine image and boot it using Xen.
The previous hack showed you how to set up a Xen server [Hack #90]. To make use of your newly Xen-enabled host, you need to create some domU virtual machines to run on it. In this hack, you'll set up a basic Dapper virtual machine (VM).
Prepare VM Filesystems
The VM needs both root and swap filesystems. In a production environment, these would most likely be stored on some form of shared-access filesystem, such as a SAN or similar, but, to keep things simple, for now you should create them as loopback disk images on the local disk. So start by making a couple of directories to store them in:
$ sudo mkdir -p /vm/vm_base $ sudo mkdir /vm/images
The root filesystem will be a 2 GB image, so first use dd to create a disk image and then use mkfs to set up a filesystem in it. 2 GB should be enough space for initial testing, but if you want to vary the size, just change the count argument, which, when multiplied by the bs (block size) argument, determines the total disk size.
$ sudo dd if=/dev/zero of=/vm/images/vm_base.img bs=1024k count=2000 $ sudo mkfs.ext3 /vm/images/vm_base.img
You can create a 200 MB swap image in a similar way:
$ sudo dd if=/dev/zero of=/vm/images/vm_base-swap.img bs=1024k count=200 $ sudo mkswap /vm/images/vm_base-swap.img
Mount the root filesystem image
Mount the root filesystem image as a loopback device, allowing it to appear as a separate volume, even though it's only an image stored on the local disk:
$ sudo mount -o loop /vm/images/vm_base.img /vm/vm_base
Install Ubuntu into the Root Filesystem
Now you have the equivalent of a blank disk just waiting to have Linux installed on it. The system you install will become the domU virtual machine that is booted by Xen. Installing into a different volume can be a tricky exercise, but luckily Debian provides an extremely useful tool called debootstrap that takes care of all the hard work for you. First, grab debootstrap:
$ sudo apt-get install debootstrap
Then, use it to build a new Breezy base system into the root filesystem. The installation process has been radically overhauled for Dapper, so for now it's easier to install Breezy first and dist-upgrade to Dapper afterwards:
$ sudo debootstrap --arch i386 breezy /vm/vm_base/ \\ http://archive.ubuntu.com/ubuntu
The preceding example specifies the architecture as i386 (32-bit Intel). You may need to specify an alternative, such as powerpc or amd64, depending on your system architecture.
Running debootstrap can take quite a long time because it needs to download all the packages, and if you need to go through this process several times, you may want to set up a local package cache [Hack #61] or replace the mirror address with a reference to file:///media/cdrom and use an Ubuntu install CD. If you have a local apt-cacher running already, you can include the cache address like so:
$ sudo debootstrap --arch i386 breezy /vm/vm_base/ \\ http://localhost/apt-cacher/archive.ubuntu.com/ubuntu
Configure the Virtual Machine
$ sudo cp -a /etc/apt/sources.list /vm/vm_base/etc/apt/
Then edit /vm/vm_base/etc/apt/sources.list and change any references from dapper to breezy, since you are starting with a base Breezy install.
Now edit /vm/vm_base/etc/network/interfaces and set up the loopback address and a virtual eth0 interface. You will need to adjust these values to suit your own network. The address allocated to eth0 needs to be one that's not in use yet:
auto lo iface lo inet loopback address 127.0.0.1 netmask 255.0.0.0 auto eth0 iface eth0 inet static address 192.168.0.101 netmask 255.255.255.0 gateway 192.168.0.1
Edit /vm/vm_base/etc/hostname and set it to vm01.
Edit /vm/vm_base/etc/hosts and put in some basic entries:
127.0.0.1 localhost.localdomain localhost vm01 # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ff02::3 ip6-allhosts
The VM also needs to be given a filesystem configuration. Note that this is not necessarily the same as the configuration of the host, and the volume names have nothing to do with your actual local disk. The volumes that the VM will see when it starts up are virtual volumes that will be determined by the Xen configuration, so for now just edit /vm/vm_base/etc/fstab and set it up like this:
/dev/hda1 / ext3 defaults 1 2 /dev/hda5 none swap sw 0 0 /dev/pts devpts gid=5,mode=620 0 0 none /dev/shm tmpfs defaults 0 0
Run Setup Within the VM Image
$ sudo chroot /vm/vm_base
From now on, everything you do will be within the context of the VM, so you can manually invoke the tools that are normally run in the last stages of the regular Ubuntu installer. Make sure the universe repository [Hack #60] is enabled in sources.list (Breezy has a universe repository as well), and tell apt to update the package list and then set up locales:
# apt-get update # apt-get install localeconf # dpkg-reconfigure localeconf
You will then be asked a series of questions when the localeconf package is installed and then additional questions when you reconfigure it:
At this point, many of the standard devices don't exist and locale generation won't be working, so mount the proc virtual filesystem and create the default devices:
# mount -t proc proc /proc # cd /dev # ./MAKEDEV generic
When MAKEDEV finishes, run base-config to bootstrap the system:
base-config will ask you all the usual questions that you normally see when running the Ubuntu Breezy installer, so answer all the questions as normal, with one exception: when asked to specify an access method for apt, select "edit sources list by hand," which will then put you into the vim editor with the sources.list file open. Since it's already set up correctly, just type ZZ to save and exit vim, and let apt run through the process of verifying the repositories and installing all the base packages.
Once the Breezy installer has finished, edit the /etc/apt/sources.list again, and this time change all references from breezy to dapper. Then update the package list again and dist-upgrade to Dapper:
# apt-get update # apt-get dist-upgrade
You now have a basic Dapper install inside the loopback filesystem, so finally you can exit the chroot:
Get Ready to Crank Up the VM
The domU virtual machine will be booted using the Xen kernel installed on the dom0 host, so copy the kernel modules into its filesystem, disable TLS, and unmount the image:
$ sudo cp -dpR /lib/modules/126.96.36.199-xenU /vm/vm_base/lib/modules/ $ sudo mv /vm/vm_base/lib/tls /vm/vm_base/lib/tls.disabled $ sudo umount /vm/vm_base
It's quite likely that umount will complain that the device is busy even though nothing is using it anymore, so ignore the warning.
You now have one complete, functional domU virtual machine, but it's quite likely that you will ultimately want to create a few of them, so rather than boot the image you just created, it's best to treat it as a template and make copies of it to play with.
Copy the disk image to create a new VM:
$ sudo cp -a /vm/images/vm_base.img /vm/images/vm01.img $ sudo cp -a /vm/images/vm_base-swap.img /vm/images/vm01-swap.img
Configure the VM in Xen
$ sudo cp /etc/xen/xmexample1 /etc/xen/vm01.conf
The sample config file is very well commented, and most of the defaults are fine as a starting point, so open /etc/xen/vm01.conf in your favorite editor and start working through it. Highlights to pay attention to include:
Boot Your Virtual Machine
$ sudo xm create -c /etc/xen/vm01.conf
If all goes well, you will see Linux run through its boot sequence all the way up to a login prompt into your virtual machine. Log in as the user you created during the setup process and poke around. Try a few things like:
$ cat /proc/cpuinfo $ cat /proc/meminfo $ uname -r
It should look exactly as if you're in a totally separate machine, and the network interface will be functional, with packets bridged to the physical Ethernet through the kernel in the dom0 host so you can even apt-get install some packages or do whatever else you need to do to set up the virtual machine just the way you want it.
While your virtual machine is still running, open another terminal session onto the dom0 host and try running:
$ sudo xm list
to see a list of currently running guests. You can also view a dynamically updated list of hosts along with resource utilization:
$ sudo xm top
If you want to nicely bring down a VM without logging in to it, you can do so through xm:
$ sudo xm shutdown vm01
When you've finished playing around in your new VM, you can either shut it down from the dom0 host using xm or shut it down from inside just like any other machine using sudo shutdown.
Create Additional Guests
$ sudo cp -a /vm/images/vm_base.img /vm/images/vm02.img $ sudo cp -a /vm/images/vm_base-swap.img /vm/images/vm02-swap.img
Mount the base image:
$ sudo mount -o loop /vm/images/vm02.img /vm/vm_base
Edit /vm/vm_base/etc/network/interfaces, /vm/vm_base/etc/network/hostname, and /vm/vm_base/etc/network/hosts to set appropriate values for the hostname and IP address.
Unmount the base image:
$ sudo umount /vm/vm_base
Copy the Xen configuration:
$ sudo cp /etc/xen/vm01.conf /etc/xen/vm02.conf
Then edit it to change the paths to the disk images and the machine name, and you're ready to start up a second VM.