Kea-DHCP HA Backup server
Kea-DHCP supports "Backup" DHCP-Server. During normal operation, these backup DHCP Server receive lease updates from active Kea-DHCP servers, but unlike a standby-server the active (primary) DHCP server will not wait for an acknowledge of the lease update from the backup server.
Also unlike a standby Kea-DHCP server, a Kea-DHCP running in backup mode will not become active automatically. Bringing a Kea-DHCP "backup" server into production requires a change in the Kea-DHCP configuration file.
The example scripts in this article will give a template on how to switch a Kea-DHCP server from backup into production and back to backup again.
Requirements
- Unix Shell
- The
curlprogram ( https://curl.se/ ), installed via package manager - The
jqprogram ( https://jqlang.org/ ), installed via package manager
The script do change the Kea-DHCP HA Hook configuration. In the production configuration,
the server kea01 is primary, and keabck1 is the backup server.
When promoting the backup server, the configuration is switched so that kea01 becomes a
backup server, and keabck1 becomes the primary.
Shell script for switching a Kea-DHCP4 server from backup into production:
#!/bin/sh
# get the full kea-config, remove "result" and "hash" JSON objects
echo "Fetching current Kea-DHCP config ..."
keaconfig=$(curl -s --json '{ "command": "config-get", "service": [ "dhcp4" ] }' http://[::1]:9099/ | jq ".[0]" | jq "del(.result)" | jq "del(.arguments.hash)" )
# get the current (production) Kea HA configuration
prodconfig=$(echo ${keaconfig} | jq '.arguments.Dhcp4."hooks-libraries".[].parameters."high-availability" | select(. != null )' )
# save the current production Kea HA config
$(echo ${prodconfig} | jq '.[0]' > kea-ha-production-config-save.json)
# delete the old HA config from the JSON config
keaconfig=$(echo ${keaconfig} | jq 'del(.arguments.Dhcp4."hooks-libraries".[].parameters."high-availability".[0])')
newconfig=$(cat kea-ha-backup-config.json)
# add new backup config to the JSON config
keaconfig=$(echo ${keaconfig} | jq ".arguments.Dhcp4.\"hooks-libraries\".[1].parameters.\"high-availability\".[0] = ${newconfig}")
# add command and service
keaconfig=$(echo ${keaconfig} | jq '."command" = "config-set"')
keaconfig=$(echo ${keaconfig} | jq '."service" = [ "dhcp4" ]')
# save new configuration to file
$(echo ${keaconfig} > newconfig.json)
# send new config to Kea-DHCP server
echo "Sending new backup config ..."
res=$(curl -s --json @newconfig.json http://[::1]:9099/)
echo ${res} | jq ".[0].text"
echo "Saving new config ..."
res=$(curl -s --json '{ "command": "config-write", "arguments": { "filename": "/etc/kea/kea-dhcp4.conf" }, "service": [ "dhcp4" ] }' http://[::1]:9099/)
echo ${res} | jq ".[0].text"
Shell script for switching a Kea-DHCP4 server from production into backup mode:
#!/bin/sh
# get the full kea-config, remove "result" and "hash" JSON objects
echo "Fetching current Kea-DHCP config ..."
keaconfig=$(curl -s --json '{ "command": "config-get", "service": [ "dhcp4" ] }' http://[::1]:9099/ | jq ".[0]" | jq "del(.result)" | jq "del(.arguments.hash)" )
# get the current (backup) Kea HA configuration
prodconfig=$(echo ${keaconfig} | jq '.arguments.Dhcp4."hooks-libraries".[].parameters."high-availability" | select(. != null )' )
# save the current production Kea HA config
$(echo ${prodconfig} | jq '.[0]' > kea-ha-backup-config-save.json)
# delete the old HA config from the JSON config
keaconfig=$(echo ${keaconfig} | jq 'del(.arguments.Dhcp4."hooks-libraries".[].parameters."high-availability".[0])')
newconfig=$(cat kea-ha-production-config.json)
# add new backup config to the JSON config
keaconfig=$(echo ${keaconfig} | jq ".arguments.Dhcp4.\"hooks-libraries\".[1].parameters.\"high-availability\".[0] = ${newconfig}")
# add command and service
keaconfig=$(echo ${keaconfig} | jq '."command" = "config-set"')
keaconfig=$(echo ${keaconfig} | jq '."service" = [ "dhcp4" ]')
# save new configuration to file
$(echo ${keaconfig} > newconfig.json)
# send new config to Kea-DHCP server
echo "Sending new production config ..."
res=$(curl -s --json @newconfig.json http://[::1]:9099/)
echo ${res} | jq ".[0].text"
echo "Saving new config ..."
res=$(curl -s --json '{ "command": "config-write", "arguments": { "filename": "/etc/kea/kea-dhcp4.conf" }, "service": [ "dhcp4" ] }' http://[::1]:9099/)
echo ${res} | jq ".[0].text"
Content of file kea-ha-backup-config.json
{
"delayed-updates-limit": 0,
"heartbeat-delay": 10000,
"max-ack-delay": 5000,
"max-rejected-lease-updates": 10,
"max-response-delay": 60000,
"max-unacked-clients": 0,
"mode": "hot-standby",
"multi-threading": {
"enable-multi-threading": true,
"http-client-threads": 0,
"http-dedicated-listener": true,
"http-listener-threads": 0
},
"peers": [
{
"auto-failover": false,
"name": "kea01",
"role": "backup",
"url": "http://192.0.2.101:9098/"
},
{
"auto-failover": false,
"name": "kea02",
"role": "standby",
"url": "http://192.0.2.102:9098/"
},
{
"auto-failover": false,
"name": "keabck1",
"role": "primary",
"url": "http://192.0.2.201:9098/"
}
],
"require-client-certs": true,
"restrict-commands": true,
"send-lease-updates": true,
"sync-leases": true,
"sync-page-limit": 10000,
"sync-timeout": 60000,
"this-server-name": "keabck1",
"wait-backup-ack": false
}
Content of file kea-ha-production-config.json
{
"delayed-updates-limit": 0,
"heartbeat-delay": 10000,
"max-ack-delay": 5000,
"max-rejected-lease-updates": 10,
"max-response-delay": 60000,
"max-unacked-clients": 0,
"mode": "hot-standby",
"multi-threading": {
"enable-multi-threading": true,
"http-client-threads": 0,
"http-dedicated-listener": true,
"http-listener-threads": 0
},
"peers": [
{
"auto-failover": false,
"name": "kea01",
"role": "primary",
"url": "http://192.0.2.101:9098/"
},
{
"auto-failover": false,
"name": "kea02",
"role": "standby",
"url": "http://192.0.2.102:9098/"
},
{
"auto-failover": false,
"name": "keabck1",
"role": "backup",
"url": "http://192.0.2.201:9098/"
}
],
"require-client-certs": true,
"restrict-commands": true,
"send-lease-updates": true,
"sync-leases": true,
"sync-page-limit": 10000,
"sync-timeout": 60000,
"this-server-name": "keabck1",
"wait-backup-ack": false
}