@@ -149,112 +149,42 @@ func (p *Plugin) Filter(ctx context.Context, state *framework.CycleState, pod *c
149149 }
150150 return nil
151151 }
152-
153- filterProfile := generateUsageThresholdsFilterProfile (node , p .args )
154- if len (filterProfile .ProdUsageThresholds ) > 0 && extension .GetPodPriorityClassWithDefault (pod ) == extension .PriorityProd {
155- status := p .filterProdUsage (node , nodeMetric , filterProfile .ProdUsageThresholds )
156- if ! status .IsSuccess () {
157- return status
158- }
159- } else {
160- var usageThresholds map [corev1.ResourceName ]int64
161- if filterProfile .AggregatedUsage != nil {
162- usageThresholds = filterProfile .AggregatedUsage .UsageThresholds
163- } else {
164- usageThresholds = filterProfile .UsageThresholds
165- }
166- if len (usageThresholds ) > 0 {
167- status := p .filterNodeUsage (node , nodeMetric , filterProfile )
168- if ! status .IsSuccess () {
169- return status
170- }
171- }
152+ if nodeMetric .Status .NodeMetric == nil {
153+ klog .Warningf ("nodeMetrics(%s) should not be nil." , node .Name )
154+ return nil
172155 }
173156
174- return nil
175- }
176-
177- func (p * Plugin ) filterNodeUsage (node * corev1.Node , nodeMetric * slov1alpha1.NodeMetric , filterProfile * usageThresholdsFilterProfile ) * framework.Status {
178- if nodeMetric .Status .NodeMetric == nil {
157+ allocatable , err := p .estimator .EstimateNode (node )
158+ if err != nil {
159+ klog .ErrorS (err , "Estimated node allocatable failed!" , "node" , node .Name )
179160 return nil
180161 }
162+ filterProfile := generateUsageThresholdsFilterProfile (node , p .args )
163+ prodPod := len (filterProfile .ProdUsageThresholds ) > 0 && extension .GetPodPriorityClassWithDefault (pod ) == extension .PriorityProd
181164
165+ var nodeUsage * slov1alpha1.ResourceMap
182166 var usageThresholds map [corev1.ResourceName ]int64
183- if filterProfile . AggregatedUsage != nil {
184- usageThresholds = filterProfile .AggregatedUsage . UsageThresholds
167+ if prodPod {
168+ usageThresholds = filterProfile .ProdUsageThresholds
185169 } else {
186- usageThresholds = filterProfile .UsageThresholds
187- }
188-
189- for resourceName , threshold := range usageThresholds {
190- if threshold == 0 {
191- continue
192- }
193- allocatable , err := p .estimator .EstimateNode (node )
194- if err != nil {
195- klog .ErrorS (err , "Failed to EstimateNode" , "node" , node .Name )
196- return nil
197- }
198- total := allocatable [resourceName ]
199- if total .IsZero () {
200- continue
201- }
202- // TODO(joseph): maybe we should estimate the Pod that just be scheduled that have not reported
203- var nodeUsage * slov1alpha1.ResourceMap
204170 if filterProfile .AggregatedUsage != nil {
205171 nodeUsage = getTargetAggregatedUsage (
206172 nodeMetric ,
207173 filterProfile .AggregatedUsage .UsageAggregatedDuration ,
208174 filterProfile .AggregatedUsage .UsageAggregationType ,
209175 )
176+ usageThresholds = filterProfile .AggregatedUsage .UsageThresholds
210177 } else {
211178 nodeUsage = & nodeMetric .Status .NodeMetric .NodeUsage
212- }
213- if nodeUsage == nil {
214- continue
215- }
216-
217- used := nodeUsage .ResourceList [resourceName ]
218- usage := int64 (math .Round (float64 (used .MilliValue ()) / float64 (total .MilliValue ()) * 100 ))
219- if usage >= threshold {
220- reason := ErrReasonUsageExceedThreshold
221- if filterProfile .AggregatedUsage != nil {
222- reason = ErrReasonAggregatedUsageExceedThreshold
223- }
224- return framework .NewStatus (framework .Unschedulable , fmt .Sprintf (reason , resourceName ))
179+ usageThresholds = filterProfile .UsageThresholds
225180 }
226181 }
227- return nil
228- }
229-
230- func (p * Plugin ) filterProdUsage (node * corev1.Node , nodeMetric * slov1alpha1.NodeMetric , prodUsageThresholds map [corev1.ResourceName ]int64 ) * framework.Status {
231- if len (nodeMetric .Status .PodsMetric ) == 0 {
182+ estimatedUsed , err := p .GetEstimatedUsed (node .Name , nodeMetric , pod , nodeUsage , prodPod )
183+ if err != nil {
184+ klog .ErrorS (err , "GetEstimatedUsed failed!" , "node" , node .Name )
232185 return nil
233186 }
234-
235- // TODO(joseph): maybe we should estimate the Pod that just be scheduled that have not reported
236- podMetrics := buildPodMetricMap (p .podLister , nodeMetric , true )
237- prodPodUsages , _ := sumPodUsages (podMetrics , nil )
238- for resourceName , threshold := range prodUsageThresholds {
239- if threshold == 0 {
240- continue
241- }
242- allocatable , err := p .estimator .EstimateNode (node )
243- if err != nil {
244- klog .ErrorS (err , "Failed to EstimateNode" , "node" , node .Name )
245- return nil
246- }
247- total := allocatable [resourceName ]
248- if total .IsZero () {
249- continue
250- }
251- used := prodPodUsages [resourceName ]
252- usage := int64 (math .Round (float64 (used .MilliValue ()) / float64 (total .MilliValue ()) * 100 ))
253- if usage >= threshold {
254- return framework .NewStatus (framework .Unschedulable , fmt .Sprintf (ErrReasonUsageExceedThreshold , resourceName ))
255- }
256- }
257- return nil
187+ return filterNodeUsage (usageThresholds , estimatedUsed , allocatable , prodPod , filterProfile )
258188}
259189
260190func (p * Plugin ) ScoreExtensions () framework.ScoreExtensions {
@@ -291,13 +221,44 @@ func (p *Plugin) Score(ctx context.Context, state *framework.CycleState, pod *co
291221 if p .args .NodeMetricExpirationSeconds != nil && isNodeMetricExpired (nodeMetric , * p .args .NodeMetricExpirationSeconds ) {
292222 return 0 , nil
293223 }
224+ if nodeMetric .Status .NodeMetric == nil {
225+ klog .Warningf ("nodeMetrics(%s) should not be nil." , node .Name )
226+ return 0 , nil
227+ }
294228
295229 prodPod := extension .GetPodPriorityClassWithDefault (pod ) == extension .PriorityProd && p .args .ScoreAccordingProdUsage
230+ var nodeUsage * slov1alpha1.ResourceMap
231+ if ! prodPod {
232+ if scoreWithAggregation (p .args .Aggregated ) {
233+ nodeUsage = getTargetAggregatedUsage (nodeMetric , & p .args .Aggregated .ScoreAggregatedDuration , p .args .Aggregated .ScoreAggregationType )
234+ } else {
235+ nodeUsage = & nodeMetric .Status .NodeMetric .NodeUsage
236+ }
237+ }
238+ estimatedUsed , err := p .GetEstimatedUsed (nodeName , nodeMetric , pod , nodeUsage , prodPod )
239+ if err != nil {
240+ klog .ErrorS (err , "GetEstimatedUsed failed!" , "node" , node .Name )
241+ return 0 , nil
242+ }
243+
244+ allocatable , err := p .estimator .EstimateNode (node )
245+ if err != nil {
246+ klog .ErrorS (err , "Estimated node allocatable failed!" , "node" , node .Name )
247+ return 0 , nil
248+ }
249+ score := loadAwareSchedulingScorer (p .args .ResourceWeights , estimatedUsed , allocatable )
250+ return score , nil
251+ }
252+
253+ func (p * Plugin ) GetEstimatedUsed (nodeName string , nodeMetric * slov1alpha1.NodeMetric , pod * corev1.Pod , nodeUsage * slov1alpha1.ResourceMap , prodPod bool ) (map [corev1.ResourceName ]int64 , error ) {
254+ if nodeMetric == nil {
255+ return nil , nil
256+ }
296257 podMetrics := buildPodMetricMap (p .podLister , nodeMetric , prodPod )
297258
298259 estimatedUsed , err := p .estimator .EstimatePod (pod )
299260 if err != nil {
300- return 0 , nil
261+ return nil , err
301262 }
302263 assignedPodEstimatedUsed , estimatedPods := p .estimatedAssignedPodUsed (nodeName , nodeMetric , podMetrics , prodPod )
303264 for resourceName , value := range assignedPodEstimatedUsed {
@@ -310,12 +271,6 @@ func (p *Plugin) Score(ctx context.Context, state *framework.CycleState, pod *co
310271 }
311272 } else {
312273 if nodeMetric .Status .NodeMetric != nil {
313- var nodeUsage * slov1alpha1.ResourceMap
314- if scoreWithAggregation (p .args .Aggregated ) {
315- nodeUsage = getTargetAggregatedUsage (nodeMetric , & p .args .Aggregated .ScoreAggregatedDuration , p .args .Aggregated .ScoreAggregationType )
316- } else {
317- nodeUsage = & nodeMetric .Status .NodeMetric .NodeUsage
318- }
319274 if nodeUsage != nil {
320275 for resourceName , quantity := range nodeUsage .ResourceList {
321276 if q := estimatedPodActualUsages [resourceName ]; ! q .IsZero () {
@@ -329,13 +284,30 @@ func (p *Plugin) Score(ctx context.Context, state *framework.CycleState, pod *co
329284 }
330285 }
331286 }
287+ return estimatedUsed , nil
288+ }
332289
333- allocatable , err := p .estimator .EstimateNode (node )
334- if err != nil {
335- return 0 , nil
290+ func filterNodeUsage (usageThresholds , estimatedUsed map [corev1.ResourceName ]int64 , allocatable corev1.ResourceList , prodPod bool , filterProfile * usageThresholdsFilterProfile ) * framework.Status {
291+ for resourceName , value := range usageThresholds {
292+ if value == 0 {
293+ continue
294+ }
295+ total := getResourceValue (resourceName , allocatable [resourceName ])
296+ if total == 0 {
297+ continue
298+ }
299+ usage := int64 (math .Round (float64 (estimatedUsed [resourceName ]) / float64 (total ) * 100 ))
300+ if usage <= value {
301+ continue
302+ }
303+
304+ reason := ErrReasonUsageExceedThreshold
305+ if ! prodPod && filterProfile .AggregatedUsage != nil {
306+ reason = ErrReasonAggregatedUsageExceedThreshold
307+ }
308+ return framework .NewStatus (framework .Unschedulable , fmt .Sprintf (reason , resourceName ))
336309 }
337- score := loadAwareSchedulingScorer (p .args .ResourceWeights , estimatedUsed , allocatable )
338- return score , nil
310+ return nil
339311}
340312
341313func (p * Plugin ) estimatedAssignedPodUsed (nodeName string , nodeMetric * slov1alpha1.NodeMetric , podMetrics map [string ]corev1.ResourceList , filterProdPod bool ) (map [corev1.ResourceName ]int64 , sets.String ) {
0 commit comments