@@ -31,6 +31,8 @@ import (
31
31
"k8s.io/apimachinery/pkg/labels"
32
32
"k8s.io/apimachinery/pkg/runtime"
33
33
utilfeature "k8s.io/apiserver/pkg/util/feature"
34
+ "k8s.io/client-go/informers"
35
+ policylisters "k8s.io/client-go/listers/policy/v1beta1"
34
36
extenderv1 "k8s.io/kube-scheduler/extender/v1"
35
37
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
36
38
kubefeatures "k8s.io/kubernetes/pkg/features"
@@ -48,7 +50,8 @@ const (
48
50
49
51
// DefaultPreemption is a PostFilter plugin implements the preemption logic.
50
52
type DefaultPreemption struct {
51
- fh framework.FrameworkHandle
53
+ fh framework.FrameworkHandle
54
+ pdbLister policylisters.PodDisruptionBudgetLister
52
55
}
53
56
54
57
var _ framework.PostFilterPlugin = & DefaultPreemption {}
@@ -60,10 +63,9 @@ func (pl *DefaultPreemption) Name() string {
60
63
61
64
// New initializes a new plugin and returns it.
62
65
func New (_ runtime.Object , fh framework.FrameworkHandle ) (framework.Plugin , error ) {
63
- pl := DefaultPreemption {fh }
64
- if utilfeature .DefaultFeatureGate .Enabled (kubefeatures .PodDisruptionBudget ) {
65
- // A hack to initialize pdbLister in sharedInformerFactory.
66
- fh .SharedInformerFactory ().Policy ().V1beta1 ().PodDisruptionBudgets ().Lister ()
66
+ pl := DefaultPreemption {
67
+ fh : fh ,
68
+ pdbLister : getPDBLister (fh .SharedInformerFactory ()),
67
69
}
68
70
return & pl , nil
69
71
}
@@ -77,7 +79,7 @@ func (pl *DefaultPreemption) PostFilter(ctx context.Context, state *framework.Cy
77
79
metrics .DeprecatedSchedulingDuration .WithLabelValues (metrics .PreemptionEvaluation ).Observe (metrics .SinceInSeconds (preemptionStartTime ))
78
80
}()
79
81
80
- nnn , err := preempt (ctx , pl . fh , state , pod , m )
82
+ nnn , err := pl . preempt (ctx , state , pod , m )
81
83
if err != nil {
82
84
return nil , framework .NewStatus (framework .Error , err .Error ())
83
85
}
@@ -97,20 +99,20 @@ func (pl *DefaultPreemption) PostFilter(ctx context.Context, state *framework.Cy
97
99
// other pods with the same priority. The nominated pod prevents other pods from
98
100
// using the nominated resources and the nominated pod could take a long time
99
101
// before it is retried after many other pending pods.
100
- func preempt (ctx context.Context , fh framework. FrameworkHandle , state * framework.CycleState , pod * v1.Pod , m framework.NodeToStatusMap ) (string , error ) {
101
- cs := fh .ClientSet ()
102
+ func ( pl * DefaultPreemption ) preempt (ctx context.Context , state * framework.CycleState , pod * v1.Pod , m framework.NodeToStatusMap ) (string , error ) {
103
+ cs := pl . fh .ClientSet ()
102
104
// TODO(Huang-Wei): get pod from informer cache instead of API server.
103
105
pod , err := util .GetUpdatedPod (cs , pod )
104
106
if err != nil {
105
107
klog .Errorf ("Error getting the updated preemptor pod object: %v" , err )
106
108
return "" , err
107
109
}
108
110
109
- if ! podEligibleToPreemptOthers (pod , fh .SnapshotSharedLister ().NodeInfos (), m [pod .Status .NominatedNodeName ]) {
111
+ if ! podEligibleToPreemptOthers (pod , pl . fh .SnapshotSharedLister ().NodeInfos (), m [pod .Status .NominatedNodeName ]) {
110
112
klog .V (5 ).Infof ("Pod %v/%v is not eligible for more preemption." , pod .Namespace , pod .Name )
111
113
return "" , nil
112
114
}
113
- allNodes , err := fh .SnapshotSharedLister ().NodeInfos ().List ()
115
+ allNodes , err := pl . fh .SnapshotSharedLister ().NodeInfos ().List ()
114
116
if err != nil {
115
117
return "" , err
116
118
}
@@ -134,19 +136,19 @@ func preempt(ctx context.Context, fh framework.FrameworkHandle, state *framework
134
136
}
135
137
klog .Infof ("%v potential nodes for preemption, first %v are: %v" , len (potentialNodes ), len (sample ), sample )
136
138
}
137
- pdbs , err := getPodDisruptionBudgets (fh )
139
+ pdbs , err := getPodDisruptionBudgets (pl . pdbLister )
138
140
if err != nil {
139
141
return "" , err
140
142
}
141
- nodeNameToVictims , err := selectNodesForPreemption (ctx , fh .PreemptHandle (), state , pod , potentialNodes , pdbs )
143
+ nodeNameToVictims , err := selectNodesForPreemption (ctx , pl . fh .PreemptHandle (), state , pod , potentialNodes , pdbs )
142
144
if err != nil {
143
145
return "" , err
144
146
}
145
147
146
148
// We will only check nodeNameToVictims with extenders that support preemption.
147
149
// Extenders which do not support preemption may later prevent preemptor from being scheduled on the nominated
148
150
// node. In that case, scheduler will find a different host for the preemptor in subsequent scheduling cycles.
149
- nodeNameToVictims , err = processPreemptionWithExtenders (fh , pod , nodeNameToVictims )
151
+ nodeNameToVictims , err = processPreemptionWithExtenders (pl . fh , pod , nodeNameToVictims )
150
152
if err != nil {
151
153
return "" , err
152
154
}
@@ -163,18 +165,18 @@ func preempt(ctx context.Context, fh framework.FrameworkHandle, state *framework
163
165
return "" , err
164
166
}
165
167
// If the victim is a WaitingPod, send a reject message to the PermitPlugin
166
- if waitingPod := fh .GetWaitingPod (victim .UID ); waitingPod != nil {
168
+ if waitingPod := pl . fh .GetWaitingPod (victim .UID ); waitingPod != nil {
167
169
waitingPod .Reject ("preempted" )
168
170
}
169
- fh .EventRecorder ().Eventf (victim , pod , v1 .EventTypeNormal , "Preempted" , "Preempting" , "Preempted by %v/%v on node %v" , pod .Namespace , pod .Name , candidateNode )
171
+ pl . fh .EventRecorder ().Eventf (victim , pod , v1 .EventTypeNormal , "Preempted" , "Preempting" , "Preempted by %v/%v on node %v" , pod .Namespace , pod .Name , candidateNode )
170
172
}
171
173
metrics .PreemptionVictims .Observe (float64 (len (victims )))
172
174
173
175
// Lower priority pods nominated to run on this node, may no longer fit on
174
176
// this node. So, we should remove their nomination. Removing their
175
177
// nomination updates these pods and moves them to the active queue. It
176
178
// lets scheduler find another place for them.
177
- nominatedPods := getLowerPriorityNominatedPods (fh .PreemptHandle (), pod , candidateNode )
179
+ nominatedPods := getLowerPriorityNominatedPods (pl . fh .PreemptHandle (), pod , candidateNode )
178
180
if err := util .ClearNominatedNodeName (cs , nominatedPods ... ); err != nil {
179
181
klog .Errorf ("Cannot clear 'NominatedNodeName' field: %v" , err )
180
182
// We do not return as this error is not critical.
@@ -615,9 +617,16 @@ func filterPodsWithPDBViolation(pods []*v1.Pod, pdbs []*policy.PodDisruptionBudg
615
617
return violatingPods , nonViolatingPods
616
618
}
617
619
618
- func getPodDisruptionBudgets ( fh framework. FrameworkHandle ) ([] * policy. PodDisruptionBudget , error ) {
620
+ func getPDBLister ( informerFactory informers. SharedInformerFactory ) policylisters. PodDisruptionBudgetLister {
619
621
if utilfeature .DefaultFeatureGate .Enabled (kubefeatures .PodDisruptionBudget ) {
620
- return fh .SharedInformerFactory ().Policy ().V1beta1 ().PodDisruptionBudgets ().Lister ().List (labels .Everything ())
622
+ return informerFactory .Policy ().V1beta1 ().PodDisruptionBudgets ().Lister ()
623
+ }
624
+ return nil
625
+ }
626
+
627
+ func getPodDisruptionBudgets (pdbLister policylisters.PodDisruptionBudgetLister ) ([]* policy.PodDisruptionBudget , error ) {
628
+ if pdbLister != nil {
629
+ return pdbLister .List (labels .Everything ())
621
630
}
622
631
return nil , nil
623
632
}
0 commit comments