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

## 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).
This commit is contained in:
2026-08-27 00:21:20 +10:00
parent 7bc380eef8
commit b0e3e31a6b
2 changed files with 64 additions and 1 deletions
+11 -1
View File
@@ -241,7 +241,17 @@ func hooks(in RenderInput) []hookLib {
"max-response-delay": firstNonZero(ha.MaxResponseDelay, 60000),
"max-ack-delay": firstNonZero(ha.MaxAckDelay, 5000),
"max-unacked-clients": firstNonZero(ha.MaxUnackedClients, 5),
"peers": peers,
// With core multi-threading enabled (Kea 2.6 default) the HA hook would
// open a dedicated HTTP listener bound to this server's peer url address —
// here a per-pod ClusterIP (virtual, kube-proxy DNAT) that is not
// assignable on the pod, so the bind fails. Disable it so inbound HA
// traffic flows via kea-ctrl-agent, which binds 0.0.0.0:CtrlAgentPort;
// peers stay reachable at their ClusterIP:CtrlAgentPort via the per-pod Service.
"multi-threading": map[string]any{
"enable-multi-threading": true,
"http-dedicated-listener": false,
},
"peers": peers,
}
libs = append(libs, hookLib{
Library: HALibrary,