@@ -22,20 +22,21 @@ import (
22
22
"math"
23
23
"sort"
24
24
25
- v1 "k8s.io/api/core/v1"
25
+ corev1 "k8s.io/api/core/v1"
26
26
"k8s.io/apimachinery/pkg/labels"
27
27
"k8s.io/apimachinery/pkg/runtime"
28
- corelisters "k8s.io/client-go/listers/core/v1"
28
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
29
+ clientgoscheme "k8s.io/client-go/kubernetes/scheme"
29
30
"k8s.io/klog/v2"
30
31
"k8s.io/kubernetes/pkg/scheduler/framework"
31
32
33
+ "sigs.k8s.io/controller-runtime/pkg/client"
34
+
32
35
pluginconfig "sigs.k8s.io/scheduler-plugins/apis/config"
33
36
networkawareutil "sigs.k8s.io/scheduler-plugins/pkg/networkaware/util"
34
37
35
- agv1alpha1 "github.com/diktyo-io/appgroup-api/pkg/apis/appgroup/v1alpha1"
36
- aglisters "github.com/diktyo-io/appgroup-api/pkg/generated/listers/appgroup/v1alpha1"
37
- ntv1alpha1 "github.com/diktyo-io/networktopology-api/pkg/apis/networktopology/v1alpha1"
38
- ntlisters "github.com/diktyo-io/networktopology-api/pkg/generated/listers/networktopology/v1alpha1"
38
+ appgroupv1a1 "github.com/diktyo-io/appgroup-api/pkg/apis/appgroup/v1alpha1"
39
+ nettopov1a1 "github.com/diktyo-io/networktopology-api/pkg/apis/networktopology/v1alpha1"
39
40
)
40
41
41
42
var _ framework.PreFilterPlugin = & NetworkOverhead {}
@@ -61,10 +62,9 @@ const (
61
62
62
63
// NetworkOverhead : Filter and Score nodes based on Pod's AppGroup requirements: MaxNetworkCosts requirements among Pods with dependencies
63
64
type NetworkOverhead struct {
65
+ client.Client
66
+
64
67
handle framework.Handle
65
- podLister corelisters.PodLister
66
- agLister aglisters.AppGroupLister
67
- ntLister ntlisters.NetworkTopologyLister
68
68
namespaces []string
69
69
weightsName string
70
70
ntName string
@@ -79,13 +79,13 @@ type PreFilterState struct {
79
79
agName string
80
80
81
81
// AppGroup CR
82
- appGroup * agv1alpha1 .AppGroup
82
+ appGroup * appgroupv1a1 .AppGroup
83
83
84
84
// NetworkTopology CR
85
- networkTopology * ntv1alpha1 .NetworkTopology
85
+ networkTopology * nettopov1a1 .NetworkTopology
86
86
87
87
// Dependency List of the given pod
88
- dependencyList []agv1alpha1 .DependenciesInfo
88
+ dependencyList []appgroupv1a1 .DependenciesInfo
89
89
90
90
// Pods already scheduled based on the dependency list
91
91
scheduledList networkawareutil.ScheduledList
@@ -136,21 +136,23 @@ func New(obj runtime.Object, handle framework.Handle) (framework.Plugin, error)
136
136
return nil , err
137
137
}
138
138
139
- agLister , err := networkawareutil .InitAppGroupInformer (handle .KubeConfig ())
140
- if err != nil {
141
- return nil , err
142
- }
139
+ scheme := runtime .NewScheme ()
140
+
141
+ utilruntime .Must (clientgoscheme .AddToScheme (scheme ))
143
142
144
- ntLister , err := networkawareutil .InitNetworkTopologyInformer (handle .KubeConfig ())
143
+ utilruntime .Must (appgroupv1a1 .AddToScheme (scheme ))
144
+ utilruntime .Must (nettopov1a1 .AddToScheme (scheme ))
145
+
146
+ client , err := client .New (handle .KubeConfig (), client.Options {
147
+ Scheme : scheme ,
148
+ })
145
149
if err != nil {
146
150
return nil , err
147
151
}
148
152
149
153
no := & NetworkOverhead {
154
+ Client : client ,
150
155
handle : handle ,
151
- podLister : handle .SharedInformerFactory ().Core ().V1 ().Pods ().Lister (),
152
- agLister : agLister ,
153
- ntLister : ntLister ,
154
156
namespaces : args .Namespaces ,
155
157
weightsName : args .WeightsName ,
156
158
ntName : args .NetworkTopologyName ,
@@ -165,7 +167,7 @@ func New(obj runtime.Object, handle framework.Handle) (framework.Plugin, error)
165
167
// 4. Update cost map of all nodes
166
168
// 5. Get number of satisfied and violated dependencies
167
169
// 6. Get final cost of the given node to be used in the score plugin
168
- func (no * NetworkOverhead ) PreFilter (ctx context.Context , state * framework.CycleState , pod * v1 .Pod ) (* framework.PreFilterResult , * framework.Status ) {
170
+ func (no * NetworkOverhead ) PreFilter (ctx context.Context , state * framework.CycleState , pod * corev1 .Pod ) (* framework.PreFilterResult , * framework.Status ) {
169
171
// Init PreFilter State
170
172
preFilterState := & PreFilterState {
171
173
scoreEqually : true ,
@@ -197,24 +199,29 @@ func (no *NetworkOverhead) PreFilter(ctx context.Context, state *framework.Cycle
197
199
return nil , framework .NewStatus (framework .Success , "Pod has no dependencies, return" )
198
200
}
199
201
200
- // Get pods from lister
201
- selector := labels .Set (map [string ]string {agv1alpha1 .AppGroupLabel : agName }).AsSelector ()
202
- pods , err := no .podLister .List (selector )
203
- if err != nil {
204
- return nil , framework .NewStatus (framework .Success , "Error while returning pods from appGroup, return" )
202
+ podList := & corev1.PodList {}
203
+ if err := no .List (ctx , podList ,
204
+ client.MatchingLabelsSelector {
205
+ Selector : labels .Set (map [string ]string {
206
+ appgroupv1a1 .AppGroupLabel : agName ,
207
+ }).AsSelector (),
208
+ }); err != nil {
209
+ klog .ErrorS (err , "List pods for group failed" )
210
+ return nil , framework .NewStatus (
211
+ framework .Success , "Error while returning pods from appGroup, return" )
205
212
}
213
+ pods := podList .Items
206
214
207
215
// Return if pods are not yet allocated for the AppGroup...
208
- if pods == nil {
216
+ if pods == nil || len ( pods ) == 0 {
209
217
return nil , framework .NewStatus (framework .Success , "No pods yet allocated, return" )
210
218
}
211
219
212
220
// Pods already scheduled: Get Scheduled List (Deployment name, replicaID, hostname)
213
221
scheduledList := networkawareutil .GetScheduledList (pods )
214
-
215
222
// Check if scheduledList is empty...
216
- if scheduledList == nil {
217
- klog .ErrorS (err , "Scheduled list is empty, return" )
223
+ if scheduledList == nil || len ( scheduledList ) == 0 {
224
+ klog .ErrorS (nil , "Scheduled list is empty, return" )
218
225
return nil , framework .NewStatus (framework .Success , "Scheduled list is empty, return" )
219
226
}
220
227
@@ -238,7 +245,10 @@ func (no *NetworkOverhead) PreFilter(ctx context.Context, state *framework.Cycle
238
245
// retrieve region and zone labels
239
246
region := networkawareutil .GetNodeRegion (nodeInfo .Node ())
240
247
zone := networkawareutil .GetNodeZone (nodeInfo .Node ())
241
- klog .V (6 ).InfoS ("Node info" , "name" , nodeInfo .Node ().Name , "region" , region , "zone" , zone )
248
+ klog .V (6 ).InfoS ("Node info" ,
249
+ "name" , nodeInfo .Node ().Name ,
250
+ "region" , region ,
251
+ "zone" , zone )
242
252
243
253
// Create map for cost / destinations. Search for requirements faster...
244
254
costMap := make (map [networkawareutil.CostKey ]int64 )
@@ -295,18 +305,29 @@ func (no *NetworkOverhead) PreFilterExtensions() framework.PreFilterExtensions {
295
305
296
306
// AddPod from pre-computed data in cycleState.
297
307
// no current need for the NetworkOverhead plugin
298
- func (no * NetworkOverhead ) AddPod (ctx context.Context , cycleState * framework.CycleState , podToSchedule * v1.Pod , podToAdd * framework.PodInfo , nodeInfo * framework.NodeInfo ) * framework.Status {
308
+ func (no * NetworkOverhead ) AddPod (ctx context.Context ,
309
+ cycleState * framework.CycleState ,
310
+ podToSchedule * corev1.Pod ,
311
+ podToAdd * framework.PodInfo ,
312
+ nodeInfo * framework.NodeInfo ) * framework.Status {
299
313
return framework .NewStatus (framework .Success , "" )
300
314
}
301
315
302
316
// RemovePod from pre-computed data in cycleState.
303
317
// no current need for the NetworkOverhead plugin
304
- func (no * NetworkOverhead ) RemovePod (ctx context.Context , cycleState * framework.CycleState , podToSchedule * v1.Pod , podToRemove * framework.PodInfo , nodeInfo * framework.NodeInfo ) * framework.Status {
318
+ func (no * NetworkOverhead ) RemovePod (ctx context.Context ,
319
+ cycleState * framework.CycleState ,
320
+ podToSchedule * corev1.Pod ,
321
+ podToRemove * framework.PodInfo ,
322
+ nodeInfo * framework.NodeInfo ) * framework.Status {
305
323
return framework .NewStatus (framework .Success , "" )
306
324
}
307
325
308
326
// Filter : evaluate if node can respect maxNetworkCost requirements
309
- func (no * NetworkOverhead ) Filter (ctx context.Context , cycleState * framework.CycleState , pod * v1.Pod , nodeInfo * framework.NodeInfo ) * framework.Status {
327
+ func (no * NetworkOverhead ) Filter (ctx context.Context ,
328
+ cycleState * framework.CycleState ,
329
+ pod * corev1.Pod ,
330
+ nodeInfo * framework.NodeInfo ) * framework.Status {
310
331
if nodeInfo .Node () == nil {
311
332
return framework .NewStatus (framework .Error , "node not found" )
312
333
}
@@ -338,7 +359,10 @@ func (no *NetworkOverhead) Filter(ctx context.Context, cycleState *framework.Cyc
338
359
}
339
360
340
361
// Score : evaluate score for a node
341
- func (no * NetworkOverhead ) Score (ctx context.Context , cycleState * framework.CycleState , pod * v1.Pod , nodeName string ) (int64 , * framework.Status ) {
362
+ func (no * NetworkOverhead ) Score (ctx context.Context ,
363
+ cycleState * framework.CycleState ,
364
+ pod * corev1.Pod ,
365
+ nodeName string ) (int64 , * framework.Status ) {
342
366
score := framework .MinNodeScore
343
367
344
368
// Get PreFilterState
@@ -360,7 +384,10 @@ func (no *NetworkOverhead) Score(ctx context.Context, cycleState *framework.Cycl
360
384
}
361
385
362
386
// NormalizeScore : normalize scores since lower scores correspond to lower latency
363
- func (no * NetworkOverhead ) NormalizeScore (ctx context.Context , state * framework.CycleState , pod * v1.Pod , scores framework.NodeScoreList ) * framework.Status {
387
+ func (no * NetworkOverhead ) NormalizeScore (ctx context.Context ,
388
+ state * framework.CycleState ,
389
+ pod * corev1.Pod ,
390
+ scores framework.NodeScoreList ) * framework.Status {
364
391
klog .V (4 ).InfoS ("before normalization: " , "scores" , scores )
365
392
366
393
// Get Min and Max Scores to normalize between framework.MaxNodeScore and framework.MinNodeScore
@@ -405,8 +432,8 @@ func getMinMaxScores(scores framework.NodeScoreList) (int64, int64) {
405
432
}
406
433
407
434
// sortNetworkTopologyCosts : sort costs if manual weights were selected
408
- func (no * NetworkOverhead ) sortNetworkTopologyCosts (networkTopology * ntv1alpha1 .NetworkTopology ) {
409
- if no .weightsName != ntv1alpha1 .NetworkTopologyNetperfCosts { // Manual weights were selected
435
+ func (no * NetworkOverhead ) sortNetworkTopologyCosts (networkTopology * nettopov1a1 .NetworkTopology ) {
436
+ if no .weightsName != nettopov1a1 .NetworkTopologyNetperfCosts { // Manual weights were selected
410
437
for _ , w := range networkTopology .Spec .Weights {
411
438
// Sort Costs by TopologyKey, might not be sorted since were manually defined
412
439
sort .Sort (networkawareutil .ByTopologyKey (w .TopologyList ))
@@ -415,17 +442,21 @@ func (no *NetworkOverhead) sortNetworkTopologyCosts(networkTopology *ntv1alpha1.
415
442
}
416
443
417
444
// populateCostMap : Populates costMap based on the node being filtered/scored
418
- func (no * NetworkOverhead ) populateCostMap (costMap map [networkawareutil.CostKey ]int64 , networkTopology * ntv1alpha1.NetworkTopology , region string , zone string ) {
445
+ func (no * NetworkOverhead ) populateCostMap (
446
+ costMap map [networkawareutil.CostKey ]int64 ,
447
+ networkTopology * nettopov1a1.NetworkTopology ,
448
+ region string ,
449
+ zone string ) {
419
450
for _ , w := range networkTopology .Spec .Weights { // Check the weights List
420
451
if w .Name != no .weightsName { // If it is not the Preferred algorithm, continue
421
452
continue
422
453
}
423
454
424
455
if region != "" { // Add Region Costs
425
456
// Binary search through CostList: find the Topology Key for region
426
- topologyList := networkawareutil .FindTopologyKey (w .TopologyList , ntv1alpha1 .NetworkTopologyRegion )
457
+ topologyList := networkawareutil .FindTopologyKey (w .TopologyList , nettopov1a1 .NetworkTopologyRegion )
427
458
428
- if no .weightsName != ntv1alpha1 .NetworkTopologyNetperfCosts {
459
+ if no .weightsName != nettopov1a1 .NetworkTopologyNetperfCosts {
429
460
// Sort Costs by origin, might not be sorted since were manually defined
430
461
sort .Sort (networkawareutil .ByOrigin (topologyList ))
431
462
}
@@ -442,9 +473,9 @@ func (no *NetworkOverhead) populateCostMap(costMap map[networkawareutil.CostKey]
442
473
}
443
474
if zone != "" { // Add Zone Costs
444
475
// Binary search through CostList: find the Topology Key for zone
445
- topologyList := networkawareutil .FindTopologyKey (w .TopologyList , ntv1alpha1 .NetworkTopologyZone )
476
+ topologyList := networkawareutil .FindTopologyKey (w .TopologyList , nettopov1a1 .NetworkTopologyZone )
446
477
447
- if no .weightsName != ntv1alpha1 .NetworkTopologyNetperfCosts {
478
+ if no .weightsName != nettopov1a1 .NetworkTopologyNetperfCosts {
448
479
// Sort Costs by origin, might not be sorted since were manually defined
449
480
sort .Sort (networkawareutil .ByOrigin (topologyList ))
450
481
}
@@ -463,9 +494,14 @@ func (no *NetworkOverhead) populateCostMap(costMap map[networkawareutil.CostKey]
463
494
}
464
495
465
496
// checkMaxNetworkCostRequirements : verifies the number of met and unmet dependencies based on the pod being filtered
466
- func checkMaxNetworkCostRequirements (scheduledList networkawareutil.ScheduledList , dependencyList []agv1alpha1.DependenciesInfo , nodeInfo * framework.NodeInfo , region string ,
467
- zone string , costMap map [networkawareutil.CostKey ]int64 , no * NetworkOverhead ) (int64 , int64 , error ) {
468
-
497
+ func checkMaxNetworkCostRequirements (
498
+ scheduledList networkawareutil.ScheduledList ,
499
+ dependencyList []appgroupv1a1.DependenciesInfo ,
500
+ nodeInfo * framework.NodeInfo ,
501
+ region string ,
502
+ zone string ,
503
+ costMap map [networkawareutil.CostKey ]int64 ,
504
+ no * NetworkOverhead ) (int64 , int64 , error ) {
469
505
var satisfied int64 = 0
470
506
var violated int64 = 0
471
507
@@ -533,9 +569,13 @@ func checkMaxNetworkCostRequirements(scheduledList networkawareutil.ScheduledLis
533
569
}
534
570
535
571
// getAccumulatedCost : calculate the accumulated cost based on the Pod's dependencies
536
- func (no * NetworkOverhead ) getAccumulatedCost (scheduledList networkawareutil.ScheduledList , dependencyList []agv1alpha1.DependenciesInfo , nodeName string , region string ,
537
- zone string , costMap map [networkawareutil.CostKey ]int64 ) (int64 , error ) {
538
-
572
+ func (no * NetworkOverhead ) getAccumulatedCost (
573
+ scheduledList networkawareutil.ScheduledList ,
574
+ dependencyList []appgroupv1a1.DependenciesInfo ,
575
+ nodeName string ,
576
+ region string ,
577
+ zone string ,
578
+ costMap map [networkawareutil.CostKey ]int64 ) (int64 , error ) {
539
579
// keep track of the accumulated cost
540
580
var cost int64 = 0
541
581
@@ -607,34 +647,42 @@ func getPreFilterState(cycleState *framework.CycleState) (*PreFilterState, error
607
647
return state , nil
608
648
}
609
649
610
- func (no * NetworkOverhead ) findAppGroupNetworkOverhead (agName string ) * agv1alpha1 .AppGroup {
650
+ func (no * NetworkOverhead ) findAppGroupNetworkOverhead (agName string ) * appgroupv1a1 .AppGroup {
611
651
klog .V (6 ).InfoS ("namespaces: %s" , no .namespaces )
612
652
for _ , namespace := range no .namespaces {
613
- klog .V (6 ).InfoS ("appGroup CR" , "namespace" , namespace , "ag.lister " , no . agLister )
653
+ klog .V (6 ).InfoS ("appGroup CR" , "namespace" , namespace , "name " , agName )
614
654
// AppGroup could not be placed in several namespaces simultaneously
615
- appGroup , err := no .agLister .AppGroups (namespace ).Get (agName )
655
+ appGroup := & appgroupv1a1.AppGroup {}
656
+ err := no .Get (context .TODO (), client.ObjectKey {
657
+ Namespace : namespace ,
658
+ Name : agName ,
659
+ }, appGroup )
616
660
if err != nil {
617
- klog .V (4 ).InfoS ( "Cannot get AppGroup from AppGroupNamespaceLister:" , "error" , err )
661
+ klog .V (4 ).ErrorS ( err , "Cannot get AppGroup from AppGroupNamespaceLister:" )
618
662
continue
619
663
}
620
- if appGroup != nil {
664
+ if appGroup != nil && appGroup . GetUID () != "" {
621
665
return appGroup
622
666
}
623
667
}
624
668
return nil
625
669
}
626
670
627
- func (no * NetworkOverhead ) findNetworkTopologyNetworkOverhead () * ntv1alpha1 .NetworkTopology {
671
+ func (no * NetworkOverhead ) findNetworkTopologyNetworkOverhead () * nettopov1a1 .NetworkTopology {
628
672
klog .V (6 ).InfoS ("namespaces: %s" , no .namespaces )
629
673
for _ , namespace := range no .namespaces {
630
- klog .V (6 ).InfoS ("networkTopology CR:" , "namespace" , namespace , "nt.lister " , no .ntLister )
674
+ klog .V (6 ).InfoS ("networkTopology CR:" , "namespace" , namespace , "name " , no .ntName )
631
675
// NetworkTopology could not be placed in several namespaces simultaneously
632
- networkTopology , err := no .ntLister .NetworkTopologies (namespace ).Get (no .ntName )
676
+ networkTopology := & nettopov1a1.NetworkTopology {}
677
+ err := no .Get (context .TODO (), client.ObjectKey {
678
+ Namespace : namespace ,
679
+ Name : no .ntName ,
680
+ }, networkTopology )
633
681
if err != nil {
634
- klog .V (4 ).InfoS ( "Cannot get networkTopology from networkTopologyNamespaceLister:" , "error" , err )
682
+ klog .V (4 ).ErrorS ( err , "Cannot get networkTopology from networkTopologyNamespaceLister:" )
635
683
continue
636
684
}
637
- if networkTopology != nil {
685
+ if networkTopology != nil && networkTopology . GetUID () != "" {
638
686
return networkTopology
639
687
}
640
688
}
0 commit comments