DNS for libvirt VMs

As the title says, this post is about setting up a solution for automatically populating DNS entries for libvirt VMs.


Update 1: Use localOnly to avoid loops between host dnsmasq and libvirt dnsmasq.

This is useful if:

  1. You have a requirement that VMs should be able to ping each other by hostname. In case of dhcp clients, if the clients are setup correctly then you don't have to do anything else. However, that is not a solution if you don't want to change anything in the guest.
  2. For ease of use, you would want to do a ssh into the VM using the VM name.
  3. You have more than one virtual networks and want VMs to communicate across them.
On a Fedora 22 installation this is how your network and dns stack would like:



  • Virtual machines which use a NAT interface through a virtual network on the host go through a DNSMASQ service that is setup by libvirt for every virtual network interface that it creates. This dnsmasq service caters as a nameserver as well as a dhcp server for all VMs on this network.
  • Virtual machines cannot ping host or virtual machines which are not on the same virtual network by hostname at all.
  • Virtual machines would be able to ping other virtual machines on the same virtual network by hostname if and only if the virtual machines have setup dhclient to pass the hostname to dns/dhcp server.

Solution1:

This is the simplest solution, just make sure you add entries for every virtual machine that is started on your host with a entry in /etc/hosts. It is sufficient for you to be able to ping every VM from host and all VMs would be able to ping each other by hostname. This however does not work if for some reason you have setup dnsmasq as your dns service on host.

Solution2:

This solution has two steps

1. Get a DNS server(dnsmasq service again) on localhost and assign dnsmasq service created by libvirt as DNS server for specfic domains.

  • We will ask NetworkManager to start using dnsmasq as name server. This has many other benefits which are better described in a different post. Create a new file /etc/NetworkManager/conf.d/10-dnsmasq.conf and add the following content.
  • Now create a file /etc/NetworkManager/dnsmasq.d/libvirt with something like shown below. Here default is the name of the virtual network virbr0 that libvirt creates by default. Also, for my vagrant setup I have vagrant-libvirt virtual network that has subnet of 192.168.123.1/24. This specifies that for all domain names of the format *.default.virt refer to 192.168.122.1 as DNS server.
  • At the same time inform libvirt's dnsmasq service that for these domains it should not forward DNS requests upstream. To do that , execute virsh net-edit "virtual-network-name" and add the line <domain name="virtual-network-name.virt" localonly='yes'>.

After restarting NetworkManager this is how our setup looks like



2. Now we have to populate the entries for hostnames. We will do it in a automated way and it requires setting up few scripts. Modify the scripts however you like to suit your needs.

username ALL=(root) NOPASSWD: /path/to/virt-hosts

Now, our setup is complete and setup looks like this


A gif of all three pics, just for fun :)




Comments

  1. Thanks for Your Great post. You publish good details about dns servers. You have shared a lot of information in this article. Anonymous VPS

    ReplyDelete

Post a Comment