Thursday, March 6, 2025

Deploying ISC DHCP Server in a systemd Container

ISC DHCP Server in a Container

This repository describes the operation of a software container to run the ISC DHCP service.

Note
ISC DHCP has been deprecated and end-of-lifed as of Dec 2022 in favor of ISC Kea

ISC DHCP has been the standard DHCP server since the release of version 1.0 in 1998. While ISC has deprecated the orginal DHCP as of Dec 2022 in favor of ISC Kea, the oringal DHCP server remains in use and is a standard package on most Linux distributions.

Conventional packages are tightly bound to the OS distribution and to the version of the OS installed on a particular host. Network services and the systems that host them are crititical infrastructure. The fear of downtime often results in aversion to regular updates.

The fear of update failures can be mitigated by providing for atomic rollback. This means that, in the event of an update induced failure, the service can be rolled back reliably to the previous version. Containerized services offer a way to accept frequent updates while also allowing rapid rollback to a previous version without the fear of conflict or system pollution that packaged software risks.

The dhcp container encapsulates the ISC DHCP daemon so that it can run on any Linux host that uses systemd for system initialization and service management.

Container Images

This repository contains scripts to create two different but functionally equivalent container images. Both are based on the Fedora dhcp-server package. This package provides the ISC DHCP server binary: dhcpd.

The dhcpd-fedora image uses the fedora-minimal base image. The dhcpd image is built from scratch.

This document describes the usage of these images to provide a DHCP service on a host capable of running software containers from systemd-containers. To learn how the container images were built, see:

Prerequisites

The system must have the BOOTP and DHCP ports (68/UDP and 69/UDP) free and must be capable of running systemd containers.

  • Static IP addresses
    The DHCP service itself requires that all IP addresses on the host are configured statically. The DHCP client will, obviously, conflict with the server for port bindings. This took me an embarrassingly long time to figure out when testing the container image.

  • containers-common package
    The host server must be able to run software containers and must have the containers-common package installed. This package provides the bindings that allow podman to generate systemd service unit files from a container service file. On Debian this is the golang-github-containers-common.

Configuration

The configuration of the DHCP daemon is the same as if it was running from an installed package. The Service configuration is contained in the /etc/dhcp/dhcpd.conf file and the lease database is in /var/lib/dhcpd/dhcp.leases.

When the service is packaged, the package creates and populates these with default values. A container can’t affect the OS outside its boundaries so the user must create those files before the service is started.

  • /etc/dhcp/dhcpd.conf
    The daemon is configured with the standard configuration file in the standard location. Describing the configuration is outside the scope of this document. See the excellent existing configuration documents for the ISC DHCP daemon.

  • /var/lib/dhcpd/dhcp.leases
    The lease file must exist when the daemon starts. Initially it is an empty file.

    sudo mkdir -p /var/lib/dhcpd ; sudo touch /var/lib/dhcpd.leases

Enable Containerized Services

OS support for Container and VM management are provided by the containers-common package. On Debian based systems this is called golang-github-containers-common

On recent Red Hat and Fedora releases it is installed by default along with podman. On Debian based systems you must install the package or one that depends on it, like the podman package.

sudo apt update ; sudo apt install golang-github-containers-common

Install DHCP container service

Containerized services are defined by a container unit file. This file follows a similar format to the other systemd unit files.

The container service system was originally known as quadlets but now is defined in the podman systemd specification.

The container file below pulls one of the public container images for the ISC DHCP server.

dhcpd.container
[Unit]
Description=ISC DCHP daemon Service Container
After=network-online.target

[Container]
Image=quay.io/markllama/dhcpd:latest
#Image=quay.io/markllama/dhcpd-fedora:latest

# This shouldn't be needed except for reading /etc/dhcp/dhcpd.conf
# Could move it to /opt/dhcp/dhcpd.conf
PodmanArgs=--privileged
Network=host

# Open listening ports
# bootps
PublishPort=67:67/udp
PublishPort=67:67/tcp

# bootpc
PublishPort=68:68/udp
PublishPort=68:68/tcp

# Mount the dhcp config dir into the container workingdir
Volume=/etc/dhcp/dhcpd.conf:/etc/dhcp/dhcpd.conf:ro,Z
Volume=/var/lib/dhcpd/:/var/lib/dhcpd/:rw,Z

[Install]
# Enable in multi-user boot
WantedBy=multi-user.target default.target

#  podman run --detach --name dhcpd \
#    --privileged  \
#    --network host \
#    --volume /etc/dhcp/dhcpd.conf:/etc/dhcp/dhcpd.conf:ro,Z \
#    --volume /var/lib/dhcpd/:/var/lib/dhcpd/:rw,Z \
#    quay.io/markllama/dhcpd

The two container images indicated in the file above are both created from the Fedora RPM dhcp-server. The dhcpd-fedora container image is based on the Fedora 41 base image. The dhcpd image is a minimal image create from scratch, containing only the dhcpd binary and the required shared libraries.

Limitations and Future Work

This is a proof-of-concept project. The container design currently does not support any of these features of the ISC DHCP server

  • No configuration of invocation parameters

  • No IPv6

  • No OMAPI

  • No external database

References

  • DHCP History
    The history of DHCP and of the ISC DHCP server

  • ISC DHCP
    A DHCP service available on all Linux distributions

  • Podman systemd unit file
    The container service unit file specification

  • systemd
    The modern Linux OS initialization and service management system

  • The containers-common package
    The package that provides the container bindings for systemd services

    • Debian golang-github-containers-common

    • Fedora containers-common

No comments:

Post a Comment