mirror of https://github.com/k3s-io/k3s
Delete only unscheduled pods if node doesn't exist anymore.
parent
b7394102d6
commit
319930fe97
|
@ -964,10 +964,10 @@ func (dsc *DaemonSetsController) manage(ds *apps.DaemonSet, hash string) error {
|
||||||
failedPodsObserved += failedPodsObservedOnNode
|
failedPodsObserved += failedPodsObservedOnNode
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove pods assigned to not existing nodes when daemonset pods are scheduled by default scheduler.
|
// Remove unscheduled pods assigned to not existing nodes when daemonset pods are scheduled by scheduler.
|
||||||
// If node doesn't exist then pods are never scheduled and can't be deleted by PodGCController.
|
// If node doesn't exist then pods are never scheduled and can't be deleted by PodGCController.
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
|
if utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
|
||||||
podsToDelete = append(podsToDelete, getPodsWithoutNode(nodeList, nodeToDaemonPods)...)
|
podsToDelete = append(podsToDelete, getUnscheduledPodsWithoutNode(nodeList, nodeToDaemonPods)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Label new pods using the hash label value of the current history when creating them
|
// Label new pods using the hash label value of the current history when creating them
|
||||||
|
@ -1531,8 +1531,9 @@ func failedPodsBackoffKey(ds *apps.DaemonSet, nodeName string) string {
|
||||||
return fmt.Sprintf("%s/%d/%s", ds.UID, ds.Status.ObservedGeneration, nodeName)
|
return fmt.Sprintf("%s/%d/%s", ds.UID, ds.Status.ObservedGeneration, nodeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPodsWithoutNode returns list of pods assigned to not existing nodes.
|
// getUnscheduledPodsWithoutNode returns list of unscheduled pods assigned to not existing nodes.
|
||||||
func getPodsWithoutNode(runningNodesList []*v1.Node, nodeToDaemonPods map[string][]*v1.Pod) []string {
|
// Returned pods can't be deleted by PodGCController so they should be deleted by DaemonSetController.
|
||||||
|
func getUnscheduledPodsWithoutNode(runningNodesList []*v1.Node, nodeToDaemonPods map[string][]*v1.Pod) []string {
|
||||||
var results []string
|
var results []string
|
||||||
isNodeRunning := make(map[string]bool)
|
isNodeRunning := make(map[string]bool)
|
||||||
for _, node := range runningNodesList {
|
for _, node := range runningNodesList {
|
||||||
|
@ -1541,7 +1542,9 @@ func getPodsWithoutNode(runningNodesList []*v1.Node, nodeToDaemonPods map[string
|
||||||
for n, pods := range nodeToDaemonPods {
|
for n, pods := range nodeToDaemonPods {
|
||||||
if !isNodeRunning[n] {
|
if !isNodeRunning[n] {
|
||||||
for _, pod := range pods {
|
for _, pod := range pods {
|
||||||
results = append(results, pod.Name)
|
if len(pod.Spec.NodeName) == 0 {
|
||||||
|
results = append(results, pod.Name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2447,7 +2447,7 @@ func TestDeleteNoDaemonPod(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeletePodForNotExistingNode(t *testing.T) {
|
func TestDeleteUnscheduledPodForNotExistingNode(t *testing.T) {
|
||||||
for _, f := range []bool{true, false} {
|
for _, f := range []bool{true, false} {
|
||||||
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
|
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
|
||||||
for _, strategy := range updateStrategies() {
|
for _, strategy := range updateStrategies() {
|
||||||
|
@ -2461,6 +2461,26 @@ func TestDeletePodForNotExistingNode(t *testing.T) {
|
||||||
addNodes(manager.nodeStore, 0, 1, nil)
|
addNodes(manager.nodeStore, 0, 1, nil)
|
||||||
addPods(manager.podStore, "node-0", simpleDaemonSetLabel, ds, 1)
|
addPods(manager.podStore, "node-0", simpleDaemonSetLabel, ds, 1)
|
||||||
addPods(manager.podStore, "node-1", simpleDaemonSetLabel, ds, 1)
|
addPods(manager.podStore, "node-1", simpleDaemonSetLabel, ds, 1)
|
||||||
|
|
||||||
|
podScheduledUsingAffinity := newPod("pod1-node-3", "", simpleDaemonSetLabel, ds)
|
||||||
|
podScheduledUsingAffinity.Spec.Affinity = &v1.Affinity{
|
||||||
|
NodeAffinity: &v1.NodeAffinity{
|
||||||
|
RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{
|
||||||
|
NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
|
{
|
||||||
|
MatchFields: []v1.NodeSelectorRequirement{
|
||||||
|
{
|
||||||
|
Key: schedulerapi.NodeFieldSelectorKeyNodeName,
|
||||||
|
Operator: v1.NodeSelectorOpIn,
|
||||||
|
Values: []string{"node-2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
manager.podStore.Add(podScheduledUsingAffinity)
|
||||||
if f {
|
if f {
|
||||||
syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 1, 0)
|
syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 1, 0)
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue