Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
67f9528e
Commit
67f9528e
authored
Dec 17, 2018
by
Bobby (Babak) Salamat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix race in setting nominated node
parent
c75356fd
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
233 additions
and
89 deletions
+233
-89
generic_scheduler.go
pkg/scheduler/core/generic_scheduler.go
+2
-2
scheduling_queue.go
pkg/scheduler/internal/queue/scheduling_queue.go
+111
-65
scheduling_queue_test.go
pkg/scheduler/internal/queue/scheduling_queue_test.go
+112
-22
scheduler.go
pkg/scheduler/scheduler.go
+8
-0
No files found.
pkg/scheduler/core/generic_scheduler.go
View file @
67f9528e
...
@@ -351,7 +351,7 @@ func (g *genericScheduler) processPreemptionWithExtenders(
...
@@ -351,7 +351,7 @@ func (g *genericScheduler) processPreemptionWithExtenders(
// worth the complexity, especially because we generally expect to have a very
// worth the complexity, especially because we generally expect to have a very
// small number of nominated pods per node.
// small number of nominated pods per node.
func
(
g
*
genericScheduler
)
getLowerPriorityNominatedPods
(
pod
*
v1
.
Pod
,
nodeName
string
)
[]
*
v1
.
Pod
{
func
(
g
*
genericScheduler
)
getLowerPriorityNominatedPods
(
pod
*
v1
.
Pod
,
nodeName
string
)
[]
*
v1
.
Pod
{
pods
:=
g
.
schedulingQueue
.
Waiting
PodsForNode
(
nodeName
)
pods
:=
g
.
schedulingQueue
.
Nominated
PodsForNode
(
nodeName
)
if
len
(
pods
)
==
0
{
if
len
(
pods
)
==
0
{
return
nil
return
nil
...
@@ -501,7 +501,7 @@ func addNominatedPods(pod *v1.Pod, meta algorithm.PredicateMetadata,
...
@@ -501,7 +501,7 @@ func addNominatedPods(pod *v1.Pod, meta algorithm.PredicateMetadata,
// This may happen only in tests.
// This may happen only in tests.
return
false
,
meta
,
nodeInfo
return
false
,
meta
,
nodeInfo
}
}
nominatedPods
:=
queue
.
Waiting
PodsForNode
(
nodeInfo
.
Node
()
.
Name
)
nominatedPods
:=
queue
.
Nominated
PodsForNode
(
nodeInfo
.
Node
()
.
Name
)
if
nominatedPods
==
nil
||
len
(
nominatedPods
)
==
0
{
if
nominatedPods
==
nil
||
len
(
nominatedPods
)
==
0
{
return
false
,
meta
,
nodeInfo
return
false
,
meta
,
nodeInfo
}
}
...
...
pkg/scheduler/internal/queue/scheduling_queue.go
View file @
67f9528e
...
@@ -36,6 +36,7 @@ import (
...
@@ -36,6 +36,7 @@ import (
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
ktypes
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/cache"
podutil
"k8s.io/kubernetes/pkg/api/v1/pod"
podutil
"k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
...
@@ -62,11 +63,14 @@ type SchedulingQueue interface {
...
@@ -62,11 +63,14 @@ type SchedulingQueue interface {
MoveAllToActiveQueue
()
MoveAllToActiveQueue
()
AssignedPodAdded
(
pod
*
v1
.
Pod
)
AssignedPodAdded
(
pod
*
v1
.
Pod
)
AssignedPodUpdated
(
pod
*
v1
.
Pod
)
AssignedPodUpdated
(
pod
*
v1
.
Pod
)
Waiting
PodsForNode
(
nodeName
string
)
[]
*
v1
.
Pod
Nominated
PodsForNode
(
nodeName
string
)
[]
*
v1
.
Pod
WaitingPods
()
[]
*
v1
.
Pod
WaitingPods
()
[]
*
v1
.
Pod
// Close closes the SchedulingQueue so that the goroutine which is
// Close closes the SchedulingQueue so that the goroutine which is
// waiting to pop items can exit gracefully.
// waiting to pop items can exit gracefully.
Close
()
Close
()
// UpdateNominatedPodForNode adds the given pod to the nominated pod map or
// updates it if it already exists.
UpdateNominatedPodForNode
(
pod
*
v1
.
Pod
,
nodeName
string
)
// DeleteNominatedPodIfExists deletes nominatedPod from internal cache
// DeleteNominatedPodIfExists deletes nominatedPod from internal cache
DeleteNominatedPodIfExists
(
pod
*
v1
.
Pod
)
DeleteNominatedPodIfExists
(
pod
*
v1
.
Pod
)
// NumUnschedulablePods returns the number of unschedulable pods exist in the SchedulingQueue.
// NumUnschedulablePods returns the number of unschedulable pods exist in the SchedulingQueue.
...
@@ -150,9 +154,9 @@ func (f *FIFO) AssignedPodUpdated(pod *v1.Pod) {}
...
@@ -150,9 +154,9 @@ func (f *FIFO) AssignedPodUpdated(pod *v1.Pod) {}
// MoveAllToActiveQueue does nothing in FIFO as all pods are always in the active queue.
// MoveAllToActiveQueue does nothing in FIFO as all pods are always in the active queue.
func
(
f
*
FIFO
)
MoveAllToActiveQueue
()
{}
func
(
f
*
FIFO
)
MoveAllToActiveQueue
()
{}
//
Waiting
PodsForNode returns pods that are nominated to run on the given node,
//
Nominated
PodsForNode returns pods that are nominated to run on the given node,
// but FIFO does not support it.
// but FIFO does not support it.
func
(
f
*
FIFO
)
Waiting
PodsForNode
(
nodeName
string
)
[]
*
v1
.
Pod
{
func
(
f
*
FIFO
)
Nominated
PodsForNode
(
nodeName
string
)
[]
*
v1
.
Pod
{
return
nil
return
nil
}
}
...
@@ -164,6 +168,9 @@ func (f *FIFO) Close() {
...
@@ -164,6 +168,9 @@ func (f *FIFO) Close() {
// DeleteNominatedPodIfExists does nothing in FIFO.
// DeleteNominatedPodIfExists does nothing in FIFO.
func
(
f
*
FIFO
)
DeleteNominatedPodIfExists
(
pod
*
v1
.
Pod
)
{}
func
(
f
*
FIFO
)
DeleteNominatedPodIfExists
(
pod
*
v1
.
Pod
)
{}
// UpdateNominatedPodForNode does nothing in FIFO.
func
(
f
*
FIFO
)
UpdateNominatedPodForNode
(
pod
*
v1
.
Pod
,
nodeName
string
)
{}
// NumUnschedulablePods returns the number of unschedulable pods exist in the SchedulingQueue.
// NumUnschedulablePods returns the number of unschedulable pods exist in the SchedulingQueue.
func
(
f
*
FIFO
)
NumUnschedulablePods
()
int
{
func
(
f
*
FIFO
)
NumUnschedulablePods
()
int
{
return
0
return
0
...
@@ -194,10 +201,9 @@ type PriorityQueue struct {
...
@@ -194,10 +201,9 @@ type PriorityQueue struct {
activeQ
*
Heap
activeQ
*
Heap
// unschedulableQ holds pods that have been tried and determined unschedulable.
// unschedulableQ holds pods that have been tried and determined unschedulable.
unschedulableQ
*
UnschedulablePodsMap
unschedulableQ
*
UnschedulablePodsMap
// nominatedPods is a map keyed by a node name and the value is a list of
// nominatedPods is a structures that stores pods which are nominated to run
// pods which are nominated to run on the node. These are pods which can be in
// on nodes.
// the activeQ or unschedulableQ.
nominatedPods
*
nominatedPodMap
nominatedPods
map
[
string
][]
*
v1
.
Pod
// receivedMoveRequest is set to true whenever we receive a request to move a
// receivedMoveRequest is set to true whenever we receive a request to move a
// pod from the unschedulableQ to the activeQ, and is set to false, when we pop
// pod from the unschedulableQ to the activeQ, and is set to false, when we pop
// a pod from the activeQ. It indicates if we received a move request when a
// a pod from the activeQ. It indicates if we received a move request when a
...
@@ -239,52 +245,12 @@ func NewPriorityQueue() *PriorityQueue {
...
@@ -239,52 +245,12 @@ func NewPriorityQueue() *PriorityQueue {
pq
:=
&
PriorityQueue
{
pq
:=
&
PriorityQueue
{
activeQ
:
newHeap
(
cache
.
MetaNamespaceKeyFunc
,
activeQComp
),
activeQ
:
newHeap
(
cache
.
MetaNamespaceKeyFunc
,
activeQComp
),
unschedulableQ
:
newUnschedulablePodsMap
(),
unschedulableQ
:
newUnschedulablePodsMap
(),
nominatedPods
:
map
[
string
][]
*
v1
.
Pod
{}
,
nominatedPods
:
newNominatedPodMap
()
,
}
}
pq
.
cond
.
L
=
&
pq
.
lock
pq
.
cond
.
L
=
&
pq
.
lock
return
pq
return
pq
}
}
// addNominatedPodIfNeeded adds a pod to nominatedPods if it has a NominatedNodeName and it does not
// already exist in the map. Adding an existing pod is not going to update the pod.
func
(
p
*
PriorityQueue
)
addNominatedPodIfNeeded
(
pod
*
v1
.
Pod
)
{
nnn
:=
NominatedNodeName
(
pod
)
if
len
(
nnn
)
>
0
{
for
_
,
np
:=
range
p
.
nominatedPods
[
nnn
]
{
if
np
.
UID
==
pod
.
UID
{
klog
.
V
(
4
)
.
Infof
(
"Pod %v/%v already exists in the nominated map!"
,
pod
.
Namespace
,
pod
.
Name
)
return
}
}
p
.
nominatedPods
[
nnn
]
=
append
(
p
.
nominatedPods
[
nnn
],
pod
)
}
}
// deleteNominatedPodIfExists deletes a pod from the nominatedPods.
// NOTE: this function assumes lock has been acquired in caller.
func
(
p
*
PriorityQueue
)
deleteNominatedPodIfExists
(
pod
*
v1
.
Pod
)
{
nnn
:=
NominatedNodeName
(
pod
)
if
len
(
nnn
)
>
0
{
for
i
,
np
:=
range
p
.
nominatedPods
[
nnn
]
{
if
np
.
UID
==
pod
.
UID
{
p
.
nominatedPods
[
nnn
]
=
append
(
p
.
nominatedPods
[
nnn
][
:
i
],
p
.
nominatedPods
[
nnn
][
i
+
1
:
]
...
)
if
len
(
p
.
nominatedPods
[
nnn
])
==
0
{
delete
(
p
.
nominatedPods
,
nnn
)
}
break
}
}
}
}
// updateNominatedPod updates a pod in the nominatedPods.
func
(
p
*
PriorityQueue
)
updateNominatedPod
(
oldPod
,
newPod
*
v1
.
Pod
)
{
// Even if the nominated node name of the Pod is not changed, we must delete and add it again
// to ensure that its pointer is updated.
p
.
deleteNominatedPodIfExists
(
oldPod
)
p
.
addNominatedPodIfNeeded
(
newPod
)
}
// Add adds a pod to the active queue. It should be called only when a new pod
// Add adds a pod to the active queue. It should be called only when a new pod
// is added so there is no chance the pod is already in either queue.
// is added so there is no chance the pod is already in either queue.
func
(
p
*
PriorityQueue
)
Add
(
pod
*
v1
.
Pod
)
error
{
func
(
p
*
PriorityQueue
)
Add
(
pod
*
v1
.
Pod
)
error
{
...
@@ -296,10 +262,9 @@ func (p *PriorityQueue) Add(pod *v1.Pod) error {
...
@@ -296,10 +262,9 @@ func (p *PriorityQueue) Add(pod *v1.Pod) error {
}
else
{
}
else
{
if
p
.
unschedulableQ
.
get
(
pod
)
!=
nil
{
if
p
.
unschedulableQ
.
get
(
pod
)
!=
nil
{
klog
.
Errorf
(
"Error: pod %v/%v is already in the unschedulable queue."
,
pod
.
Namespace
,
pod
.
Name
)
klog
.
Errorf
(
"Error: pod %v/%v is already in the unschedulable queue."
,
pod
.
Namespace
,
pod
.
Name
)
p
.
deleteNominatedPodIfExists
(
pod
)
p
.
unschedulableQ
.
delete
(
pod
)
p
.
unschedulableQ
.
delete
(
pod
)
}
}
p
.
addNominatedPodIfNeeded
(
pod
)
p
.
nominatedPods
.
add
(
pod
,
""
)
p
.
cond
.
Broadcast
()
p
.
cond
.
Broadcast
()
}
}
return
err
return
err
...
@@ -320,7 +285,7 @@ func (p *PriorityQueue) AddIfNotPresent(pod *v1.Pod) error {
...
@@ -320,7 +285,7 @@ func (p *PriorityQueue) AddIfNotPresent(pod *v1.Pod) error {
if
err
!=
nil
{
if
err
!=
nil
{
klog
.
Errorf
(
"Error adding pod %v/%v to the scheduling queue: %v"
,
pod
.
Namespace
,
pod
.
Name
,
err
)
klog
.
Errorf
(
"Error adding pod %v/%v to the scheduling queue: %v"
,
pod
.
Namespace
,
pod
.
Name
,
err
)
}
else
{
}
else
{
p
.
addNominatedPodIfNeeded
(
pod
)
p
.
nominatedPods
.
add
(
pod
,
""
)
p
.
cond
.
Broadcast
()
p
.
cond
.
Broadcast
()
}
}
return
err
return
err
...
@@ -345,12 +310,12 @@ func (p *PriorityQueue) AddUnschedulableIfNotPresent(pod *v1.Pod) error {
...
@@ -345,12 +310,12 @@ func (p *PriorityQueue) AddUnschedulableIfNotPresent(pod *v1.Pod) error {
}
}
if
!
p
.
receivedMoveRequest
&&
isPodUnschedulable
(
pod
)
{
if
!
p
.
receivedMoveRequest
&&
isPodUnschedulable
(
pod
)
{
p
.
unschedulableQ
.
addOrUpdate
(
pod
)
p
.
unschedulableQ
.
addOrUpdate
(
pod
)
p
.
addNominatedPodIfNeeded
(
pod
)
p
.
nominatedPods
.
add
(
pod
,
""
)
return
nil
return
nil
}
}
err
:=
p
.
activeQ
.
Add
(
pod
)
err
:=
p
.
activeQ
.
Add
(
pod
)
if
err
==
nil
{
if
err
==
nil
{
p
.
addNominatedPodIfNeeded
(
pod
)
p
.
nominatedPods
.
add
(
pod
,
""
)
p
.
cond
.
Broadcast
()
p
.
cond
.
Broadcast
()
}
}
return
err
return
err
...
@@ -401,13 +366,13 @@ func (p *PriorityQueue) Update(oldPod, newPod *v1.Pod) error {
...
@@ -401,13 +366,13 @@ func (p *PriorityQueue) Update(oldPod, newPod *v1.Pod) error {
defer
p
.
lock
.
Unlock
()
defer
p
.
lock
.
Unlock
()
// If the pod is already in the active queue, just update it there.
// If the pod is already in the active queue, just update it there.
if
_
,
exists
,
_
:=
p
.
activeQ
.
Get
(
newPod
);
exists
{
if
_
,
exists
,
_
:=
p
.
activeQ
.
Get
(
newPod
);
exists
{
p
.
updateNominatedPod
(
oldPod
,
newPod
)
p
.
nominatedPods
.
update
(
oldPod
,
newPod
)
err
:=
p
.
activeQ
.
Update
(
newPod
)
err
:=
p
.
activeQ
.
Update
(
newPod
)
return
err
return
err
}
}
// If the pod is in the unschedulable queue, updating it may make it schedulable.
// If the pod is in the unschedulable queue, updating it may make it schedulable.
if
usPod
:=
p
.
unschedulableQ
.
get
(
newPod
);
usPod
!=
nil
{
if
usPod
:=
p
.
unschedulableQ
.
get
(
newPod
);
usPod
!=
nil
{
p
.
updateNominatedPod
(
oldPod
,
newPod
)
p
.
nominatedPods
.
update
(
oldPod
,
newPod
)
if
isPodUpdated
(
oldPod
,
newPod
)
{
if
isPodUpdated
(
oldPod
,
newPod
)
{
p
.
unschedulableQ
.
delete
(
usPod
)
p
.
unschedulableQ
.
delete
(
usPod
)
err
:=
p
.
activeQ
.
Add
(
newPod
)
err
:=
p
.
activeQ
.
Add
(
newPod
)
...
@@ -422,7 +387,7 @@ func (p *PriorityQueue) Update(oldPod, newPod *v1.Pod) error {
...
@@ -422,7 +387,7 @@ func (p *PriorityQueue) Update(oldPod, newPod *v1.Pod) error {
// If pod is not in any of the two queue, we put it in the active queue.
// If pod is not in any of the two queue, we put it in the active queue.
err
:=
p
.
activeQ
.
Add
(
newPod
)
err
:=
p
.
activeQ
.
Add
(
newPod
)
if
err
==
nil
{
if
err
==
nil
{
p
.
addNominatedPodIfNeeded
(
newPod
)
p
.
nominatedPods
.
add
(
newPod
,
""
)
p
.
cond
.
Broadcast
()
p
.
cond
.
Broadcast
()
}
}
return
err
return
err
...
@@ -433,7 +398,7 @@ func (p *PriorityQueue) Update(oldPod, newPod *v1.Pod) error {
...
@@ -433,7 +398,7 @@ func (p *PriorityQueue) Update(oldPod, newPod *v1.Pod) error {
func
(
p
*
PriorityQueue
)
Delete
(
pod
*
v1
.
Pod
)
error
{
func
(
p
*
PriorityQueue
)
Delete
(
pod
*
v1
.
Pod
)
error
{
p
.
lock
.
Lock
()
p
.
lock
.
Lock
()
defer
p
.
lock
.
Unlock
()
defer
p
.
lock
.
Unlock
()
p
.
deleteNominatedPodIfExists
(
pod
)
p
.
nominatedPods
.
delete
(
pod
)
err
:=
p
.
activeQ
.
Delete
(
pod
)
err
:=
p
.
activeQ
.
Delete
(
pod
)
if
err
!=
nil
{
// The item was probably not found in the activeQ.
if
err
!=
nil
{
// The item was probably not found in the activeQ.
p
.
unschedulableQ
.
delete
(
pod
)
p
.
unschedulableQ
.
delete
(
pod
)
...
@@ -516,16 +481,13 @@ func (p *PriorityQueue) getUnschedulablePodsWithMatchingAffinityTerm(pod *v1.Pod
...
@@ -516,16 +481,13 @@ func (p *PriorityQueue) getUnschedulablePodsWithMatchingAffinityTerm(pod *v1.Pod
return
podsToMove
return
podsToMove
}
}
//
Waiting
PodsForNode returns pods that are nominated to run on the given node,
//
Nominated
PodsForNode returns pods that are nominated to run on the given node,
// but they are waiting for other pods to be removed from the node before they
// but they are waiting for other pods to be removed from the node before they
// can be actually scheduled.
// can be actually scheduled.
func
(
p
*
PriorityQueue
)
Waiting
PodsForNode
(
nodeName
string
)
[]
*
v1
.
Pod
{
func
(
p
*
PriorityQueue
)
Nominated
PodsForNode
(
nodeName
string
)
[]
*
v1
.
Pod
{
p
.
lock
.
RLock
()
p
.
lock
.
RLock
()
defer
p
.
lock
.
RUnlock
()
defer
p
.
lock
.
RUnlock
()
if
list
,
ok
:=
p
.
nominatedPods
[
nodeName
];
ok
{
return
p
.
nominatedPods
.
podsForNode
(
nodeName
)
return
list
}
return
nil
}
}
// WaitingPods returns all the waiting pods in the queue.
// WaitingPods returns all the waiting pods in the queue.
...
@@ -551,10 +513,20 @@ func (p *PriorityQueue) Close() {
...
@@ -551,10 +513,20 @@ func (p *PriorityQueue) Close() {
p
.
cond
.
Broadcast
()
p
.
cond
.
Broadcast
()
}
}
// DeleteNominatedPodIfExists deletes pod
from internal cache if it's a nominatedPod
// DeleteNominatedPodIfExists deletes pod
nominatedPods.
func
(
p
*
PriorityQueue
)
DeleteNominatedPodIfExists
(
pod
*
v1
.
Pod
)
{
func
(
p
*
PriorityQueue
)
DeleteNominatedPodIfExists
(
pod
*
v1
.
Pod
)
{
p
.
lock
.
Lock
()
p
.
lock
.
Lock
()
p
.
deleteNominatedPodIfExists
(
pod
)
p
.
nominatedPods
.
delete
(
pod
)
p
.
lock
.
Unlock
()
}
// UpdateNominatedPodForNode adds a pod to the nominated pods of the given node.
// This is called during the preemption process after a node is nominated to run
// the pod. We update the structure before sending a request to update the pod
// object to avoid races with the following scheduling cycles.
func
(
p
*
PriorityQueue
)
UpdateNominatedPodForNode
(
pod
*
v1
.
Pod
,
nodeName
string
)
{
p
.
lock
.
Lock
()
p
.
nominatedPods
.
add
(
pod
,
nodeName
)
p
.
lock
.
Unlock
()
p
.
lock
.
Unlock
()
}
}
...
@@ -802,3 +774,77 @@ func newHeap(keyFn KeyFunc, lessFn LessFunc) *Heap {
...
@@ -802,3 +774,77 @@ func newHeap(keyFn KeyFunc, lessFn LessFunc) *Heap {
},
},
}
}
}
}
// nominatedPodMap is a structure that stores pods nominated to run on nodes.
// It exists because nominatedNodeName of pod objects stored in the structure
// may be different than what scheduler has here. We should be able to find pods
// by their UID and update/delete them.
type
nominatedPodMap
struct
{
// nominatedPods is a map keyed by a node name and the value is a list of
// pods which are nominated to run on the node. These are pods which can be in
// the activeQ or unschedulableQ.
nominatedPods
map
[
string
][]
*
v1
.
Pod
// nominatedPodToNode is map keyed by a Pod UID to the node name where it is
// nominated.
nominatedPodToNode
map
[
ktypes
.
UID
]
string
}
func
(
npm
*
nominatedPodMap
)
add
(
p
*
v1
.
Pod
,
nodeName
string
)
{
// always delete the pod if it already exist, to ensure we never store more than
// one instance of the pod.
npm
.
delete
(
p
)
nnn
:=
nodeName
if
len
(
nnn
)
==
0
{
nnn
=
NominatedNodeName
(
p
)
if
len
(
nnn
)
==
0
{
return
}
}
npm
.
nominatedPodToNode
[
p
.
UID
]
=
nnn
for
_
,
np
:=
range
npm
.
nominatedPods
[
nnn
]
{
if
np
.
UID
==
p
.
UID
{
klog
.
V
(
4
)
.
Infof
(
"Pod %v/%v already exists in the nominated map!"
,
p
.
Namespace
,
p
.
Name
)
return
}
}
npm
.
nominatedPods
[
nnn
]
=
append
(
npm
.
nominatedPods
[
nnn
],
p
)
}
func
(
npm
*
nominatedPodMap
)
delete
(
p
*
v1
.
Pod
)
{
nnn
,
ok
:=
npm
.
nominatedPodToNode
[
p
.
UID
]
if
!
ok
{
return
}
for
i
,
np
:=
range
npm
.
nominatedPods
[
nnn
]
{
if
np
.
UID
==
p
.
UID
{
npm
.
nominatedPods
[
nnn
]
=
append
(
npm
.
nominatedPods
[
nnn
][
:
i
],
npm
.
nominatedPods
[
nnn
][
i
+
1
:
]
...
)
if
len
(
npm
.
nominatedPods
[
nnn
])
==
0
{
delete
(
npm
.
nominatedPods
,
nnn
)
}
break
}
}
delete
(
npm
.
nominatedPodToNode
,
p
.
UID
)
}
func
(
npm
*
nominatedPodMap
)
update
(
oldPod
,
newPod
*
v1
.
Pod
)
{
// We update irrespective of the nominatedNodeName changed or not, to ensure
// that pod pointer is updated.
npm
.
delete
(
oldPod
)
npm
.
add
(
newPod
,
""
)
}
func
(
npm
*
nominatedPodMap
)
podsForNode
(
nodeName
string
)
[]
*
v1
.
Pod
{
if
list
,
ok
:=
npm
.
nominatedPods
[
nodeName
];
ok
{
return
list
}
return
nil
}
func
newNominatedPodMap
()
*
nominatedPodMap
{
return
&
nominatedPodMap
{
nominatedPods
:
make
(
map
[
string
][]
*
v1
.
Pod
),
nominatedPodToNode
:
make
(
map
[
ktypes
.
UID
]
string
),
}
}
pkg/scheduler/internal/queue/scheduling_queue_test.go
View file @
67f9528e
...
@@ -99,8 +99,14 @@ func TestPriorityQueue_Add(t *testing.T) {
...
@@ -99,8 +99,14 @@ func TestPriorityQueue_Add(t *testing.T) {
q
.
Add
(
&
medPriorityPod
)
q
.
Add
(
&
medPriorityPod
)
q
.
Add
(
&
unschedulablePod
)
q
.
Add
(
&
unschedulablePod
)
q
.
Add
(
&
highPriorityPod
)
q
.
Add
(
&
highPriorityPod
)
expectedNominatedPods
:=
map
[
string
][]
*
v1
.
Pod
{
expectedNominatedPods
:=
&
nominatedPodMap
{
"node1"
:
{
&
medPriorityPod
,
&
unschedulablePod
},
nominatedPodToNode
:
map
[
types
.
UID
]
string
{
medPriorityPod
.
UID
:
"node1"
,
unschedulablePod
.
UID
:
"node1"
,
},
nominatedPods
:
map
[
string
][]
*
v1
.
Pod
{
"node1"
:
{
&
medPriorityPod
,
&
unschedulablePod
},
},
}
}
if
!
reflect
.
DeepEqual
(
q
.
nominatedPods
,
expectedNominatedPods
)
{
if
!
reflect
.
DeepEqual
(
q
.
nominatedPods
,
expectedNominatedPods
)
{
t
.
Errorf
(
"Unexpected nominated map after adding pods. Expected: %v, got: %v"
,
expectedNominatedPods
,
q
.
nominatedPods
)
t
.
Errorf
(
"Unexpected nominated map after adding pods. Expected: %v, got: %v"
,
expectedNominatedPods
,
q
.
nominatedPods
)
...
@@ -114,8 +120,8 @@ func TestPriorityQueue_Add(t *testing.T) {
...
@@ -114,8 +120,8 @@ func TestPriorityQueue_Add(t *testing.T) {
if
p
,
err
:=
q
.
Pop
();
err
!=
nil
||
p
!=
&
unschedulablePod
{
if
p
,
err
:=
q
.
Pop
();
err
!=
nil
||
p
!=
&
unschedulablePod
{
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
unschedulablePod
.
Name
,
p
.
Name
)
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
unschedulablePod
.
Name
,
p
.
Name
)
}
}
if
len
(
q
.
nominatedPods
[
"node1"
])
!=
2
{
if
len
(
q
.
nominatedPods
.
nominatedPods
[
"node1"
])
!=
2
{
t
.
Errorf
(
"Expected medPriorityPod and unschedulablePod to be still present in nomindatePods: %v"
,
q
.
nominatedPods
[
"node1"
])
t
.
Errorf
(
"Expected medPriorityPod and unschedulablePod to be still present in nomindatePods: %v"
,
q
.
nominatedPods
.
nominatedPods
[
"node1"
])
}
}
}
}
...
@@ -125,8 +131,14 @@ func TestPriorityQueue_AddIfNotPresent(t *testing.T) {
...
@@ -125,8 +131,14 @@ func TestPriorityQueue_AddIfNotPresent(t *testing.T) {
q
.
AddIfNotPresent
(
&
highPriNominatedPod
)
// Must not add anything.
q
.
AddIfNotPresent
(
&
highPriNominatedPod
)
// Must not add anything.
q
.
AddIfNotPresent
(
&
medPriorityPod
)
q
.
AddIfNotPresent
(
&
medPriorityPod
)
q
.
AddIfNotPresent
(
&
unschedulablePod
)
q
.
AddIfNotPresent
(
&
unschedulablePod
)
expectedNominatedPods
:=
map
[
string
][]
*
v1
.
Pod
{
expectedNominatedPods
:=
&
nominatedPodMap
{
"node1"
:
{
&
medPriorityPod
,
&
unschedulablePod
},
nominatedPodToNode
:
map
[
types
.
UID
]
string
{
medPriorityPod
.
UID
:
"node1"
,
unschedulablePod
.
UID
:
"node1"
,
},
nominatedPods
:
map
[
string
][]
*
v1
.
Pod
{
"node1"
:
{
&
medPriorityPod
,
&
unschedulablePod
},
},
}
}
if
!
reflect
.
DeepEqual
(
q
.
nominatedPods
,
expectedNominatedPods
)
{
if
!
reflect
.
DeepEqual
(
q
.
nominatedPods
,
expectedNominatedPods
)
{
t
.
Errorf
(
"Unexpected nominated map after adding pods. Expected: %v, got: %v"
,
expectedNominatedPods
,
q
.
nominatedPods
)
t
.
Errorf
(
"Unexpected nominated map after adding pods. Expected: %v, got: %v"
,
expectedNominatedPods
,
q
.
nominatedPods
)
...
@@ -137,8 +149,8 @@ func TestPriorityQueue_AddIfNotPresent(t *testing.T) {
...
@@ -137,8 +149,8 @@ func TestPriorityQueue_AddIfNotPresent(t *testing.T) {
if
p
,
err
:=
q
.
Pop
();
err
!=
nil
||
p
!=
&
unschedulablePod
{
if
p
,
err
:=
q
.
Pop
();
err
!=
nil
||
p
!=
&
unschedulablePod
{
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
unschedulablePod
.
Name
,
p
.
Name
)
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
unschedulablePod
.
Name
,
p
.
Name
)
}
}
if
len
(
q
.
nominatedPods
[
"node1"
])
!=
2
{
if
len
(
q
.
nominatedPods
.
nominatedPods
[
"node1"
])
!=
2
{
t
.
Errorf
(
"Expected medPriorityPod and unschedulablePod to be still present in nomindatePods: %v"
,
q
.
nominatedPods
[
"node1"
])
t
.
Errorf
(
"Expected medPriorityPod and unschedulablePod to be still present in nomindatePods: %v"
,
q
.
nominatedPods
.
nominatedPods
[
"node1"
])
}
}
if
q
.
unschedulableQ
.
get
(
&
highPriNominatedPod
)
!=
&
highPriNominatedPod
{
if
q
.
unschedulableQ
.
get
(
&
highPriNominatedPod
)
!=
&
highPriNominatedPod
{
t
.
Errorf
(
"Pod %v was not found in the unschedulableQ."
,
highPriNominatedPod
.
Name
)
t
.
Errorf
(
"Pod %v was not found in the unschedulableQ."
,
highPriNominatedPod
.
Name
)
...
@@ -151,8 +163,15 @@ func TestPriorityQueue_AddUnschedulableIfNotPresent(t *testing.T) {
...
@@ -151,8 +163,15 @@ func TestPriorityQueue_AddUnschedulableIfNotPresent(t *testing.T) {
q
.
AddUnschedulableIfNotPresent
(
&
highPriNominatedPod
)
// Must not add anything.
q
.
AddUnschedulableIfNotPresent
(
&
highPriNominatedPod
)
// Must not add anything.
q
.
AddUnschedulableIfNotPresent
(
&
medPriorityPod
)
// This should go to activeQ.
q
.
AddUnschedulableIfNotPresent
(
&
medPriorityPod
)
// This should go to activeQ.
q
.
AddUnschedulableIfNotPresent
(
&
unschedulablePod
)
q
.
AddUnschedulableIfNotPresent
(
&
unschedulablePod
)
expectedNominatedPods
:=
map
[
string
][]
*
v1
.
Pod
{
expectedNominatedPods
:=
&
nominatedPodMap
{
"node1"
:
{
&
highPriNominatedPod
,
&
medPriorityPod
,
&
unschedulablePod
},
nominatedPodToNode
:
map
[
types
.
UID
]
string
{
medPriorityPod
.
UID
:
"node1"
,
unschedulablePod
.
UID
:
"node1"
,
highPriNominatedPod
.
UID
:
"node1"
,
},
nominatedPods
:
map
[
string
][]
*
v1
.
Pod
{
"node1"
:
{
&
highPriNominatedPod
,
&
medPriorityPod
,
&
unschedulablePod
},
},
}
}
if
!
reflect
.
DeepEqual
(
q
.
nominatedPods
,
expectedNominatedPods
)
{
if
!
reflect
.
DeepEqual
(
q
.
nominatedPods
,
expectedNominatedPods
)
{
t
.
Errorf
(
"Unexpected nominated map after adding pods. Expected: %v, got: %v"
,
expectedNominatedPods
,
q
.
nominatedPods
)
t
.
Errorf
(
"Unexpected nominated map after adding pods. Expected: %v, got: %v"
,
expectedNominatedPods
,
q
.
nominatedPods
)
...
@@ -163,7 +182,7 @@ func TestPriorityQueue_AddUnschedulableIfNotPresent(t *testing.T) {
...
@@ -163,7 +182,7 @@ func TestPriorityQueue_AddUnschedulableIfNotPresent(t *testing.T) {
if
p
,
err
:=
q
.
Pop
();
err
!=
nil
||
p
!=
&
medPriorityPod
{
if
p
,
err
:=
q
.
Pop
();
err
!=
nil
||
p
!=
&
medPriorityPod
{
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
medPriorityPod
.
Name
,
p
.
Name
)
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
medPriorityPod
.
Name
,
p
.
Name
)
}
}
if
len
(
q
.
nominatedPods
)
!=
1
{
if
len
(
q
.
nominatedPods
.
nominatedPods
)
!=
1
{
t
.
Errorf
(
"Expected nomindatePods to have one element: %v"
,
q
.
nominatedPods
)
t
.
Errorf
(
"Expected nomindatePods to have one element: %v"
,
q
.
nominatedPods
)
}
}
if
q
.
unschedulableQ
.
get
(
&
unschedulablePod
)
!=
&
unschedulablePod
{
if
q
.
unschedulableQ
.
get
(
&
unschedulablePod
)
!=
&
unschedulablePod
{
...
@@ -180,8 +199,8 @@ func TestPriorityQueue_Pop(t *testing.T) {
...
@@ -180,8 +199,8 @@ func TestPriorityQueue_Pop(t *testing.T) {
if
p
,
err
:=
q
.
Pop
();
err
!=
nil
||
p
!=
&
medPriorityPod
{
if
p
,
err
:=
q
.
Pop
();
err
!=
nil
||
p
!=
&
medPriorityPod
{
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
medPriorityPod
.
Name
,
p
.
Name
)
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
medPriorityPod
.
Name
,
p
.
Name
)
}
}
if
len
(
q
.
nominatedPods
[
"node1"
])
!=
1
{
if
len
(
q
.
nominatedPods
.
nominatedPods
[
"node1"
])
!=
1
{
t
.
Errorf
(
"Expected medPriorityPod to be present in nomindatePods: %v"
,
q
.
nominatedPods
[
"node1"
])
t
.
Errorf
(
"Expected medPriorityPod to be present in nomindatePods: %v"
,
q
.
nominatedPods
.
nominatedPods
[
"node1"
])
}
}
}()
}()
q
.
Add
(
&
medPriorityPod
)
q
.
Add
(
&
medPriorityPod
)
...
@@ -194,7 +213,7 @@ func TestPriorityQueue_Update(t *testing.T) {
...
@@ -194,7 +213,7 @@ func TestPriorityQueue_Update(t *testing.T) {
if
_
,
exists
,
_
:=
q
.
activeQ
.
Get
(
&
highPriorityPod
);
!
exists
{
if
_
,
exists
,
_
:=
q
.
activeQ
.
Get
(
&
highPriorityPod
);
!
exists
{
t
.
Errorf
(
"Expected %v to be added to activeQ."
,
highPriorityPod
.
Name
)
t
.
Errorf
(
"Expected %v to be added to activeQ."
,
highPriorityPod
.
Name
)
}
}
if
len
(
q
.
nominatedPods
)
!=
0
{
if
len
(
q
.
nominatedPods
.
nominatedPods
)
!=
0
{
t
.
Errorf
(
"Expected nomindatePods to be empty: %v"
,
q
.
nominatedPods
)
t
.
Errorf
(
"Expected nomindatePods to be empty: %v"
,
q
.
nominatedPods
)
}
}
// Update highPriorityPod and add a nominatedNodeName to it.
// Update highPriorityPod and add a nominatedNodeName to it.
...
@@ -202,7 +221,7 @@ func TestPriorityQueue_Update(t *testing.T) {
...
@@ -202,7 +221,7 @@ func TestPriorityQueue_Update(t *testing.T) {
if
q
.
activeQ
.
data
.
Len
()
!=
1
{
if
q
.
activeQ
.
data
.
Len
()
!=
1
{
t
.
Error
(
"Expected only one item in activeQ."
)
t
.
Error
(
"Expected only one item in activeQ."
)
}
}
if
len
(
q
.
nominatedPods
)
!=
1
{
if
len
(
q
.
nominatedPods
.
nominatedPods
)
!=
1
{
t
.
Errorf
(
"Expected one item in nomindatePods map: %v"
,
q
.
nominatedPods
)
t
.
Errorf
(
"Expected one item in nomindatePods map: %v"
,
q
.
nominatedPods
)
}
}
// Updating an unschedulable pod which is not in any of the two queues, should
// Updating an unschedulable pod which is not in any of the two queues, should
...
@@ -235,11 +254,13 @@ func TestPriorityQueue_Delete(t *testing.T) {
...
@@ -235,11 +254,13 @@ func TestPriorityQueue_Delete(t *testing.T) {
if
_
,
exists
,
_
:=
q
.
activeQ
.
Get
(
&
highPriNominatedPod
);
exists
{
if
_
,
exists
,
_
:=
q
.
activeQ
.
Get
(
&
highPriNominatedPod
);
exists
{
t
.
Errorf
(
"Didn't expect %v to be in activeQ."
,
highPriorityPod
.
Name
)
t
.
Errorf
(
"Didn't expect %v to be in activeQ."
,
highPriorityPod
.
Name
)
}
}
if
len
(
q
.
nominatedPods
)
!=
1
{
if
len
(
q
.
nominatedPods
.
nominatedPods
)
!=
1
{
t
.
Errorf
(
"Expected nomindatePods to have only 'unschedulablePod': %v"
,
q
.
nominatedPods
)
t
.
Errorf
(
"Expected nomindatePods to have only 'unschedulablePod': %v"
,
q
.
nominatedPods
.
nominatedPods
)
}
if
err
:=
q
.
Delete
(
&
unschedulablePod
);
err
!=
nil
{
t
.
Errorf
(
"delete failed: %v"
,
err
)
}
}
q
.
Delete
(
&
unschedulablePod
)
if
len
(
q
.
nominatedPods
.
nominatedPods
)
!=
0
{
if
len
(
q
.
nominatedPods
)
!=
0
{
t
.
Errorf
(
"Expected nomindatePods to be empty: %v"
,
q
.
nominatedPods
)
t
.
Errorf
(
"Expected nomindatePods to be empty: %v"
,
q
.
nominatedPods
)
}
}
}
}
...
@@ -311,7 +332,7 @@ func TestPriorityQueue_AssignedPodAdded(t *testing.T) {
...
@@ -311,7 +332,7 @@ func TestPriorityQueue_AssignedPodAdded(t *testing.T) {
}
}
}
}
func
TestPriorityQueue_
Waiting
PodsForNode
(
t
*
testing
.
T
)
{
func
TestPriorityQueue_
Nominated
PodsForNode
(
t
*
testing
.
T
)
{
q
:=
NewPriorityQueue
()
q
:=
NewPriorityQueue
()
q
.
Add
(
&
medPriorityPod
)
q
.
Add
(
&
medPriorityPod
)
q
.
Add
(
&
unschedulablePod
)
q
.
Add
(
&
unschedulablePod
)
...
@@ -320,14 +341,83 @@ func TestPriorityQueue_WaitingPodsForNode(t *testing.T) {
...
@@ -320,14 +341,83 @@ func TestPriorityQueue_WaitingPodsForNode(t *testing.T) {
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
highPriorityPod
.
Name
,
p
.
Name
)
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
highPriorityPod
.
Name
,
p
.
Name
)
}
}
expectedList
:=
[]
*
v1
.
Pod
{
&
medPriorityPod
,
&
unschedulablePod
}
expectedList
:=
[]
*
v1
.
Pod
{
&
medPriorityPod
,
&
unschedulablePod
}
if
!
reflect
.
DeepEqual
(
expectedList
,
q
.
Waiting
PodsForNode
(
"node1"
))
{
if
!
reflect
.
DeepEqual
(
expectedList
,
q
.
Nominated
PodsForNode
(
"node1"
))
{
t
.
Error
(
"Unexpected list of nominated Pods for node."
)
t
.
Error
(
"Unexpected list of nominated Pods for node."
)
}
}
if
q
.
Waiting
PodsForNode
(
"node2"
)
!=
nil
{
if
q
.
Nominated
PodsForNode
(
"node2"
)
!=
nil
{
t
.
Error
(
"Expected list of nominated Pods for node2 to be empty."
)
t
.
Error
(
"Expected list of nominated Pods for node2 to be empty."
)
}
}
}
}
func
TestPriorityQueue_UpdateNominatedPodForNode
(
t
*
testing
.
T
)
{
q
:=
NewPriorityQueue
()
if
err
:=
q
.
Add
(
&
medPriorityPod
);
err
!=
nil
{
t
.
Errorf
(
"add failed: %v"
,
err
)
}
// Update unschedulablePod on a different node than specified in the pod.
q
.
UpdateNominatedPodForNode
(
&
unschedulablePod
,
"node5"
)
// Update nominated node name of a pod on a node that is not specified in the pod object.
q
.
UpdateNominatedPodForNode
(
&
highPriorityPod
,
"node2"
)
expectedNominatedPods
:=
&
nominatedPodMap
{
nominatedPodToNode
:
map
[
types
.
UID
]
string
{
medPriorityPod
.
UID
:
"node1"
,
highPriorityPod
.
UID
:
"node2"
,
unschedulablePod
.
UID
:
"node5"
,
},
nominatedPods
:
map
[
string
][]
*
v1
.
Pod
{
"node1"
:
{
&
medPriorityPod
},
"node2"
:
{
&
highPriorityPod
},
"node5"
:
{
&
unschedulablePod
},
},
}
if
!
reflect
.
DeepEqual
(
q
.
nominatedPods
,
expectedNominatedPods
)
{
t
.
Errorf
(
"Unexpected nominated map after adding pods. Expected: %v, got: %v"
,
expectedNominatedPods
,
q
.
nominatedPods
)
}
if
p
,
err
:=
q
.
Pop
();
err
!=
nil
||
p
!=
&
medPriorityPod
{
t
.
Errorf
(
"Expected: %v after Pop, but got: %v"
,
medPriorityPod
.
Name
,
p
.
Name
)
}
// List of nominated pods shouldn't change after popping them from the queue.
if
!
reflect
.
DeepEqual
(
q
.
nominatedPods
,
expectedNominatedPods
)
{
t
.
Errorf
(
"Unexpected nominated map after popping pods. Expected: %v, got: %v"
,
expectedNominatedPods
,
q
.
nominatedPods
)
}
// Update one of the nominated pods that doesn't have nominatedNodeName in the
// pod object. It should be updated correctly.
q
.
UpdateNominatedPodForNode
(
&
highPriorityPod
,
"node4"
)
expectedNominatedPods
=
&
nominatedPodMap
{
nominatedPodToNode
:
map
[
types
.
UID
]
string
{
medPriorityPod
.
UID
:
"node1"
,
highPriorityPod
.
UID
:
"node4"
,
unschedulablePod
.
UID
:
"node5"
,
},
nominatedPods
:
map
[
string
][]
*
v1
.
Pod
{
"node1"
:
{
&
medPriorityPod
},
"node4"
:
{
&
highPriorityPod
},
"node5"
:
{
&
unschedulablePod
},
},
}
if
!
reflect
.
DeepEqual
(
q
.
nominatedPods
,
expectedNominatedPods
)
{
t
.
Errorf
(
"Unexpected nominated map after updating pods. Expected: %v, got: %v"
,
expectedNominatedPods
,
q
.
nominatedPods
)
}
// Delete a nominated pod that doesn't have nominatedNodeName in the pod
// object. It should be deleted.
q
.
DeleteNominatedPodIfExists
(
&
highPriorityPod
)
expectedNominatedPods
=
&
nominatedPodMap
{
nominatedPodToNode
:
map
[
types
.
UID
]
string
{
medPriorityPod
.
UID
:
"node1"
,
unschedulablePod
.
UID
:
"node5"
,
},
nominatedPods
:
map
[
string
][]
*
v1
.
Pod
{
"node1"
:
{
&
medPriorityPod
},
"node5"
:
{
&
unschedulablePod
},
},
}
if
!
reflect
.
DeepEqual
(
q
.
nominatedPods
,
expectedNominatedPods
)
{
t
.
Errorf
(
"Unexpected nominated map after deleting pods. Expected: %v, got: %v"
,
expectedNominatedPods
,
q
.
nominatedPods
)
}
}
func
TestUnschedulablePodsMap
(
t
*
testing
.
T
)
{
func
TestUnschedulablePodsMap
(
t
*
testing
.
T
)
{
var
pods
=
[]
*
v1
.
Pod
{
var
pods
=
[]
*
v1
.
Pod
{
{
{
...
...
pkg/scheduler/scheduler.go
View file @
67f9528e
...
@@ -328,11 +328,19 @@ func (sched *Scheduler) preempt(preemptor *v1.Pod, scheduleErr error) (string, e
...
@@ -328,11 +328,19 @@ func (sched *Scheduler) preempt(preemptor *v1.Pod, scheduleErr error) (string, e
var
nodeName
=
""
var
nodeName
=
""
if
node
!=
nil
{
if
node
!=
nil
{
nodeName
=
node
.
Name
nodeName
=
node
.
Name
// Update the scheduling queue with the nominated pod information. Without
// this, there would be a race condition between the next scheduling cycle
// and the time the scheduler receives a Pod Update for the nominated pod.
sched
.
config
.
SchedulingQueue
.
UpdateNominatedPodForNode
(
preemptor
,
nodeName
)
// Make a call to update nominated node name of the pod on the API server.
err
=
sched
.
config
.
PodPreemptor
.
SetNominatedNodeName
(
preemptor
,
nodeName
)
err
=
sched
.
config
.
PodPreemptor
.
SetNominatedNodeName
(
preemptor
,
nodeName
)
if
err
!=
nil
{
if
err
!=
nil
{
klog
.
Errorf
(
"Error in preemption process. Cannot update pod %v/%v annotations: %v"
,
preemptor
.
Namespace
,
preemptor
.
Name
,
err
)
klog
.
Errorf
(
"Error in preemption process. Cannot update pod %v/%v annotations: %v"
,
preemptor
.
Namespace
,
preemptor
.
Name
,
err
)
sched
.
config
.
SchedulingQueue
.
DeleteNominatedPodIfExists
(
preemptor
)
return
""
,
err
return
""
,
err
}
}
for
_
,
victim
:=
range
victims
{
for
_
,
victim
:=
range
victims
{
if
err
:=
sched
.
config
.
PodPreemptor
.
DeletePod
(
victim
);
err
!=
nil
{
if
err
:=
sched
.
config
.
PodPreemptor
.
DeletePod
(
victim
);
err
!=
nil
{
klog
.
Errorf
(
"Error preempting pod %v/%v: %v"
,
victim
.
Namespace
,
victim
.
Name
,
err
)
klog
.
Errorf
(
"Error preempting pod %v/%v: %v"
,
victim
.
Namespace
,
victim
.
Name
,
err
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment