I ran into a problem recently where virtual machines I created from a template were fighting over the same IP address. Each of them would be assigned the same IP address from my DHCP server, despite the fact that each VM created from my standard template had a unique Mac address. I had a hard time finding the culprit, so I figured I would write a post about it. In my case, I am using Proxmox, though the root-cause is not specific to any virtualization package. My virtual machines were all running Ubuntu 18.04, though this can impact other distributions too. The root cause ended up being due to something called a “machine-id”. Read on to find out how I solved this.
When you install a Linux distribution that utilizes machine-id (Ubuntu 18.04 is such a distribution) it will get a unique machine-id generated and stored in the following file:
In addition, the machine-id may (or may not) also be stored in the following file:
It’s also common for /var/lib/dbus/machine-id to be a symbolic link to /etc/machine-id.
What’s happening, is that for some reason, the machine-id is being used to request an IP address from DHCP, rather than the Mac address. I am not sure why this is the case, why someone thought this was a good idea, or the reasons why Ubuntu 18.04 is set up this way. I haven’t done a lot of reading on this yet, I did only enough research to solve the problem. I’ll probably study this a bit more at some point, but I wanted to get this blog entry posted quickly in case someone else is fighting this.
Here’s what you’ll need to do.
To best solve this problem, remove the contents of /etc/machine-id so that it is an empty file:
sudo truncate -s 0 /etc/machine-id
Then, delete /var/lib/dbus/machine-id:
sudo rm /var/lib/dbus/machine-id
Finally, make a symbolic link:
sudo ln -s /var/lib/dbus/machine-id /etc/machine-id
When you reboot the system, it should generate a new machine-id. It’s important to note that you cannot simply delete the machine-id file, it needs to exist, and be empty. For whatever reason, if the file doesn’t exist, it will never get recreated. But if it’s empty, it will. If you’re like me and attempting to create a virtual machine image or template for rolling out servers, what you’ll do is perform the above steps before you create the image. One would think that cloud-init should take care of this for us, since that’s its entire purpose (provisioning resources to be unique). For some reason, cloud-init doesn’t have a mechanism to solve this and it’s up to us to ensure this aspect of our templates/images is set up manually.
Update: Someone has recently written in to the Sunday Morning Linux Review podcast and mentioned that he’s seen this problem on CentOS as well, so it’s not just Ubuntu.