From 042b83ba73e6e5fca6285abdc6c6074be257af8b Mon Sep 17 00:00:00 2001 From: Jun Gong Date: Wed, 20 Mar 2019 21:11:26 +0800 Subject: [PATCH] Pick pods for preemption based on StartTime of pods when priorities are equal --- pkg/scheduler/core/extender_test.go | 2 +- pkg/scheduler/core/generic_scheduler.go | 2 +- pkg/scheduler/core/generic_scheduler_test.go | 13 +++++++++++++ pkg/scheduler/util/utils.go | 16 +++++++++++----- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/pkg/scheduler/core/extender_test.go b/pkg/scheduler/core/extender_test.go index bd24d3b9f46..97ece6448d2 100644 --- a/pkg/scheduler/core/extender_test.go +++ b/pkg/scheduler/core/extender_test.go @@ -197,7 +197,7 @@ func (f *FakeExtender) selectVictimsOnNodeByExtender( // and get cached node info by given node name. nodeInfoCopy := f.cachedNodeNameToInfo[node.GetName()].Clone() - potentialVictims := util.SortableList{CompFunc: util.HigherPriorityPod} + potentialVictims := util.SortableList{CompFunc: util.MoreImportantPod} removePod := func(rp *v1.Pod) { nodeInfoCopy.RemovePod(rp) diff --git a/pkg/scheduler/core/generic_scheduler.go b/pkg/scheduler/core/generic_scheduler.go index e84cf3fcd0b..b5c44cf9725 100644 --- a/pkg/scheduler/core/generic_scheduler.go +++ b/pkg/scheduler/core/generic_scheduler.go @@ -1046,7 +1046,7 @@ func selectVictimsOnNode( if nodeInfo == nil { return nil, 0, false } - potentialVictims := util.SortableList{CompFunc: util.HigherPriorityPod} + potentialVictims := util.SortableList{CompFunc: util.MoreImportantPod} nodeInfoCopy := nodeInfo.Clone() removePod := func(rp *v1.Pod) { diff --git a/pkg/scheduler/core/generic_scheduler_test.go b/pkg/scheduler/core/generic_scheduler_test.go index 3a7683dd928..2a7d9cf424a 100644 --- a/pkg/scheduler/core/generic_scheduler_test.go +++ b/pkg/scheduler/core/generic_scheduler_test.go @@ -946,6 +946,19 @@ func TestSelectNodesForPreemption(t *testing.T) { {ObjectMeta: metav1.ObjectMeta{Name: "e", UID: types.UID("e")}, Spec: v1.PodSpec{Containers: largeContainers, Priority: &highPriority, NodeName: "machine2"}}}, expected: map[string]map[string]bool{"machine1": {"b": true, "c": true}}, }, + { + name: "mixed priority pods are preempted, pick later StartTime one when priorities are equal", + predicates: map[string]algorithmpredicates.FitPredicate{"matches": algorithmpredicates.PodFitsResources}, + nodes: []string{"machine1", "machine2"}, + pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}, Spec: v1.PodSpec{Containers: largeContainers, Priority: &highPriority}}, + pods: []*v1.Pod{ + {ObjectMeta: metav1.ObjectMeta{Name: "a", UID: types.UID("a")}, Spec: v1.PodSpec{Containers: smallContainers, Priority: &lowPriority, NodeName: "machine1"}, Status: v1.PodStatus{StartTime: &startTime20190107}}, + {ObjectMeta: metav1.ObjectMeta{Name: "b", UID: types.UID("b")}, Spec: v1.PodSpec{Containers: smallContainers, Priority: &lowPriority, NodeName: "machine1"}, Status: v1.PodStatus{StartTime: &startTime20190106}}, + {ObjectMeta: metav1.ObjectMeta{Name: "c", UID: types.UID("c")}, Spec: v1.PodSpec{Containers: mediumContainers, Priority: &midPriority, NodeName: "machine1"}, Status: v1.PodStatus{StartTime: &startTime20190105}}, + {ObjectMeta: metav1.ObjectMeta{Name: "d", UID: types.UID("d")}, Spec: v1.PodSpec{Containers: smallContainers, Priority: &highPriority, NodeName: "machine1"}, Status: v1.PodStatus{StartTime: &startTime20190104}}, + {ObjectMeta: metav1.ObjectMeta{Name: "e", UID: types.UID("e")}, Spec: v1.PodSpec{Containers: largeContainers, Priority: &highPriority, NodeName: "machine2"}, Status: v1.PodStatus{StartTime: &startTime20190103}}}, + expected: map[string]map[string]bool{"machine1": {"a": true, "c": true}}, + }, { name: "pod with anti-affinity is preempted", predicates: map[string]algorithmpredicates.FitPredicate{"matches": algorithmpredicates.PodFitsResources}, diff --git a/pkg/scheduler/util/utils.go b/pkg/scheduler/util/utils.go index b32eadb515f..4ccd3220c3f 100644 --- a/pkg/scheduler/util/utils.go +++ b/pkg/scheduler/util/utils.go @@ -134,9 +134,15 @@ func (l *SortableList) Sort() { sort.Sort(l) } -// HigherPriorityPod return true when priority of the first pod is higher than -// the second one. It takes arguments of the type "interface{}" to be used with -// SortableList, but expects those arguments to be *v1.Pod. -func HigherPriorityPod(pod1, pod2 interface{}) bool { - return GetPodPriority(pod1.(*v1.Pod)) > GetPodPriority(pod2.(*v1.Pod)) +// MoreImportantPod return true when priority of the first pod is higher than +// the second one. If two pods' priorities are equal, compare their StartTime. +// It takes arguments of the type "interface{}" to be used with SortableList, +// but expects those arguments to be *v1.Pod. +func MoreImportantPod(pod1, pod2 interface{}) bool { + p1 := GetPodPriority(pod1.(*v1.Pod)) + p2 := GetPodPriority(pod2.(*v1.Pod)) + if p1 != p2 { + return p1 > p2 + } + return GetPodStartTime(pod1.(*v1.Pod)).Before(GetPodStartTime(pod2.(*v1.Pod))) }