Tag Archives: libvirt

Making VM cloning simpler v2

In my last post I wrote about a procedure that I use to help me to locate VM IP address after creation. You can read about the problem here.

The problem with my solution is that you need to take the networking control away from Libvirt, creating the bridge with hand, configuring dnsmasq, etc. So, I looked at the code and I made libvirt do it for me. Here is the commit.

Basically, this adds an option to network config inside libvirt to setup forwarders for dnsmasq. This allows you to use the last one as the nameserver for your host machine (using in your resolv.conf). Every time a VM boots up, it receives an IP address from dnsmasq and gets its FQDN mapped to its IP address (something like a dnsupdate, but this happens internally because the same daemon provides both services).

You have to setup the domain and the forwarders options to get this working.

This new feature is documented and will appear in a future release of libvirt.

Post to Twitter

Making VM cloning simpler with libvirt, fabric and dnsmasq

When I bought my laptop I chose one with a lot of RAM because I use virtualization for development and testing. I use KVM and libvirt tools to manage my VMs. I have different templates of different Linux distributions that I clone frequently to do my tasks. One of the annoying things that I faced is the IP address assignment. Every time I new VM is created, I have log into the VM to see the IP address, to configure hostnames, /etc/hosts, etc.

libvirt uses dnsmasq by default as DHCP/DNS server for the virtualization environment. dnsmasq supports something like DNS update (because the same daemon has both services, it’s a built-in feature), so when an address is provided, the host sends its hostname and the dns is updated. To get this working you need to configure a couple of parameters. One of the problems is that libvirt doesn’t support this (until my patch is accepted). You have to disable the network configuration and configure it manually:

# virsh net-autostart default --disable
# virsh net-destroy default
# cat >> /etc/network/interfaces << EOF
auto virbr0
iface virbr0 inet static
        bridge_ports none
        up iptables -t nat -A POSTROUTING -s -j MASQUERADE
        up /usr/sbin/dnsmasq -C /etc/dnsmasq.d/virt.conf

Then, it’s time to configure dnsmasq:
cat > /etc/dnsmasq.d/virt.conf << EOF
# mkdir -p /var/lib/dnsmasq/
# touch /var/lib/dnsmasq/default.hostsfile /var/lib/dnsmasq/default.addnhosts

And now… up!
# ifup virbr0

Don’t forget to configure as nameserver for your local machine and to set the domain configured in dnsmasq in the search parameter of resolv.conf.

At this point, every time a VM boots up, you will be able to log in using its hostname. But the story hasn’t finished yet. In my machine, when I clone a guest I still have to log into it to change hostname, /etc/hosts, etc. To avoid this I created a script that I added to my toolbox, that uses Fabric to configure this stuff. It has the following requirements:

  • The hostname of the guest that you use as template must match the VM name in libvirt configuration.
  • The root user should be enabled and the ssh pubkey of your PC user must be in the authorized_file of the root user in the template.

Now, when I need to create one or more virtual machines, I just execute:

# my-virt-clone.py templaname virtual1 virtual2 ... virtualN

The VMs are created, and I am able to use the hostname to log into them.

My laptop has Ubuntu 13.04 installed, and I tested this procedure using templates with Ubuntu 12.04 , Ubuntu 13.04 and Debian Wheezy.

Post to Twitter