Using own dhcp server for containers

I setup my own dhcp server for containers instead of LXD’s dhcp server.
I did “lxc network set lxdbr0 ipv4.dhcp false”, created a “dhcp” container with static ip (I used images:alpine/3.8 to make it small), installed and configured dnsmasq. New containers now get ip4 addresses from the “dhcp” container.

In the dnsmasq configuration file, I specified that container a1 should get a specific ip address. When I launch a1 for the first time, it gets the desired address.
When I delete a1 and relaunch another container with the same name “a1”, dnsmasq does not give it the specified ip address, because that address is alread leased to the dead container. This is the error I get:

dhcp daemon.warn dnsmasq-dhcp[549]: not using configured address 10.232.110.142 because it is leased to 00:16:3e:30:74:eb

How can I force dnsmasq to ignore the lease and give to “a1” the address specified for it?

How does the LXD dhcp server handle this situation? Configuring the host-ip association in raw.dnsmasq does not work in LXD 3.x (which is why I want to use a separate dhcp server). But I noticed that if I put the ip address in the host’s /etc/hosts, then it does reassign the same ip address.

delete the file, /var/lib/misc/dnsmasq.lxcbr0.leases and restart lxc-net service before starting the container. This should assign the configured ip address to the container.

When you launch a container, by default it gets a random MAC address (from 00:16:3e:xx:xx:xx which is a range designated for use in virtualisation environments) and keeps that MAC address for the duration of its lifetime.
The DHCP server (either from LXD, or your own) associates the DHCP leases with MAC addresses, not with container names.

To able able to associate the container name with a specific DHCP lease (specific IP address), you would need to grant the same container name with the same MAC address. That is, specify the MAC address instead of letting it be chosen automatically.

How would you do that? Suppose the container name is “a1”.

$ echo -n a1 | sha1sum | cut -c 1-6
f29bc9

Then, set the MAC address to 00:16:3e:f2:9b:c9.

That’s good! And I do this by adding “-c volatile.eth0.hwaddr=00:16:3e:f2:9b:c9” to the “lxc launch” command.

Exactly.

Is such a feature useful enough that would warrant a feature request?

I would prefer if this were implemented in dnsmasq, e.g. when I associate a hostname with an ip address, it should override any leases for a previous mac address (perhaps controlled with an additional dnsmasq configuration value). But I’m afraid they’ll say it goes against the DHCP spec.

It’s important to be able to assign ip addresses to containers by name (which is typically also the hostname). Most of the time I want a container to use the same ip address that a previous container with the same ip address had. For example, I may need to rebuild the container from a new OS template, or restore it from backup. It’s a new container, but it replaces a previously existing container and should work in a system of interconnected containers (like replacing a worn bicycle tire). It’s not always possible to reference that container by hostname. In many cases an ip address is necessary (for example when configuring iptables to redirect an incoming tcp connection for a port to that container), or when using a reverse http proxy, which avoids doing dns lookups for performance reasons.

Also, the .lxd dns reference only works between containers. It does not work from a host. if I create a container c1, I cannot ping it with its c1.lxd name from the host.
If I need to access c1 via tcp, I’d need to put its ip address in /etc/hosts and/or in ~/.ssh/config, etc. If I put it in /etc/hosts, this seems to be used by LXD’s dhcp server (although I haven’t seen it documented), so it reduces the need for the feature.

There may also be cases where I’d want it to be treated as a completely new container with no relation to any previous containers (for example for testing the behavior of a DHCP server).

Between dnsmasq and LXD, such a feature would fit better to be implemented in LXD.
LXD is the one already that gives random MAC addresses to the containers, therefore it could give fixed addresses, derived from the hostname. To be fair, it would be implemented either in LXD, or adapted with some scripting on top of LXD.

You can setup the host to resolve the .lxd hostnames according to https://blog.simos.info/how-to-use-lxd-container-hostnames-on-the-host-in-ubuntu-18-04/

Currently I’m doing something similar to what you did but I’m noobie on this.
Can you please explain me how did you deploy a dhcp server and dnsmasq on an alpine container?
Thanks @votsalo!