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 and it becomes a bit larger. This is unfortunate but will probably have to remain like this until official packages are built for all architectures, however, since all images shares the same base the vast majority of the data will not be duplicated if you run all the services at the same time.
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 will reach its end of life sometime during 2022, so it is recommended to start migrating now. It is built with the modern web in mind, 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/socket/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.
Since these hooks enable advanced functionality, like High Availability and BOOTP, most users will never use these. They also take up quite a lot of space compared to the rest of the image so therefore they are not included by default. However, we do provide an image from where the hooks may be imported so you can make your own specialized image, and in the example below we just import the HA hooks into the DHCP4 service image.
There actually exists pre-built containers with the HA hooks built in if that is the only thing you need: kea-dhcp4-ha & kea-dhcp6-ha.
FROM jonasal/kea-dhcp4: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
You probably also need 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