KVM and Virtualization

Virtualization

The goal of virtualization is to provide a software platform consisting of a completely different instance of an operating system, called a virtual machine. The virtual machine "lives" in a single binary image file. A system which supports virtualization is called the host and a virtual machine is called a guest. There are a number of software tools called hypervisors, which serve as the virtualization software, including KVM, XEN, VmWare, VirtualBox, etc. Ubuntu builds much of its virtual KVM is only possible if the hardware has sufficient capabilities, but if you can use it, it is extremely fast and Ubuntu supports it well.

The main benefit for us is the ability to set up a "test bed" for trying out software features without tying up extra hardware. One can use this virtualization to install multiple versions of Linux in order to evaluate and compare them. From a security perspective, we can use virtual machines as "attack targets" for security software testing. In an enterprise setting a virtual machine can be a lightweight specialized "server" which is optimized to perform one service task.

The last section of this document suggests an idea of how you might use a VM as a dedicated web server. Often it is simpler to configure a web server at the web root and dedicate all the system resources to this server, instead of figuring out how to share them with other services.

Install the necessary packages:
$ sudo apt-get install kvm qemu bridge-utils libvirt-bin \
    ubuntu-vm-builder virt-viewer virt-manager
You must add yourself to the libvirtd group to use some of the tools:
$ sudo adduser LOGIN libvirtd
You then have to log out and log back in to have this take effect.

The inspiration for the steps outlined below is the Ubuntu Server Guide, in particular, the section which describes the minimal JeOS (pronounced "juice") installation using the Ubuntu vmbuilder tool. You can get information about how to use vmbuilder tool in two ways:
$ man vmbuilder
$ vmbuilder kvm ubuntu --help | more
The vmbuilder tool is undoubtedly the best approach for creating "production style" virtual machines whose primary goal is to provide some server function on a single server or within a so-called "server cloud", because vmbuilder is specifically geared for a virtual machine and only the software necessary is installed specific to that end.

Our guest machines will be "attached" to the virtual bridge interface virbr0, which has been generated for you by the libvirt-bin installation. Check it out by:
$ ifconfig virbr0

Build the VM

Our virtual machine will be called vm1. We'll use the directory ~/vm1 to hold it, but technically it can be anywhere in the system since we'll create the VM as root.
$ mkdir -p ~/vm1
Within this folder create the following file by copy/paste. Make sure you have your LOGIN set at the top of this script. The MIRROR variable is set to use for our Lab machines.

vm1/create-vm1.sh
#!/bin/bash
 
# choose mirror size
MIRROR="http://us.archive.ubuntu.com/ubuntu"
 
# choose sute  (precise=12.04)
SUITE=precise
 
# choose architecture
ARCH="amd64"
#ARCH="i386"
 
VMNAME="vm1"
MYOCTET=200
ROOTSIZE=5000
SWAPSIZE=512
 
# login/password into VM
# we will change the password immediately
ADMIN="LOGIN"
INITPWD="vmpass"
 
vmbuilder kvm ubuntu \
--suite="$SUITE" \
--flavour=virtual \
--arch="$ARCH" \
--libvirt=qemu:///system \
--hostname="$VMNAME" \
--bridge=virbr0 \
--ip="192.168.122.$MYOCTET" \
--mask=255.255.255.0 \
--gw=192.168.122.1 \
--dns=192.168.122.1 \
--domain=localdomain \
--user="$ADMIN" \
--name=Administrator \
--pass="$INITPWD" \
--rootsize="$ROOTSIZE" \
--swapsize="$SWAPSIZE" \
--mem=512 \
--addpkg=acpid \
--addpkg=openssh-server \
--addpkg=nano \
--addpkg=rsync \
--install-mirror="$MIRROR" \
 
# leave at least one blank line after command
# so any further options can easily be appended
select
To create the virtual machine, run create-vm.sh as root:
$ cd ~/vm1 
$ time sudo bash create-vm1.sh
The entire install completes in less than 10 minutes on the lab machines.

Here are some points about this vmbuilder command usage:
  1. The kvm argument means to use KVM as the hypervisor.
  2. The --libvirt=qemu:///system option indicates to make the virtual machine accessible through the QEMU interface. This allows us to control the VM with many of the available software tools.
  3. The --hostname="$VMNAME" makes vm1 be the virtual machine hostname, and also the domain name, accessible through the QEMU system.
  4. The --bridge=virbr0 option means to use virbr0 as the guest's network interface.
  5. The --ip (IP address), --mask (netmask), --gw (gateway), --dns (resolver) and --domain define the network setup.

    The IP address is 192.168.122.200, has last octet set at 200. which could be anything other than 1.
  6. The --user, --name, and --pass set up the initial account on the guest.
  7. The --rootsize and --swapsize specifiy the virtual machine's virtual disk size being a 5000MB (~5GB) root and 512MB (~.5GB) swap.
  8. The RAM size is 512M introduced through the --mem option. This memory usage actually takes away from the memory available to the host machine. This memory size is configurable after creation.
  9. The --addpkg options specify packages to install in the initial machine.

The VM contents

After completion, the virtual machine you just built is represented by these:
~/vm1/ubuntu-kvm/
/etc/libvirt/qemu/vm1.xml
You can see the file which represents the guest's storage as:
$ ls -s ~/vm1/ubuntu-kvm
size-in-K  ____.qcow2
The "cow" here means copy-on-write. Note that the file size, around 550MB or so, is significantly less than 5.5BG maximum size.

If you want to start over, delete both the directory and the XML configuration file and restart the virtual machine manager: libvirt-bin:
$ sudo service libvirt-bin restart

Run and access the VM

You can control the machine through two tools: First create a host entry for vm1. Edit the file /etc/hosts. At the end of the file add the entry:
192.168.122.200   vm1
Start up virt-manager. Select vm1 from the list of virtual machines (the only one so far) and click the green triangle "run" button. If you double-click on the line, it will bring up a shell by which you can access the machine, but we'll access it via SSH.

The VMs boot very quickly. You should be able to ping it very soon after starting it up:
$ ping vm1 
Then, open a Terminal and go in:
$ ssh vm1 
LOGIN@vm1's password: vmpass
Set the VM's password to your password. Use "sudo" to circumvent any password "deficiency":
LOGIN@vm1:~$ sudo passwd LOGIN 
[sudo] password for LOGIN: vmpass 
Enter new UNIX password: password-for-LOGIN-on-MACHINE
Retype new UNIX password: password-for-LOGIN-on-MACHINE
passwd: password updated successfully
Give cryptographic access to your virtual machine. Create the .ssh directory:
[vm1] $ mkdir .ssh
Open another shell in the host and do this:
[MACHINE] $ rsync ~/.ssh/id_dsa.pub vm1:.ssh/authorized_keys2
LOGIN@vm1's password: password-for-LOGIN-on-MACHINE
Then test password-less access:
[MACHINE] $ ssh vm1 ls

Run nginx web server on VM

This is yet another alternative to Apache, on par with Lighttpd in terms of speed. Its home page is this:
http://wiki.nginx.org/
We won't configure it, just set it up to give you an the idea.
[vm1] $ sudo apt-get install nginx
[vm1] $ sudo /etc/init.d/nginx start
Confirm by accessing the VM web root:
http://vm1
Make the virtual machine accessible to the world by proxy. Create the proxy lines in /etc/apache2/conf.d/local.conf:
ProxyPass        /special http://vm1
ProxyPassReverse /special http://vm1
Reload Apache and confirm access to the VM by:
http://localhost/special

Upgrades

The VM is used a GUI interface, so do the updates with aptitude.
[vm1] $ sudo apt-get install aptitude
Update like this:
[vm1] $ sudo aptitude update
[vm1] $ sudo aptitude upgrade


© Robert M. Kline