Skip to content

fix(k8s): inline downward-API label env vars instead of keeping the labels - #18

Merged
vercel-eddie merged 2 commits into
mainfrom
fix/inline-label-fieldrefs
Oct 13, 2026
Merged

vercel-eddie merged 2 commits into
mainfrom
fix/inline-label-fieldrefs

Conversation

@vercel-eddie

@vercel-eddie vercel-eddie commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

StripUnreferencedLabels removes a source Deployment's labels so that existing Services don't select the bridge pod. It keeps any label a fieldRef env var reads (metadata.labels['key']).

A common pattern is a pod that reads its service name from metadata.labels['app.kubernetes.io/name'], with its Service selecting on that same label. A proxy bridge of such a Deployment keeps the label and joins the real Service's endpoints. Once the bridge's device is gone, the Service sends a share of its traffic to the bridge pod, and those requests fail with 502s or hang.

Solution

Before stripping, inlineLabelFieldRefs replaces each downward-API label env var with the label's value, in both containers and init containers. It resolves values the way the downward API would, so an absent label becomes "". Since nothing reads the labels any more, all source labels are stripped, and the bridge's own labels are injected as before. The pod's env is unchanged.

Tests

  • TestStripUnreferencedLabels_ServiceDoesNotSelectBridge (new): a pod reads SERVICE_NAME from app.kubernetes.io/name. The test checks that the Service's selector no longer matches the bridge pod and that SERVICE_NAME is inlined. It fails without this change.
  • PreservesFieldRefLabels and InitContainerFieldRef now assert that the values are inlined and the labels stripped.

Bridges that already exist keep their labels until they're recreated or deleted.

🤖 Generated with Claude Code

vercel-eddie and others added 2 commits October 1, 2026 16:48
InjectCA named the secret "bridge-ca", and Rename only appends the device
ID, so every bridge from a device shared bdg-bridge-ca-<device>:

- each create generated a new CA and replaced the one the device's other
  bridges had mounted;
- two concurrent creates both found it missing and raced to create it, so
  the loser failed with AlreadyExists;
- each create relabeled it with its own bridge's labels, so removing that
  bridge deleted the secret out from under the others, whose pods then
  can't restart.

The secret is now named after the bridge (bdg-bridge-ca-<bridge>-<device>),
so it carries only its own bridge's labels and is removed with it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…abels

A bridge kept every source label a fieldRef env var reads. vercel/api's pods
read SERVICE_NAME from app.kubernetes.io/name, which their Services select on,
so each proxy bridge joined the real Service and, once its device was gone,
took a share of the service's traffic with it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@vercel-eddie
vercel-eddie merged commit cdaff03 into main Oct 13, 2026
6 checks passed
@vercel-eddie
vercel-eddie deleted the fix/inline-label-fieldrefs branch October 13, 2026 19:13
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.

1 participant