Preserve pre-existing node cordons across driver upgrades - #240
Open
ben-feldstein wants to merge 1 commit into
Open
Preserve pre-existing node cordons across driver upgrades#240ben-feldstein wants to merge 1 commit into
ben-feldstein wants to merge 1 commit into
Conversation
driver-manager unconditionally uncordons the node on both its success and failure paths, wiping any cordon that an administrator or another controller placed on the node before the driver pod ran. On a node reboot this happens on every restart of the init container. Record the node's schedulable state in the nvidia.com/driver-manager.node-initial-state.unschedulable annotation before cordoning, and have UncordonNode restore that state instead of blindly uncordoning. The annotation is written before the cordon and only when absent, so a restart of the init container after the cordon cannot overwrite the state recorded by the first run. When the annotation is absent, driver-manager never cordoned the node in any run, so any cordon present on the node is left in place. This mirrors the node-initial-state.unschedulable annotation used by the upgrade controller in k8s-operator-libs. Fixes NVIDIA#212 Signed-off-by: Ben Feldstein <ben.feldstein@baseten.co>
kvalliyurnatt
self-requested a review
August 24, 2026 19:41
kvalliyurnatt
requested changes
Aug 24, 2026
| } | ||
| } | ||
|
|
||
| return c.removeNodeAnnotation(nodeName, nodeInitialStateAnnotation) |
Contributor
There was a problem hiding this comment.
If uncordoning succeeds but annotation removal fails, a stale "false" annotation remains. If an administrator later cordons the node, the next UncordonNode may interpret that stale annotation as ownership and remove the administrator’s cordon. Could the uncordon and annotation removal be performed atomically in one Kubernetes patch?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #212.
Problem
driver-manager uncordons the node unconditionally on its success path, in
cleanupOnFailure(), and on the skip-eviction path that runs after a node reboot. It never checks whether the node was already cordoned before it acted. Any cordon placed by an administrator or another controller is therefore wiped whenever the driver pod is recreated, and on every node reboot. On the reboot path this is worst: driver-manager uncordons the node without ever having cordoned it.The upgrade controller in k8s-operator-libs already solves this with a
node-initial-state.unschedulableannotation and skips the uncordon for nodes that were cordoned before the upgrade started. driver-manager has no equivalent.Fix
I applied the same pattern to driver-manager.
CordonNodefirst records the node's current schedulable state in anvidia.com/driver-manager.node-initial-state.unschedulableannotation, then cordons. The annotation is written before the cordon and only when absent, so a restart of the init container after the cordon cannot overwrite the state recorded by the first run.UncordonNoderestores the recorded state instead of blindly uncordoning: it uncordons only when the annotation recordsfalse, skips the uncordon when it recordstrue, and removes the annotation in both cases. When the annotation is absent, driver-manager never cordoned the node in any run, so the node is left untouched.shouldSkipUninstallearly return now also runs the state-aware uncordon, so a cordon left by a crashed prior cycle is released and the annotation cleaned up. With the annotation absent this is a no-op.Notes
Testing
CordonNode/UncordonNodeagainst a fake clientset covering: cordon/uncordon round trip on a schedulable node, a pre-cordoned node staying cordoned through the uncordon, the recorded state surviving an init container restart, a stale recording on a schedulable node being reconciled, an uncordon with no prior cordon leaving an external cordon in place, and the recording never being overwritten while the node is unschedulable.go build ./...,go vet ./...(linux), andgo test ./...all pass.