From 3bf94a5d7fd33e415686a035bfb21fa5cc896730 Mon Sep 17 00:00:00 2001 From: Niklas Ye Date: Sat, 3 Oct 2026 12:30:27 +0200 Subject: [PATCH] Default to 2 replicas and RollingUpdate now that the singleton jobs are locked replicas and strategy: Recreate were the chart's only guard against the archiver, notifier and migration races; v0.36.0 closed all three with advisory locks and a conflict-resolving incident insert, which made that guard redundant rather than load-bearing. Expose replicaCount (new, no values.yaml key existed before) defaulting to 2, and switch to strategy: RollingUpdate with no explicit maxUnavailable/maxSurge -- the 25%/25% default rounds to 0/1 at replicaCount: 2, which is already zero-downtime. The chart does not gate this on image.tag, so pointing it at a pre-v0.36.0 image with the new default is a foot-gun by omission -- noted in both the values.yaml comment and the deployment.yaml comment, not guarded in code, same as the chart does for every other version-coupled assumption today. Co-authored-by: Claude --- .../terdut-server/templates/deployment.yaml | 19 +++++++++---------- charts/terdut-server/values.yaml | 7 +++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/charts/terdut-server/templates/deployment.yaml b/charts/terdut-server/templates/deployment.yaml index f2eb2b0..e193306 100644 --- a/charts/terdut-server/templates/deployment.yaml +++ b/charts/terdut-server/templates/deployment.yaml @@ -6,20 +6,19 @@ metadata: labels: {{- include "terdut-server.labels" . | nindent 4 }} spec: - replicas: 1 + replicas: {{ .Values.replicaCount }} selector: matchLabels: {{- include "terdut-server.selectorLabels" . | nindent 6 }} - # Recreate, not RollingUpdate, even though the PVC that forced it is gone: - # the sweeper, notifier and migration runner take a Postgres advisory lock - # each, and new-incident creation on the first webhook for a brand-new - # groupKey resolves its own insert conflict — so two replicas overlapping - # during a rollout no longer double-page, race a migration, or drop a - # webhook payload. Nothing left here actually requires Recreate anymore; - # it stays the default pending a deliberate decision to raise replicas - # above 1 and move to RollingUpdate. + # RollingUpdate, not Recreate: the sweeper, notifier and migration runner + # each take a Postgres advisory lock around their own pass, and new-incident + # creation on the first webhook for a brand-new groupKey resolves its own + # insert conflict -- so two replicas overlapping during a rollout no longer + # double-page, race a migration, or drop a webhook payload (v0.36.0). No + # explicit maxUnavailable/maxSurge: the 25%/25% default rounds to 0/1 at + # replicaCount: 2, which is zero-downtime already. strategy: - type: Recreate + type: RollingUpdate template: metadata: labels: diff --git a/charts/terdut-server/values.yaml b/charts/terdut-server/values.yaml index 19d8933..64d3de4 100644 --- a/charts/terdut-server/values.yaml +++ b/charts/terdut-server/values.yaml @@ -1,3 +1,10 @@ +# Safe above 1 since v0.36.0: the sweeper, notifier and migration runner each +# take a Postgres advisory lock around their own pass, and a webhook that +# loses the race to open a brand-new incident attaches to the winner's row +# instead of dropping its payload. An image older than v0.36.0 does not have +# these guards -- do not raise this against one. +replicaCount: 2 + networking: hostname: "terdut.example.com" servicePort: 8080