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
        address 192.168.122.1
        netmask 255.255.255.0
        up iptables -t nat -A POSTROUTING -s 192.168.122.0/24 -j MASQUERADE
        up /usr/sbin/dnsmasq -C /etc/dnsmasq.d/virt.conf
EOF

Then, it’s time to configure dnsmasq:
cat > /etc/dnsmasq.d/virt.conf << EOF
strict-order
domain-needed
domain=woitasen.local
expand-hosts
local=/woitasen.local/
no-resolv
server=8.8.8.8
server=8.8.4.4
pid-file=/var/run/dnsmasq-diegows-laptop.pid
bind-dynamic
addn-hosts=/var/lib/dnsmasq/default.addnhosts
dhcp-option=3,192.168.122.1
dhcp-range=192.168.122.2,192.168.122.254
dhcp-no-override
dhcp-leasefile=/var/lib/dnsmasq/default.leases
dhcp-lease-max=253
dhcp-hostsfile=/var/lib/dnsmasq/default.hostsfile
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 127.0.0.1 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

One thought on “Making VM cloning simpler with libvirt, fabric and dnsmasq”

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>