The ISC (Internet System Consortium) Kea DHCP server running inside a Docker container. Separate images for the IPv4 and IPv6 services, as well as an image for the Control Agent which exposes a RESTful API that can be used for querying/controlling the other services.
Available as both Debian and Alpine images and for multiple architectures. In order to facilitate the last part this repo needs to build Kea from source, so it might not be 100% identical to the official ISC package, which is unfortunate but it will probably have to remain like this until official packages are built for all architectures.
There is also an Ansible role using this image, if that is of interest.
Kea is the successor of the old ISC DHCP server which reached its end of life late 2022, so it is recommended to migrate to Kea now if you are still using the old service. Kea is built with the modern web in mind (intro presentation), and is more modular with separate packages for the different services along with a lot of documentation.
To keep the same modularity in the Docker case this repo produces four different images which are tagged with the same version as the Kea service running inside:
jonasal/kea-dhcp4:<version>
jonasal/kea-dhcp6:<version>
jonasal/kea-dhcp-ddns:<version>
jonasal/kea-ctrl-agent:<version>
- (+
jonasal/kea-hooks:<version>
- read about this in the Kea Hooks section)
Just append
-alpine
to the tags above to get the Alpine image.
It is possible to define how strict you want to lock down the version so 2
,
2.2
or 2.2.0
all work and the less specific tags will move to point to the
latest of the more specific ones. One thing to be aware of is that even
minor versions (2.2
) are stable builds while odd (2.3
) are development
builds, therefore the major tagging of all the images built here will only track
the stable releases. What this means is that 2 -> 2.2.0
even though 2.3.1
is
available.
There is no
:latest
tag since Kea updates may break things.
KEA_EXECUTABLE
: Should not be modified, is used byentrypoint.sh
.KEA_USER
: Currently does nothing, might be used in the future.
There are a few directories present inside the images that may be utilized if your usecase calls for it.
This image creates the user
kea
with uid:gid101:101
/100:101
(Debian/Alpine) which may be used for non-root execution in the future, however, Kea runs as root right now since it needs high privilege to open raw sockets.
/kea/config
: Mount this to the directory with all your configuration files./kea/leases
: Good location to place the leases memfile if used./kea/logs
: Good location to output any logs to./kea/sockets
: Host mount this in order to share sockets between containers./entrypoint.d
: Place any custom scripts you want executed at the start of the container here.
All the folders under kea/
may be mounted individually or you can just mount
the entire kea/
folder, however, then you need to manually create the
subfolders since Kea is not able to do so itself. See the advanced
docker-compose example for
inspiration.
Each image/service needs its own specific configuration file, so you will need
to create one for each service you want to run. There is a very simple config
for the dhcp4
service in the simple/ folder,
with more comprehensive ones for all services in the
advanced/ folder. You may also look in the examples
folder on the official repo to find stuff like all available keys for the
DHCP4 config, or go to the documentation for the latest info.
The syntax used is extended JSON with another couple of addons which allows comments and file inclusion. This is very handy and makes it much easier to write well structured configuration files.
When starting the service you need to make sure that you point it to the correct configuration file. In the simple example we would provide the following command to have it find the correct file:
docker run -it --rm \
-v $(pwd)/examples/simple:/kea/config \
jonasal/kea-dhcp4:2 \
-c /kea/config/dhcp4.json
This container will run inside a Docker network so it should not interfere with
anything. You can test to see if it responds correctly by calling upon the
test4
target from the Makefile.
make test4
To start the IPv6 service you just replace all instances of dhcp4
with dhcp6
in the command above. However, I would suggest you read the
next section about the Docker network mode and how that
affects these services before trying anything else.
When you want to run your DHCP server for real you will need to make sure that the incoming DHCP packages can reach your service, and this will not happen in case you put the containers on a normal Docker network.
For basic home use I would recommend just setting the container to use the
host
network, since this will be the absolute easiest way to get around
most issues. However, you could fiddle with a macvlan or an
ipvlan (example) setup in
case you have more advanced needs, but unless you know you need this I would not
bother.
Additionally, IPv6 support in Docker is a little bit messy right now so if you want to deploy that your other choices are a bit limited either way.
Setting the host
network is done by adding
--network host
to the command above, or look at the docker-compose file for how it is done there. Then you should be able to serve leases on the network the host machine is connected to.
The DHCP services expose an API that may be used if the control-socket
setting is defined in their configuration file:
"control-socket": {
"socket-type": "unix",
"socket-name": "/kea/sockets/dhcp4.socket"
},
A unix socket is the only method available, and while you can push commands
directly through this with the help of socat
the ctrl-agent
service
provides a RESTful API that may be interfaced with instead. You just need
to make sure this service can communicate with the control-socket
of the DHCP
service, and an example of how to do this can be found in the
advanced/ folder along with the
docker-compose.yaml file.
When that is all up and running you should be able to make queries like this:
curl -X POST -H "Content-Type: application/json" \
-d '{ "command": "config-get", "service": [ "dhcp4" ] }' \
http://localhost:8000/
More information about this may be found in the Management API section of the documentation.
Kea has some extended features that are available as "hooks" which may be imported in those cases when they are specifically needed. Some are available as free open source while others require a premium subscription in order to get them, a table exists here with more info.
These hooks enable advanced functionality, like High Availability and BOOTP,
which means most people will probably never use these, and which is why we
provide dhcp4-slim
and dhcp6-slim
images which don't have any hook libraries
included at all.
However, if you want to make your own specialized image we do provide an
additional image from where individual hooks may be imported. In the example
below we just import the HA hooks into the dhcp4-slim
service image.
FROM jonasal/kea-dhcp4-slim:2.2.0
COPY --from=jonasal/kea-hooks:2.2.0 /hooks/libdhcp_ha.so /hooks/libdhcp_lease_cmds.so /usr/local/lib/kea/hooks
It could also be necessary to run the linker after this, so just to be safe I would add one of the following lines afterwards.
RUN ldconfig # <--- Debian
or
RUN ldconfig /usr/local/lib/kea/hooks # <--- Alpine