feat(nodeset): roll pods when mounted Secrets/ConfigMaps change - #204
feat(nodeset): roll pods when mounted Secrets/ConfigMaps change#204giuliocalzo wants to merge 1 commit into
Conversation
Adds opt-in tracking of the Secrets and ConfigMaps mounted by a NodeSet's worker pods so a content change automatically rolls the pods and records a ConfigHashChanged event. - Opt in per-NodeSet via the "slinky.slurm.net/reload-on-change" annotation. - Discovers Secrets/ConfigMaps referenced via volumes (incl. projected sources), envFrom, and env[].valueFrom (new internal/utils/confighash). - Computes a key-aware checksum per resource and stamps it on the pod template before revision computation, so a change yields a new ControllerRevision and the existing Slurm-aware rolling update. - Persists the observed checksums in a new status.configHashes map keyed by "<kind>/<name>"; the reconciler compares freshly computed checksums against it and emits a ConfigHashChanged event on change. No event fires on first observation. The status map is the sole source of truth for change detection (no ControllerRevision reads, no watch-time diffing). - Watches ConfigMaps, extends the Secret watch, and indexes opted-in NodeSets by mounted config refs so a changed resource enqueues only the NodeSets that mount it. - Missing resources resolve to a deterministic sentinel; transient read errors requeue without creating spurious revisions. - Adds a live-cluster verification test (build-tagged test/configrollout, "make test-config-rollout") that asserts on status.configHashes, a new ControllerRevision, and the ConfigHashChanged event.
|
Good afternoon @giuliocalzo, I'm reading through this PR now. Out of curiosity, why did you use an annotation to contain this configuration value instead of the NodeSet CRD itself? In my opinion, a NodeSet CRD field would be more consistent with the rest of our NodeSet configuration pattern. Best, |
hi @vivian-hafener I did not want to overload the CRD of flags/parameters, using an annotation feels more correct as opt-in feature, just let me know I can convert as CRD parameter if you think is better |
|
I think that it would make the most sense to use a tool like Reloader for this. I've reached out to the Reloader team to see if they would be open to a contribution that would enable that tool to reload NodeSet pods: stakater/Reloader#1192 |
Summary
Adds opt-in tracking of the Secrets and ConfigMaps mounted by a NodeSet's worker pods so that a content change automatically rolls the pods and records an event.
slinky.slurm.net/reload-on-change: "true".envFrom, andenv[].valueFrom.spec.template.metadata.annotations) during reconcile, before revision computation. BecausegetPatchfoldsspec.templateinto theControllerRevision, a changed checksum yields a new revision and triggers the existing Slurm-aware rolling update (drain +maxUnavailable+updateStrategy).Why
NodeSet worker pods routinely mount configuration and credentials from Secrets/ConfigMaps, but Kubernetes does not roll a workload when the content of a mounted Secret/ConfigMap changes — only when the pod template itself changes. For most workloads a kubelet-side projected-volume refresh is enough, but Slurm workers are different: many of these files are read once at container start (or by an init hook), so a live update silently diverges from what the running
slurmdactually loaded. Operators are then forced to manually delete pods to pick up the new config, which bypasses Slurm-aware draining.Concrete production scenarios this addresses:
hooks.dconfig. A cluster ships its enroot configuration and a set ofhooks.dscripts (e.g. enroot/pyxis hooks, NCCL/topology tuning, mount setup) via a mounted ConfigMap. These are consumed at container/job startup, so updating the ConfigMap has no effect on already-running workers. With opt-in tracking, editing thehooks.dConfigMap rolls the NodeSet through a proper Slurm drain so every worker comes up with the new hooks.<kind>/<name>-keyedstatus.configHashesmap make it clear which resource changed, and theConfigHashChangedevent gives operators an audit trail of what triggered each rollout.The behavior is opt-in per NodeSet precisely because rolling on every config change is not always desired; clusters enable it only for the workers whose mounted config must be consistent with what
slurmdloaded.Change detection & events
status.configHashesmap keyed by<kind>/<name>(e.g.configmap/my-config) on the NodeSet. The fullslinky.slurm.net/...annotation key is used only for the pod-template stamp.applyConfigHashescompares the freshly computed checksums againststatus.configHashesand emits a NormalConfigHashChangedevent against the NodeSet when a tracked resource's content differs.syncNodeSetStatusrefreshes the map from the checksums stamped on the pod template.ControllerRevisionreads and no watch-time old/new diffing. The Secret/ConfigMap watch handlers are enqueue-only; they just trigger a reconcile so the controller can recompute and compare against persisted state.Implementation notes
internal/utils/confighash(reference discovery, length-safe annotation keys, key-aware hashing).status.configHashesfield onNodeSetStatus(CRDs + deepcopy regenerated).applyConfigHashesreconciler step wired intoSync; status persistence insyncNodeSetStatus.Test Plan
go build ./...,go vet ./internal/... ./api/...internal/utils/confighash,.../nodeset,.../nodeset/indexes,.../nodeset/eventhandler(event on status mismatch, no event when status matches, no event on first observation)ConfigHashChangedeventgo test -tags configrollout ./test/configrollout/against a kind cluster (Go port of the formerhack/verify-config-rollout.sh)