Disable HA hook dedicated listener; route HA via ctrl-agent #8

Merged
benvin merged 1 commits from benvin/ha-listener-bind into main 2026-08-29 12:03:26 +10:00
Member

Why

After v0.1.4 (commit 66ae5f5) pointed HA peer URLs at per-pod ClusterIP Services, kea-dhcp4 2.6 now starts the HA service ("HA_SERVICE_STARTED server0: started high availability service in hot-standby mode as primary server") but immediately crashes at hook load:

DHCP4_CONFIG_LOAD_FAIL ... Error initializing hooks: CmdHttpListener::run failed:
unable to setup TCP acceptor for listening to the incoming HTTP requests:
bind: Cannot assign requested address

With core multi-threading enabled (the Kea 2.6 default), the HA hook opens a dedicated HTTP listener bound to this server's own peer url address. That address is now a per-pod ClusterIP — virtual (kube-proxy DNAT) and not assignable on the pod — so the bind fails. Peers must be reachable via ClusterIP, but the local listener must bind a pod-local address.

How

  • In the HA relationship, add a multi-threading block with http-dedicated-listener: false (enable-multi-threading: true). Per the Kea 2.6 docs, disabling the dedicated listener routes inbound HA traffic through kea-ctrl-agent instead of a hook-owned listener.
  • This matches the existing deployment: the kea-ctrl-agent sidecar already binds 0.0.0.0:8000, and each per-pod Service's targetPort 8000 routes ClusterIP:8000 to that container. Remote peers keep reaching this server at its stable ClusterIP; nothing binds the virtual address locally.

Rendered HA block now:

"multi-threading": {
  "enable-multi-threading": true,
  "http-dedicated-listener": false
}

Tests

  • TestHADedicatedListenerDisabled — rendered dhcp4 config disables the dedicated listener (string assertion + parsed high-availability.multi-threading map).
  • TestRenderCtrlAgent extended — ctrl-agent binds 0.0.0.0 (the pod-local address the CA-mediated HA route depends on).
  • make test / go vet / build all green.
## Why After v0.1.4 (commit 66ae5f5) pointed HA peer URLs at per-pod ClusterIP Services, kea-dhcp4 2.6 now starts the HA service ("HA_SERVICE_STARTED server0: started high availability service in hot-standby mode as primary server") but immediately crashes at hook load: ``` DHCP4_CONFIG_LOAD_FAIL ... Error initializing hooks: CmdHttpListener::run failed: unable to setup TCP acceptor for listening to the incoming HTTP requests: bind: Cannot assign requested address ``` With core multi-threading enabled (the Kea 2.6 default), the HA hook opens a **dedicated HTTP listener bound to this server's own peer url address**. That address is now a per-pod ClusterIP — virtual (kube-proxy DNAT) and not assignable on the pod — so the bind fails. Peers must be reachable via ClusterIP, but the local listener must bind a pod-local address. ## How - In the HA relationship, add a `multi-threading` block with `http-dedicated-listener: false` (`enable-multi-threading: true`). Per the Kea 2.6 docs, disabling the dedicated listener routes inbound HA traffic through **kea-ctrl-agent** instead of a hook-owned listener. - This matches the existing deployment: the `kea-ctrl-agent` sidecar already binds `0.0.0.0:8000`, and each per-pod Service's `targetPort 8000` routes `ClusterIP:8000` to that container. Remote peers keep reaching this server at its stable ClusterIP; nothing binds the virtual address locally. Rendered HA block now: ```json "multi-threading": { "enable-multi-threading": true, "http-dedicated-listener": false } ``` ## Tests - `TestHADedicatedListenerDisabled` — rendered dhcp4 config disables the dedicated listener (string assertion + parsed `high-availability.multi-threading` map). - `TestRenderCtrlAgent` extended — ctrl-agent binds `0.0.0.0` (the pod-local address the CA-mediated HA route depends on). - `make test` / `go vet` / build all green.
unkin-agent added 1 commit 2026-08-27 00:21:53 +10:00
Disable HA hook dedicated listener; route HA via ctrl-agent
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
b0e3e31a6b
## Why
After v0.1.4 pointed HA peer URLs at per-pod ClusterIP Services, kea-dhcp4 2.6
starts the HA service but then crashes at hook load:

  DHCP4_CONFIG_LOAD_FAIL ... Error initializing hooks: CmdHttpListener::run
  failed: unable to setup TCP acceptor for listening to the incoming HTTP
  requests: bind: Cannot assign requested address

With core multi-threading enabled (Kea 2.6 default), the HA hook opens a
dedicated HTTP listener bound to *this* server's peer url address. That address
is now a per-pod ClusterIP — virtual (kube-proxy DNAT), not assignable on the
pod — so the bind fails. Peers must be reached via ClusterIP, but the local
listener must bind a pod-local address.

## How
- Set the HA relationship's multi-threading block http-dedicated-listener:false
  (enable-multi-threading:true). Per Kea 2.6 docs this makes inbound HA traffic
  flow through kea-ctrl-agent instead of a hook-owned listener. The ctrl-agent
  sidecar already binds 0.0.0.0:8000, and the per-pod Service targetPort 8000
  routes ClusterIP:8000 to that container, so remote peers keep reaching this
  server at its ClusterIP while nothing binds the virtual address locally.
- Regression tests: rendered config disables the dedicated listener (string +
  parsed high-availability.multi-threading assertion); ctrl-agent binds 0.0.0.0
  (the pod-local address the CA-mediated route depends on).
benvin merged commit 0567505a51 into main 2026-08-29 12:03:26 +10:00
benvin deleted branch benvin/ha-listener-bind 2026-08-29 12:03:26 +10:00
Sign in to join this conversation.