Automatic DNS updates from libvirt guests

Tue, 24 Dec 2013 12:51:13 +0000

Recently I've been relying a lot on Vagrant and vagrant-libvirt in particular for spinning up a variety of OSes for testing. One irritating habit I've developed is to check the IP of the VM each time it comes up if I need to view a website/app hosted on the VM itself and paste this into my browser, rather than using a DNS name.

Since libvirt runs dnsmasq by default for DHCP and DNS services inside NAT virtual networks, getting DNS working from the hypervisor (my desktop) is very easy. First ensure that the libvirt network has the domain name correctly configured - this was my hostname initially, but I changed it to example.com:

$ sudo virsh net-edit default
<network>
  <name>default</name>
  <uuid>f6f31c1d-0130-40e4-9cfc-80811021b46e</uuid>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr0' stp='on' delay='0' />
  <mac address='52:54:00:03:62:29'/>
  <domain name='example.com'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.128' end='192.168.122.254' />
    </dhcp>
  </ip>
</network>

Change the <domain> tag's name attribute, then virsh net-destroy default and virsh net-start default to restart and apply this change.

Next I updated the images and VMs I use in libvirt to send hostnames when making DHCP requests, ensuring that dnsmasq would associate the hostname with the DHCP lease. On Red Hat variants, set DHCP_HOSTNAME=yourhost.example.com in /etc/sysconfig/network-scripts/ifcfg-eth0 and run service network restart.

Provided the domain in the DHCP_HOSTNAME is the same as the domain set in libvirt's network (which is used to configure dnsmasq), the hostname will get updated and is shown in /var/lib/libvirt/dnsmasq/default.leases with the domain removed:

1387893215 52:54:00:15:d1:73 192.168.122.143 foreman *

If hostnames aren't shown, check syslog for messages such as this to indicate a domain name mismatch:

Dec 24 12:32:46 cobalt dnsmasq-dhcp[8571]: Ignoring domain example.com for DHCP host name foreman

Lastly, I configure NetworkManager on my desktop to redirect queries for example.com to the dnsmasq instance serving the libvirt network. First I switch NetworkManager to run a dnsmasq instance of its own instead of pointing resolv.conf to external resolvers:

$ sudoedit /etc/NetworkManager/NetworkManager.conf
[main]
dns=dnsmasq

Then add a dnsmasq config snippet to send queries for example.com through to the dnsmasq instance bound to the gateway IP address of the libvirt network:

$ sudoedit /etc/NetworkManager/dnsmasq.d/libvirt_dnsmasq.conf
server=/example.com/192.168.122.1

And now, from my desktop I'm able to bring up a VM and instantly query or use the foreman.example.com hostname to access it.