Skip to content

SeiNodeDeployment: template.metadata.labels don't propagate to pods (divergence from Deployment semantics) #103

@bdchatham

Description

@bdchatham

Context

SeiNodeDeployment.spec.template.metadata.labels is a footgun for anyone coming from Kubernetes Deployment semantics.

In a stock K8s Deployment:

  • spec.template.metadata.labelspod labels (what you select with kubectl get pods -l ...)

In SeiNodeDeployment today:

  • spec.template.metadata.labels → labels on the owned SeiNode CR only
  • spec.template.spec.podLabels → labels that actually land on pods

This inverts a strong, widely-internalized Kubernetes convention. We hit it while writing the autobake smoke-test workflow — the probe step used labels declared in template.metadata.labels expecting them on pods, kubectl returned zero matches, run failed. See sei-protocol/platform#110 for the symptom.

Call sites

  • internal/controller/nodedeployment/labels.go:65-66 — applies template.metadata.labels to SeiNode resources
  • internal/controller/nodedeployment/nodes.go:224-228 — auto-injects sei.io/nodedeployment + revision into SeiNode.Spec.PodLabels
  • internal/noderesource/noderesource.go:52-57ResourceLabels reads from SeiNode.Spec.PodLabels for the StatefulSet pod template

So only template.spec.podLabels reaches pods. Anything in template.metadata.labels is applied to the SeiNode CR and stops there.

Options

A. Also propagate template.metadata.labels onto pods — makes SND feel like Deployment. Low risk: these labels already get added to SeiNode metadata, adding them to PodLabels as well is a strict superset. Provider owns the interface, so consumers only gain labels they already expected.

B. Prominent CRD schema description + godoc comment — cheaper, preserves current semantics. Relies on every future consumer reading the schema carefully before using the field.

C. Reject template.metadata.labels at admission — force callers to use podLabels explicitly. Breaks existing consumers.

My lean is A: it costs little, removes the trap, and aligns with the most common K8s mental model.

Acceptance (for option A)

  • template.metadata.labels keys appear on both the child SeiNode CR and the pods it creates
  • template.spec.podLabels still works as today (keys still apply to pods)
  • Conflict policy: template.spec.podLabels wins over template.metadata.labels on key collision (explicit beats implicit), or flag the conflict at admission
  • System labels (sei.io/nodedeployment, revision) still set last so they can't be overridden
  • Unit test in internal/controller/nodedeployment/ covering the merge order

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions