Skip to content

3.4 High availability

Part 3 · Architecture & operationsArchitect⏱ ~25 min✓ Knowledge check

High availability in SpatiumDDI is three separate problems: redundant DNS, redundant DHCP, and a redundant control plane. Each uses different mechanics and fails in a different way. If you mix them up you can end up with a three-node cluster that still drops DNS when one box reboots. This module takes each layer in turn, then puts them together in a failure table you can use in design reviews.

  • Build redundant DNS with several servers per group, explain why no zone transfer is involved, and know the DNSSEC exception
  • Configure a Kea HA pair, and separate what SpatiumDDI renders from what Kea does itself
  • Choose a control-plane HA path: the appliance or Helm, since Compose HA isn’t supported in 1.0
  • Predict what keeps serving for each common failure, and why HA doesn’t replace backups
Layer How you make it redundant Protects
DNS More servers in the same DNS server group Name resolution
DHCP Two Kea servers in one DHCP server group (DHCPv4) Leases and renewals
Control plane Several api/worker/frontend replicas, plus HA PostgreSQL and Redis The UI, the API and your ability to make changes

The layers don’t cover for each other. The appliance docs say it bluntly: control-plane HA is not serving HA. A cluster whose DNS and DHCP roles sit on one node still loses DNS and DHCP when that node goes down.

nginx LB API + DBsingle VM (Topology 2) DNS Server Group vm-dns-01is_primarybind9 :53 vm-dns-02own copybind9 :53 vm-dns-03own copybind9 :53 DHCP HA pair (Kea) vm-dhcp-eastprimarykea :67 vm-dhcp-weststandbykea :67 HA Configured via the UI DNS Server Group — every member renders its own copy; each record change is an op per server. The zone'sper-server serial status shows who has converged. DNSSEC signing needs a group with one server. DHCP Server Group with HA mode hot-standby (or load-balancing). HA covers DHCPv4 only.Set each Kea server's own ha_peer_url (appliances fill it in). Peer IPs are re-resolved if they drift. Agents long-poll the control plane; if the API is unreachable, both sides serve from cache and Kea HAcontinues operating against its peer regardless of control-plane state.
Several DNS servers in one group, and a Kea HA pair · Adapted from the SpatiumDDI documentation (Apache-2.0)

Add a second (or third) agent-managed server to the same group and you have redundant authoritative DNS. Unless the group’s zones are DNSSEC-signed, nothing else needs configuring.

  • Every enabled server renders each of the group’s zones as an independent authoritative copy, and gets its own queued op for every record change.
  • is_primary doesn’t make one server “the writer” in an agent-managed group. It only orders the fan-out and picks whose result the audit trail reports.
  • If one server is unreachable, its ops wait as pending and drain when it returns, while the others apply straight away. The zone’s per-server serial status shows who has converged.
  • Hand clients more than one of the servers, for example in DHCP option 6, so they can fail over.

Signed zones are the exception. Every agent engine signs with keys held on that server, so two servers in a group would serve two DNSKEY sets against one DS. SpatiumDDI therefore signs only on a group with one agent server, and refuses to add or move a server into a group that holds signed zones; disabled servers count (#1762). For signed zones, keep one signing server and add redundancy with secondary zones in another group (module 3.2 shows the pattern).

A zone already signed on several servers shows a red DNSSEC: multiple signers badge and raises the critical dnssec_multi_signer alert. An agent that registers itself into such a group through AGENT_GROUP isn’t refused, because it would retry forever, so check for that alert after you add agents.

Put two Kea servers in one DHCP server group, pick an HA Mode on the group, and fill in the HA Peer URL on each server. Each server’s URL is its own HA listener, typically http://<that server's address>:8000/ on the shipped image; SpatiumDDI renders every member’s URL into each peer’s list, which is how the partner finds it. On appliances, empty URLs are filled in for you when the second Kea member joins a host-networked HA group (#2963). When both URLs are set, SpatiumDDI renders Kea’s HA hook into both configs.

  • Hot Standby (one active, one passive): the primary serves every client, and the standby takes over when Kea decides the partner is down.
  • Load Balancing (both active): Kea splits clients between the peers by a hash of the client identifier.

Scopes, pools, reservations and classes live on the group, so both peers always render the same config.

SpatiumDDI does Kea does
Renders the HA hook with an identical peer list in both configs, plus your heartbeat and delay tuning Replicates leases and runs the HA state machine, peer to peer over TCP 8000
Generates a per-group CA and peer certificate, so only the group’s own peers can use the HA listener; a superadmin rotates it with POST /api/v1/dhcp/server-groups/{id}/ha-peer-credential/rotate Requires that certificate from its partner, over HTTPS, once every member’s agent supports it
Resolves peer hostnames to IP addresses (Kea only accepts IP literals) and re-checks them every 30 s Decides when to fail over, including after the control plane is gone
Polls status-get about every 15 s to drive the HA v4 pill in the UI Keeps answering from its own lease store if replication breaks

A third Kea member now has defined behavior. With its own HA Peer URL it joins as a backup peer that receives lease updates but takes no part in the heartbeat. Without one it’s sidelined: no HA hook and none of the group’s scopes, and the group page says “More than two Kea members” (#3151). Two things still aren’t built: driving HA state transitions (maintenance, continue, force-sync) from the UI, and gating DDNS writes on HA state, so in some windows both peers could try to write the same record.

Windows DHCP uses its own failover relationships. Since 2026.10.02-1 SpatiumDDI reads them on every lease sync, writes each scope only to the members that hold it (both partners when a relationship covers it), and can create, edit and replicate relationships from the group’s Windows DHCP failover panel over the CredSSP transport (#1110). Kea and Windows DHCP can’t share a group; module 3.2 has the details.

operators / DNS · DHCP agents MetalLB control-plane VIPone floating IP · L2 · re-homes on node loss appliance-1 · etcd seedk3s server + etcdapi · frontend · workerCNPG primaryredis · sentinel (master) appliance-2 · memberk3s server + etcdapi · frontend · workerCNPG replicaredis · sentinel (replica) appliance-3 · memberk3s server + etcdapi · frontend · workerCNPG replicaredis · sentinel (replica) embedded-etcd quorum (3 / 5 / 7) · CNPG primary + async replicas · Redis Sentinel scaled by promoting Additional nodes in /appliance → Fleet · DNS and DHCP run only on nodes given those roles
Topology 7: a 3-node appliance control plane behind one VIP · Adapted from the SpatiumDDI documentation (Apache-2.0)

In every shape the rules are the same: api, worker and frontend are stateless and scale out, PostgreSQL and Redis need their own HA, and beat stays a singleton.

  • Install every node after the first as an Additional node, then promote from /appliance → Fleet → Manage control plane cluster…. Sizes are odd only (1, 3, 5, 7); the API refuses an even total. A second First node would be a separate SpatiumDDI, not a member.
  • Within about 60 seconds of promoting two nodes you have etcd quorum across three, CloudNativePG at three instances, a 3-node Redis Sentinel set, and three api, worker and frontend replicas.
  • Size every member at 4 vCPU, 8 GiB and a 48 GiB SSD: on 40 GiB disks a slot upgrade followed by a rolling upgrade reached the disk-usage warning.
  • CloudNativePG replicates asynchronously, so a failover can lose the last few commits.
  • Per-role node labels keep control-plane workloads on control-plane nodes, so a DNS-only appliance never gets PostgreSQL.
  • Set a MetalLB pool and control-plane VIP under Appliance → Network & Host. The self-signed Web UI certificate grows to cover the VIP.
  • You can’t demote the etcd seed, and you can’t revoke a node while it’s a live cluster member; demote it first.
  • k3s takes an etcd snapshot every 6 hours and keeps 8. Restoring one resets etcd to a single node, so it’s for disaster recovery only.

An agent follows one control-plane URL. Point DNS and DHCP agents (and operators’ browsers) at the VIP or load balancer, never at one node’s IP: an agent pinned to a node loses its control plane whenever that node is down, even while the cluster is healthy. It keeps serving from cache, but it gets no changes until the node returns. When you install an Additional node, give the VIP as its control plane URL. Cluster members themselves are safe: their supervisors reach the api through the in-cluster Service.

Failure Impact What keeps serving
One DNS server in a group Its ops wait as pending; marked unreachable after 90 s The group’s other servers answer and take changes; the stale one catches up on return
One Kea in an HA pair The HA v4 pill shows the change of state The surviving peer, under Kea’s own HA state machine
Whole control plane unreachable No UI, API, changes or scheduled jobs; agents spool leases, query logs and metrics and replay them on reconnect Every agent from its last-known-good cache; Kea HA peer to peer
Redis down Celery loses its broker, so DNS bundles stop being rendered. The long-poll falls back to polling: DHCP changes land within about 2 s, and DNS changes wait for the api, which builds the bundle itself after 120 s Config delivery through the long-poll, and all DNS and DHCP
Worker not consuming bundles, or no worker at all No DNS bundle renders. If the rest of the worker runs, agent_bundle_render_failed fires after 10 minutes; with no worker, alerts and other background jobs stop too DNS changes through the api’s fallback after 120 s (it can time out on very large groups); DHCP config delivery
PostgreSQL primary lost (HA) The api can’t reach the database until a replica is promoted (about a minute on Helm); the last few commits can be lost Agents from cache; the api resumes on the new primary
One of three appliance control-plane nodes etcd keeps quorum (2 of 3), the database fails over (possibly losing the last few commits), the VIP moves The UI on the same address, and DNS/DHCP on every node that carries the roles
Beat stopped Scheduled jobs stop; the dashboard’s Platform Health card flags Beat (celery-beat) Everything interactive, and all DNS and DHCP
A bad config bundle The agent reverts, quarantines it and raises agent_config_rejected That server, on its previous good config

Replication copies mistakes as fast as it copies good changes. A deleted zone disappears from every DNS server and every database replica within seconds. Your undo buttons are the Trash (30 days) and your backups, so keep both working:

  • Schedule backups to a remote destination and run Restore Drills against them. A drill replays the newest archive into a scratch database and checks it without touching the live one. The backup_failed and backup_stale alerts are on by default for every scheduled destination (#1262).
  • On a hand-built Patroni cluster behind HAProxy, point restores at the read/write port, not the read-only one.
  • DNSSEC keys live on each agent’s own volume, whatever the engine, not in the backup.
  • An etcd snapshot restore is disaster recovery for the cluster, not a way to undo a bad change.
Knowledge check · 6 questions

High availability

1. Ridgeline adds a second BIND9 server to the default group. What else must you set up so that it serves corp.example.edu?

2. A DHCP group has two Kea servers, run from the standalone agent compose file, in Hot Standby mode, but only one server has its HA Peer URL filled in. What happens?

3. Which of these is Kea's own job, not SpatiumDDI's?

4. You upgrade a Kea HA pair from 2.6 to 3.0 one node at a time. What should you expect?

5. Why should off-cluster DNS and DHCP agents use the control-plane VIP rather than a node's IP?

6. Which statements about control-plane HA are true?

Select all that apply.

Finished 3.4 High availability?
Mark it complete to track your progress (stored only in this browser).