Merge pull request #133749 from xigang/automated-cherry-pick-of-#132477-upstream-release-1.34

Automated cherry pick of #132477: Fix DaemonSet misscheduled status not updating on node taint changes
This commit is contained in:
Kubernetes Prow Robot
2025-09-04 05:45:16 -07:00
committed by GitHub
2 changed files with 34 additions and 1 deletions

View File

@@ -1445,7 +1445,15 @@ func (dsc *DaemonSetsController) syncNodeUpdate(ctx context.Context, nodeName st
daemonPods := podsByDS[dsKey]
scheduled := len(daemonPods) > 0
if (shouldRun && !scheduled) || (!shouldContinueRunning && scheduled) {
// Enqueue DaemonSet for sync in the following scenarios:
// 1. (shouldRun && !scheduled): Node now meets scheduling requirements but no pod exists
// - Need to create a new pod on this node
// 2. (!shouldContinueRunning && scheduled): Node no longer meets requirements but pod exists
// - Need to delete the existing pod from this node
// 3. (scheduled && ds.Status.NumberMisscheduled > 0): DaemonSet pod exists and misscheduled count is nonzero.
// - For example: a pod was scheduled before the node became unready and tainted; after the node becomes ready and taints are removed, the pod may now be valid again.
// - Need to recalculate NumberMisscheduled to ensure the DaemonSet status accurately reflects the current scheduling state.
if (shouldRun && !scheduled) || (!shouldContinueRunning && scheduled) || (scheduled && ds.Status.NumberMisscheduled > 0) {
dsc.enqueueDaemonSet(ds)
}
}

View File

@@ -2410,6 +2410,9 @@ func TestUpdateNode(t *testing.T) {
expectedEventsFunc func(strategyType apps.DaemonSetUpdateStrategyType) int
shouldEnqueue bool
expectedCreates func() int
// Indicates whether a DaemonSet pod was already present on the node before the node transitioned to Ready and schedulable state.
// (In other words, was the DaemonSet pod scheduled before the node lost its readiness / was tainted?)
preExistingPod bool
}{
{
test: "Nothing changed, should not enqueue",
@@ -2422,6 +2425,7 @@ func TestUpdateNode(t *testing.T) {
}(),
shouldEnqueue: false,
expectedCreates: func() int { return 0 },
preExistingPod: false,
},
{
test: "Node labels changed",
@@ -2434,6 +2438,7 @@ func TestUpdateNode(t *testing.T) {
}(),
shouldEnqueue: true,
expectedCreates: func() int { return 0 },
preExistingPod: false,
},
{
test: "Node taints changed",
@@ -2446,6 +2451,7 @@ func TestUpdateNode(t *testing.T) {
ds: newDaemonSet("ds"),
shouldEnqueue: true,
expectedCreates: func() int { return 0 },
preExistingPod: false,
},
{
test: "Node Allocatable changed",
@@ -2475,6 +2481,21 @@ func TestUpdateNode(t *testing.T) {
expectedCreates: func() int {
return 1
},
preExistingPod: false,
},
{
test: "Pod transitions from misscheduled to scheduled due to node label change",
oldNode: newNode("node1", nil),
newNode: newNode("node1", simpleNodeLabel),
ds: func() *apps.DaemonSet {
ds := newDaemonSet("ds")
ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
ds.Status.NumberMisscheduled = 1
return ds
}(),
shouldEnqueue: true,
expectedCreates: func() int { return 0 },
preExistingPod: true,
},
}
for _, c := range cases {
@@ -2511,6 +2532,10 @@ func TestUpdateNode(t *testing.T) {
}
expectSyncDaemonSets(t, manager, c.ds, podControl, expectedCreates, 0, expectedEvents)
if c.preExistingPod {
addPods(manager.podStore, c.oldNode.Name, simpleDaemonSetLabel, c.ds, 1)
}
manager.enqueueDaemonSet = func(ds *apps.DaemonSet) {
if ds.Name == "ds" {
enqueued = true