Replace Duckgres control-plane replicas without breaking most existing sessions during a planned deployment.
- The Deployment uses rolling replacement with overlap:
maxUnavailable: 0maxSurge: 1
terminationGracePeriodSecondsis at least the configured drain timeout- The control plane sets
--handover-drain-timeout 15m(or another explicit value appropriate for the cluster)
- The old replica receives
SIGTERM. - It closes local pgwire and Flight admission and fails
/health. - It publishes
drainingin runtime state. - New pgwire and Flight bootstrap sessions are rejected on the draining replica.
- Existing pgwire connections and existing Flight sessions continue until they finish or the drain timeout expires.
- When the timeout expires, the replica force-shuts down remaining sessions and workers.
See Org connection admission for the mixed-version admission boundary during a rolling deployment.
Unplanned control-plane failure is different:
- live pgwire connections are lost immediately
- durable Flight reconnect may recover only when the worker survives and the session token is still valid
-
Start the rollout.
kubectl -n duckgres rollout restart deploy/duckgres-control-plane kubectl -n duckgres rollout status deploy/duckgres-control-plane
-
Watch old and new pods during overlap.
kubectl -n duckgres get pods -l app=duckgres-control-plane -w
-
Verify the old pod becomes unready before it exits.
kubectl -n duckgres get pods -l app=duckgres-control-plane kubectl -n duckgres logs <old-pod-name>
-
Confirm the new pod is serving traffic and new sessions acquire workers.
sum(duckgres_worker_lifecycle_count{state="spawning"})settles back toward 0 (on-demand spawns succeed)sum(duckgres_worker_lifecycle_count{state="hot"})does not drop unexpectedly- client reconnect errors do not spike
- Check whether the old pod is still draining active sessions:
kubectl -n duckgres logs <old-pod-name> | rg "drain|draining|shutdown"
- Check whether the pod termination grace period is shorter than the configured drain timeout.
- Check whether long-lived idle clients are holding pgwire connections open.
- Check whether Flight sessions are still active and not timing out.
- Increase both:
--handover-drain-timeoutterminationGracePeriodSeconds
Keep those values aligned. If the pod is killed before the drain timeout elapses, Kubernetes will cut the drain short.