Virtualization The Linux OSS Way
Virtualization The Linux OSS Way
dpkg will complain about missing dependencies. You can ignore most of them, but you will
need to satisfy the non-GUI dependencies to have full functionality. Subsequent to this, you
will find that when you need to install or upgrade packages via the apt utility, it will complain
about broken dependencies and refuse to do anything until you resolve the problem. I get
around this by taking down all the virtual machines on a host, bringing up the essential ones
on another host, uninstalling the virtualbox package, performing my upgrades or installs, and
then re-installing. It's an extra step and takes a few minutes, but on your production
virtualization hosts, this probably isn't something you will be doing terribly often, as it should
have a minimum of required packages to start with:
dpgk -r VirtualBox-3.0.14
apt-get update
apt-get upgrade
dpkg -i --force-depends \
virtualbox-3.0_3.0.14-58977_Ubuntu_karmic_amd64.deb
Once things are installed, everything is exposed via the command line. In fact, the GUI is only
a subset of what is available via the CLI. Currently, configuring port forwarding and the use of
the built-in iSCSI initiator are possible only via the CLI (not via the GUI). Try typing this in and
pressing Enter for some undocumented goodness that has saved me many hours and
headaches:
VBoxManage internalcommands
The usage information available by typing partial commands is exhaustive, and the
comprehensive nature of what is available allows for many custom and time-saving scripts.
I've scripted all the repetitive things I do, from creating new VMs to bouncing ones that
become troublesome after a month or so of uptime. Not only can you shell script, but there
also is a Python interface to VirtualBox, and the example script, vboxshell.py, ships with the
standard distribution.
A few notes on efficiency and performance—you'll do well to set up a “template” virtual
machine installation of your various operating systems that has your environment's
configurations for authentication, logging, networking and any other commonalities
necessary. You'd also need to throw in your performance enhancements, like for instance,
adding divider=10 to the GRUB kernel configuration, resulting in a line like this:
kernel /vmlinuz-2.6.18-164.el5 ro \
root=/dev/VolGroup01/LogVol00 rhgb quiet divider=10
This will require some experimentation in your environment, but most systems are set to a
1,000Hz clock cycle. Even on a host with idle guest systems, the number of context switches
that occur simply to check for interrupts can result in high load on the host. This boot-time
parameter will divide the clock frequency by ten, reducing the number of context switches by
a factor of ten as well, and reducing host load greatly. This might not be suitable for all
workload types, but running it on the guests for which it does not produce unacceptable
performance will speed up the system overall and most of your guests.
Consider the example script in Listing 1. Like most of the scripts I write, it's quick and dirty, but
if you follow this example, you'll have a basic infrastructure in place that you can use to
provision and manipulate an almost unlimited number of virtual servers quickly. It takes no
variables or input on the command line, supplying the information internally, but it easily
could be modified to allow passing parameters via command-line switches. Let's say you need
to bring up many virtual machines based on your base disk image. You will give the virtual
machines sequential IPs and hostnames. The example script has a few prerequisites you'll have
to satisfy. First, the disk image you are starting with must be a fixed size, not dynamically
allocated. If you have a dynamic .vdi you want to use, first convert it using clonehd:
VBoxManage clonehd dynfile.vdi statfile.vdi --variant Fixed
Next, you'll need the mount_vdi script (see Resources), which is quite handy in itself, as it
mounts the .vdi file as if it were an .iso or raw disk image. And, you'll need to be able to
execute it via sudo to create and mount loopback devices. I have edited the mount_vdi.sh
script to comment out the lines telling you to type end to unmount and exit the script, and
the last few lines of the script that actually do so, moving those functions into the top-level
script. You'll need to do likewise for the script in Listing 1 to work. Once you've tested the
mount_vdi.sh script, change the path to it in the script in Listing 1 to the appropriate one on
your host system.
Assumptions made for the purposes of this particular script include the following: you are
running a fairly recent Ubuntu as host and guest with VirtualBox 3.0.x (what I run in
production); the .vdis are in the current working directory where the script is located; there are
no loop devices (/dev/loopx) on the system already; the root partition is the first one on the
virtual disk; the hostname on the base vdi image is basicsys.example.com; it has one Ethernet
interface, and the IP address is 1.1.1.1 with a default gateway of 1.1.1.2. The script will be less
painful, especially during testing, if you set up your virtualbox user to have password-less
sudo, at least temporarily. I've tested the script now on several systems and with slight
variations in .vdi age and format, so I'm reasonably confident it will work for a wide variety of
environments. Be warned; I have found that VirtualBox 3.2.x, which I am now testing, requires
a few changes. Should you run into trouble and solve it, drop me an e-mail at the address in
my bio, and let me know, so I can improve the script for future generations.
Listing 1. Script to Create Multiple VMs
#! /bin/bash
# A quick and dirty script to create multiple virtual machines,
# give them unique hostnames and IP addresses, and culminate in
# bringing them on-line.
counter=1
while [ $counter -le $number ]
do
echo $basename$counter $basename$counter.vdi \
$IPnetwork$baseIP $memory
VBoxManage clonehd `pwd`/base.vdi \
`pwd`/$basename$counter.vdi --variant Fixed
sudo mount_vdi/mount_vdi.sh $basename$counter.vdi $rootdir 1
sudo sed -i "s/basicsys/$basename$counter/g" $rootdir/etc/hosts
sudo sed -i "s/basicsys/$basename$counter/g" $rootdir/etc/hostname
sudo sed -i "s/1.1.1.2/$gateway/g" $rootdir/etc/network/interfaces
sudo sed -i "s/1.1.1.1/$IPnetwork$baseIP/g" \
$rootdir/etc/network/interfaces
sudo rm $rootdir/etc/udev/rules.d/70-persistent-net.rules
sudo touch $rootdir/etc/udev/rules.d/70-persistent-net.rules
sudo umount $rootdir
sudo losetup -d /dev/loop1
sudo losetup -d /dev/loop0
VBoxManage createvm --name $basename$counter --register
VBoxManage modifyvm $basename$counter --pae on --hwvirtex on
VBoxManage modifyvm $basename$counter --memory $memory --acpi on
VBoxManage modifyvm $basename$counter \
--hda `pwd`/$basename$counter.vdi
VBoxManage modifyvm $basename$counter \
--nic1 bridged --nictype1 82540EM --bridgeadapter1 eth0
VBoxHeadless --startvm $basename$counter -p $baseRDP &
sleep 5
baseRDP=$((baseRDP + 1))
baseIP=$((baseIP + 1))
counter=$((counter + 1))
done
If you get this script working, you are well on your way to having the infrastructure in place to
support a manageable, flexible, cost-effective, robust virtualization environment. Personally,
I'm looking forward to getting 3.2.x in place and being able to teleport running machines
between hosts to manage workloads in real time—from the command line, of course. Stay
tuned, my next article will deal with the back-end shared storage (based on open protocols
and free, open-source software, while being redundant and performant). I intend to connect
my virtualization hosts to support being able to:
VBoxManage controlvm vbox-vm-3 \
teleport --host vbox-host-2 --port 17001
Resources
Oracle's Virtualization Blog: blogs.oracle.com/virtualization
mount_vdi: www.mat.uniroma1.it/~caminati/mount_vdi.html
Bill Childers' “Virtualization Shootout: VMware Server vs. VirtualBox vs. KVM”, LJ, November
2009: www.linuxjournal.com/article/10528
Greg Bledsoe is the Manager of Technical Operations for a standout VoIP startup, Aptela
(www.aptela.com), an author, husband, father to six children, wine enthusiast, amateur
philosopher and general know-it-all who welcomes your comments and criticism at
[email protected].