diff --git a/kubernetes/infrastructure/netbird-ingress/daemonset.yaml b/kubernetes/infrastructure/netbird-ingress/daemonset.yaml index 54fd1c1e..2c18787c 100644 --- a/kubernetes/infrastructure/netbird-ingress/daemonset.yaml +++ b/kubernetes/infrastructure/netbird-ingress/daemonset.yaml @@ -38,6 +38,16 @@ spec: rollingUpdate: # roll one node's peer at a time; the others keep serving the route. maxUnavailable: 1 + # Pace the roll to NetBird's route re-convergence. A rolled peer is replaced + # by a freshly-enrolled peer (ephemeral state below) that must join the + # k8s-ingress-router route group and propagate to mesh clients before it + # actually forwards. Without this, the roll steps to the next node as soon as + # `netbird status --check ready` passes (seconds) — faster than the mesh + # re-converges — so the HA route runs degraded for the whole roll and public + # ingress (home.renner.uno) drops for ~1 min (observed 2026-07-11). Hold each + # new peer Ready this long before rolling the next, so >=2 peers are always + # actually serving the route. + minReadySeconds: 45 template: metadata: labels: @@ -86,6 +96,17 @@ spec: memory: 64Mi limits: memory: 256Mi + # Graceful drain: withdraw this peer from the mesh BEFORE the process + # is killed. Without a preStop the pod is only SIGTERM'd, so the mesh + # keeps the (now-dead) peer in the HA route group until a keepalive + # timeout (~25-30s) — traffic riding through it black-holes until + # then. `netbird down` disconnects the peer from the management server + # so it fails the route over to the other per-node peers immediately. + # Runs within terminationGracePeriodSeconds (default 30s). + lifecycle: + preStop: + exec: + command: ["netbird", "down"] livenessProbe: exec: command: ["netbird", "status", "--check", "live"]