LXC Not Honoring DHCP Reservation

The LXC getting started guide states that lxc-stop will remove dhcp leases but it does not. Starting a container with a reserved IP works the first time, meaning it get’s the IP assigned, but stopping the container and starting it again leads to a new IP address, which is not desired behavior.

Stopping the container removes the lease.

Linux Containers – LXC – Getting started

Example output demonstrating the problem

root@cdesktop:~# cat /var/lib/misc/dnsmasq.lxcbr0.leases
root@cdesktop:~# cat /etc/lxc/dnsmasq.conf
dhcp-host=container1,10.0.3.100
root@cdesktop:~# lxc-start --name container1
root@cdesktop:~# lxc-ls --fancy
NAME       STATE   AUTOSTART GROUPS IPV4       IPV6 UNPRIVILEGED
container1 RUNNING 1         -      10.0.3.100 -    true
root@cdesktop:~# cat /var/lib/misc/dnsmasq.lxcbr0.leases
1748212357 a6:45:a4:d6:cb:8c 10.0.3.100 container1 *
root@cdesktop:~# lxc-stop container1
root@cdesktop:~# lxc-ls --fancy
NAME       STATE   AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
container1 STOPPED 1         -      -    -    true
root@cdesktop:~#  cat /var/lib/misc/dnsmasq.lxcbr0.leases
1748212357 a6:45:a4:d6:cb:8c 10.0.3.100 container1 *
root@cdesktop:~# lxc-start --name container1
root@cdesktop:~# lxc-ls --fancy
NAME       STATE   AUTOSTART GROUPS IPV4       IPV6 UNPRIVILEGED
container1 RUNNING 1         -      10.0.3.216 -    true
root@cdesktop:~# cat /var/lib/misc/dnsmasq.lxcbr0.leases
1748212411 9e:69:54:ed:1a:bc 10.0.3.216 container1 *
1748212357 a6:45:a4:d6:cb:8c 10.0.3.100 * *

A Quick and Dirty Workaround

I do not have the time to find the root cause and I know precisely what I want to happen so I created a bash script that removes the lease from the file and then runs the lxc-stop command after.

#! /bin/bash
echo "This is a workaround to remove dhcp leases when a container is stopped"
echo "More info at technicallyrambling.calmatlas.com/lxc-not-honoring-dhcp-reservation"
# Extract the container name from the args
if [ "$#" == 1 ]; then
        containerName=$1
else
        containerName="$(echo $@ \
                | grep \
                        -oe '--name [a-z,A-Z,0-9]* ' \
                        -oe '-n [a-z,A-Z,0-9]* ' \
                        -oe '--name [a-z,A-Z,0-9]*$' \
                        -oe '-n [a-z,A-Z,0-9]*$' \
                |cut -d " " -f 2)"
fi

# Remove the lease
if [ "$containerName" ]; then
        echo "Removing $containerName lease in /var/lib/misc/dnsmasq.lxcbr0.leases"
        sed -i "/$containerName/d" /var/lib/misc/dnsmasq.lxcbr0.leases
        echo "Restarting lxc network"
        service lxc-net restart
fi

# Stop the container
echo "Running: lxc-stop.orig $@"
lxc-stop.orig $@

To make this script work move /usr/bin/lxc-stop to /usr/bin/lxc-stop.orig, then symlink the script to the /usr/bin/lxc-stop

mv /usr/bin/lxc-stop /usr/bin/lxc-stop.orig
ln -s /root/lxc-stop-workaround.sh /usr/bin/lxc-stop

The script deletes the lease while it’s assigned to the container, so if you have already started and stopped the container a few times you will need manually delete the lease in question then run service lxc-net restart, or you can restart the host. The script should keep your IP addresses reliably unchanged going forward.

Output After Applying Workaround

root@cdesktop:~# cat /var/lib/misc/dnsmasq.lxcbr0.leases
root@cdesktop:~# cat /etc/lxc/dnsmasq.conf
dhcp-host=container1,10.0.3.100
root@cdesktop:~# lxc-start --name container1
root@cdesktop:~# lxc-ls --fancy
NAME       STATE   AUTOSTART GROUPS IPV4       IPV6 UNPRIVILEGED
container1 RUNNING 1         -      10.0.3.100 -    true
root@cdesktop:~# cat /var/lib/misc/dnsmasq.lxcbr0.leases
1748224563 a6:49:57:4b:ad:27 10.0.3.100 container1 *
root@cdesktop:~# lxc-stop container1
This is a workaround to remove dhcp leases when a container is stopped
More info at technicallyrambling.calmatlas.com/lxc-not-honoring-dhcp-reservation
Removing container1 lease in /var/lib/misc/dnsmasq.lxcbr0.leases
Restarting lxc network
Running: lxc-stop.orig container1
root@cdesktop:~# lxc-ls --fancy
NAME       STATE   AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
container1 STOPPED 1         -      -    -    true
root@cdesktop:~# cat /var/lib/misc/dnsmasq.lxcbr0.leases
root@cdesktop:~# lxc-start --name container1
root@cdesktop:~# lxc-ls --fancy
NAME       STATE   AUTOSTART GROUPS IPV4       IPV6 UNPRIVILEGED
container1 RUNNING 1         -      10.0.3.100 -    true
root@cdesktop:~# cat /var/lib/misc/dnsmasq.lxcbr0.leases
1748224594 8a:39:be:5a:17:67 10.0.3.100 container1 *

A Call for Feedback

If you want to learn more about the problem, or you have a more elegant solution, please comment. I only built this script so I could quickly get back to my other post: Using LXC containers on Ubuntu

Leave a Reply