Skip to content

JonasAlfredsson/docker-kea

Repository files navigation

docker-kea

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:

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.

Usage

Environment Variables

  • KEA_EXECUTABLE: Should not be modified, is used by entrypoint.sh.
  • KEA_USER: Currently does nothing, might be used in the future.

Useful Directories

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:gid 101: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.

The DHCP Server

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.

Docker Network Mode

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 Control Agent

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 Hooks

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 so 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