Skip to content

fix(#341): pin dev by digest so pods converge; symmetric convergence check - #342

Merged
cboettig merged 2 commits into
mainfrom
fix/341-dev-digest-pin
Aug 8, 2026
Merged

fix(#341): pin dev by digest so pods converge; symmetric convergence check#342
cboettig merged 2 commits into
mainfrom
fix/341-dev-digest-pin

Conversation

@cboettig

Copy link
Copy Markdown
Member

Closes #341.

Problem

dev-duckdb-mcp was serving traffic from multiple mismatched builds at once. The live ReplicaSet ran two different digests on its two pods, so a request hit the metadata.json tile feature (≥ v0.8.6) or not, at random — which is what broke add_hex_tile_layer on the padus app.

Root cause is the deploy design, not a code bug: dev pinned the moving :main tag with imagePullPolicy: Always. Always re-resolves the mutable :main → digest independently per pod at each (re)start, and :main moves on every push to main plus the weekly cron. So pods started seconds apart, or any single later liveness/eviction/crash/cron restart, silently drift onto different builds — the exact cross-pod skew dev's ≥2 replicas exist to surface. AGENTS.md documented convergence verification for prod only, so the skew was invisible in dev's own workflow.

Fix (issue's Option A — pin dev by digest, same discipline as prod)

  • k8s/dev-deployment.yaml: pin main@sha256:1b0f133f… (current :main) with imagePullPolicy: IfNotPresent. All dev pods now run one reproducible build; restarts/evictions/cron can't silently drift a pod. Redeploy is one extra imagetools inspect line — identical to the prod promote flow.
  • AGENTS.md: dev redeploy is now a promote-by-digest flow (read digest → pin → apply → restart → verify). The convergence check is stated once for both dev and prod, with the Terminating-zombie caveat (out of Service endpoints; never force-delete per NRP policy).

Trade-off: dev no longer auto-tracks main/the cron. Accepted — dev tests a specific merge, so reproducibility beats auto-freshness, and the cron silently bumping dev to random builds was itself the footgun.

Cluster remediation (already applied)

Applied the digest-pinned manifest to dev and rolled out — this both converges the live pods and implements the pin. Verified all live pods report the single pinned imageID. The two stuck Terminating zombie pods (07-05 / 07-09) on unreachable nodes are left alone per NRP ops policy.

cboettig added 2 commits July 20, 2026 17:21
dev pinned the moving :main tag with imagePullPolicy: Always, which is
non-convergent: Always re-resolves :main -> digest independently per pod
at each (re)start, so pods started seconds apart or restarted later
(liveness/eviction/cron) silently drift onto different builds. This is
the exact cross-pod skew dev's >=2 replicas exist to surface, yet it was
invisible: AGENTS.md documented convergence verification for prod only.

- k8s/dev-deployment.yaml: pin main@sha256:<digest>, IfNotPresent (like prod)
- AGENTS.md: dev redeploy is now a promote-by-digest flow; convergence
  check is stated once for both dev and prod, with the Terminating-zombie
  caveat (never force-delete).
…ss digest lookup

The pin in this PR was read 18 days ago. :main has moved five builds since, and
dev has been hand-pinned twice in the meantime to keep up — most recently to
sha256:f9be5dae (git_sha 19b3c70, current main tip), which is what the live
deployment and both serving pods run right now.

Merging the stale sha256:1b0f133f would have made git disagree with the cluster
and silently rolled dev back 18 days on the next `kubectl apply` — the same
class of drift this PR exists to prevent, just slower. Re-read the digest from
the registry and pin what dev actually runs, so the merge is a no-op against the
live deployment.

Also document the registry-v2 fallback for reading a digest. The `imagetools
inspect` line assumes a docker CLI, which a JupyterLab session doesn't have, and
the GHCR packages API needs a read:packages scope our gh logins generally lack —
so the documented step was not executable from the environment the rollout often
gets driven from. The curl form works anywhere, with a note to validate it
against prod's existing pin before trusting it.
@cboettig
cboettig merged commit 24a1ef0 into main Aug 8, 2026
1 check passed
@cboettig
cboettig deleted the fix/341-dev-digest-pin branch August 8, 2026 23:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dev-duckdb-mcp runs mismatched image builds across pods & lags prod — :main+Always is non-convergent

1 participant