What is the IP address of my guest?

When using libvirt to create virtual machines, I find that networking works pretty well right out of the box. My VMs are connected to one another via a virtual subnet and have outbound access to the internet. But there is one itch that needs scratching. When I am ready to SSH into a VM, what hostname/IP address should I use? That answer is attained only after connecting to the VM with VNC, logging in, and looking at ‘ifconfig’ output. Sure, you could configure your VMs with static IPs, but that’s not a very elegant solution either.

The ideal solution to this problem is to be able to do: ssh <vm name> and have it “just work”. In this article I will show you how to use a libvirt virtual network to do just that.

Libvirt Virtual Networks

Libvirt provides many useful networking functions to domains through the concept of a virtual network. Among the services that can be provided are addressing via DHCP and local DNS, LAN connectivity via Network Address Translation (NAT), and network boot services (TFTP and BOOTP). When you configure your domain with
<interface type='network'> and <source network='default'> you are using the ‘default’ virtual network which provides DHCP and NAT. By creating our own virtual network, we can customize how these services are provided and produce the results we want.

Create your own libvirt network

The first step is to define a new virtual network. To do this, we will create an XML document to describe what we want. Details on the format of this document can be found here.

Let’s begin:

<network>
  <name>mynetwork</name>
  <bridge name="virbr1" />
  <forward/>
  <ip address="192.168.123.1" netmask="255.255.255.0">
    <dhcp>
      <range start="192.168.123.2" end="192.168.123.254" />
      <host mac='de:ad:be:ef:00:01' name='vm-1' ip='192.168.123.2' />
      <host mac='de:ad:be:ef:00:02' name='vm-2' ip='192.168.123.3' />
      ...
    </dhcp>
  </ip>
</network>

On line 2, we define the name of the network. The name is how we select this network in the domain configuration. On line 3, we define the bridge device name that will be used to build the virtual network. Be sure to choose a name that is not already taken (virbr0 is reserved for the ‘default’ network). On line 4, we enable NAT so our VMs can access the internet. The <ip> tag on line 5 is where things get interesting. This is where we configure addressing. Line 5 defines the gateway (or router) for the virtual network. Here we reserve a block of 254 possible addresses all beginning with ‘192.168.123.’. This should be enough but make sure this subnet does not conflict with your existing network configuration. On the next line, the <dhcp> tag enables DHCP services and gives us the opportunity to customize address and hostname assignment. The <range> tag tells the DHCP server which addresses it is allowed to assign to virtual machines.

Immediately following that, are explicit per-host address assignments. You will want one of these lines for each of your VMs. The DHCP server will identify your VMs by mac address. Therefore, make sure that the network config and domain config files agree about these mac addresses. The name tag will create a named entry in the local DNS server for this VM which is very handy. I recommend using your VM name here. ‘.localdomain’ must be appended to produce a fully-qualified domain name. Since these IP addresses are local to the host, use localdomain. Finally, the ip allows you to reserve a specific IP address for the VM.

Once you have made your network config file, save it to /etc/libvirt/qemu/networks and create a symlink in /etc/libvirt/qemu/networks/autostart to have it started automatically. Start up the network with the following:

virsh net-define /etc/libvirt/qemu/networks/mynetwork.xml
virsh net-start mynetwork

If you typed your network xml carefully you should see a message indicating that your network was started successfully.

Modify your libvirt domains

With the custom virtual network created, the last step is to modify your domains to use it. This should be a simple process if your domains were previously using the ‘default’ network. In that case, change:

<source network='default'>
to
<source network='mynetwork'>

in your domain configuration files. Remember to make sure that the mac address in your network xml matches the domain xml. After making changes, shut down and restart your virtual machines. If you decided to change the mac address in your domain xml, you may need to reconfigure networking inside the VM.

At this point, your efforts should bear fruit. From your host, you should be able to map vm name to ip address automatically (ie. ssh vm-1 or host vm-1). Enjoy!

About aglitke

I am a software engineer working on Linux, open source software, and virtualization. I am proud to work at Red Hat on oVirt and Red Hat Virtualization with a focus on software defined storage. Other notable projects I have been involved in include: The Linux ppc64 architecture, Linux kernel crash dumps (kdump), Linux huge pages and libhugetlbfs, qemu, libvirt, and the Memory Overcommitment Manager.
This entry was posted in libvirt. Bookmark the permalink.

2 Responses to What is the IP address of my guest?

  1. hydra35 says:

    Good post!
    My quick-and-dirty way to find out vm’s IP is doing ‘arp -an’ on host…

  2. L says:

    Hi,

    I found an interesting thing. I try to `dig @192.168.122.1 vm1` and it turned out that the virtual network could resolve the hostname by itself. Thus I simply add the “nameserver 192.168.122.1” to the tail file of /etc/resolv.conf configuration files.

    The next time I try `ssh vm1`, it worked.

Leave a reply to hydra35 Cancel reply