Skip to content

Commit 9096af8

Browse files
committed
refactor: migrate appgroup and net topo client to ctrl runtime
Signed-off-by: Wei Zhang <[email protected]>
1 parent 40c0fee commit 9096af8

File tree

4 files changed

+150
-151
lines changed

4 files changed

+150
-151
lines changed

pkg/networkaware/networkoverhead/networkoverhead.go

Lines changed: 107 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,21 @@ import (
2222
"math"
2323
"sort"
2424

25-
v1 "k8s.io/api/core/v1"
25+
corev1 "k8s.io/api/core/v1"
2626
"k8s.io/apimachinery/pkg/labels"
2727
"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"
2930
"k8s.io/klog/v2"
3031
"k8s.io/kubernetes/pkg/scheduler/framework"
3132

33+
"sigs.k8s.io/controller-runtime/pkg/client"
34+
3235
pluginconfig "sigs.k8s.io/scheduler-plugins/apis/config"
3336
networkawareutil "sigs.k8s.io/scheduler-plugins/pkg/networkaware/util"
3437

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"
3940
)
4041

4142
var _ framework.PreFilterPlugin = &NetworkOverhead{}
@@ -61,10 +62,9 @@ const (
6162

6263
// NetworkOverhead : Filter and Score nodes based on Pod's AppGroup requirements: MaxNetworkCosts requirements among Pods with dependencies
6364
type NetworkOverhead struct {
65+
client.Client
66+
6467
handle framework.Handle
65-
podLister corelisters.PodLister
66-
agLister aglisters.AppGroupLister
67-
ntLister ntlisters.NetworkTopologyLister
6868
namespaces []string
6969
weightsName string
7070
ntName string
@@ -79,13 +79,13 @@ type PreFilterState struct {
7979
agName string
8080

8181
// AppGroup CR
82-
appGroup *agv1alpha1.AppGroup
82+
appGroup *appgroupv1a1.AppGroup
8383

8484
// NetworkTopology CR
85-
networkTopology *ntv1alpha1.NetworkTopology
85+
networkTopology *nettopov1a1.NetworkTopology
8686

8787
// Dependency List of the given pod
88-
dependencyList []agv1alpha1.DependenciesInfo
88+
dependencyList []appgroupv1a1.DependenciesInfo
8989

9090
// Pods already scheduled based on the dependency list
9191
scheduledList networkawareutil.ScheduledList
@@ -136,21 +136,23 @@ func New(obj runtime.Object, handle framework.Handle) (framework.Plugin, error)
136136
return nil, err
137137
}
138138

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))
143142

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+
})
145149
if err != nil {
146150
return nil, err
147151
}
148152

149153
no := &NetworkOverhead{
154+
Client: client,
150155
handle: handle,
151-
podLister: handle.SharedInformerFactory().Core().V1().Pods().Lister(),
152-
agLister: agLister,
153-
ntLister: ntLister,
154156
namespaces: args.Namespaces,
155157
weightsName: args.WeightsName,
156158
ntName: args.NetworkTopologyName,
@@ -165,7 +167,7 @@ func New(obj runtime.Object, handle framework.Handle) (framework.Plugin, error)
165167
// 4. Update cost map of all nodes
166168
// 5. Get number of satisfied and violated dependencies
167169
// 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) {
169171
// Init PreFilter State
170172
preFilterState := &PreFilterState{
171173
scoreEqually: true,
@@ -197,24 +199,29 @@ func (no *NetworkOverhead) PreFilter(ctx context.Context, state *framework.Cycle
197199
return nil, framework.NewStatus(framework.Success, "Pod has no dependencies, return")
198200
}
199201

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")
205212
}
213+
pods := podList.Items
206214

207215
// Return if pods are not yet allocated for the AppGroup...
208-
if pods == nil {
216+
if pods == nil || len(pods) == 0 {
209217
return nil, framework.NewStatus(framework.Success, "No pods yet allocated, return")
210218
}
211219

212220
// Pods already scheduled: Get Scheduled List (Deployment name, replicaID, hostname)
213221
scheduledList := networkawareutil.GetScheduledList(pods)
214-
215222
// 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")
218225
return nil, framework.NewStatus(framework.Success, "Scheduled list is empty, return")
219226
}
220227

@@ -238,7 +245,10 @@ func (no *NetworkOverhead) PreFilter(ctx context.Context, state *framework.Cycle
238245
// retrieve region and zone labels
239246
region := networkawareutil.GetNodeRegion(nodeInfo.Node())
240247
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)
242252

243253
// Create map for cost / destinations. Search for requirements faster...
244254
costMap := make(map[networkawareutil.CostKey]int64)
@@ -295,18 +305,29 @@ func (no *NetworkOverhead) PreFilterExtensions() framework.PreFilterExtensions {
295305

296306
// AddPod from pre-computed data in cycleState.
297307
// 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 {
299313
return framework.NewStatus(framework.Success, "")
300314
}
301315

302316
// RemovePod from pre-computed data in cycleState.
303317
// 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 {
305323
return framework.NewStatus(framework.Success, "")
306324
}
307325

308326
// 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 {
310331
if nodeInfo.Node() == nil {
311332
return framework.NewStatus(framework.Error, "node not found")
312333
}
@@ -338,7 +359,10 @@ func (no *NetworkOverhead) Filter(ctx context.Context, cycleState *framework.Cyc
338359
}
339360

340361
// 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) {
342366
score := framework.MinNodeScore
343367

344368
// Get PreFilterState
@@ -360,7 +384,10 @@ func (no *NetworkOverhead) Score(ctx context.Context, cycleState *framework.Cycl
360384
}
361385

362386
// 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 {
364391
klog.V(4).InfoS("before normalization: ", "scores", scores)
365392

366393
// Get Min and Max Scores to normalize between framework.MaxNodeScore and framework.MinNodeScore
@@ -405,8 +432,8 @@ func getMinMaxScores(scores framework.NodeScoreList) (int64, int64) {
405432
}
406433

407434
// 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
410437
for _, w := range networkTopology.Spec.Weights {
411438
// Sort Costs by TopologyKey, might not be sorted since were manually defined
412439
sort.Sort(networkawareutil.ByTopologyKey(w.TopologyList))
@@ -415,17 +442,21 @@ func (no *NetworkOverhead) sortNetworkTopologyCosts(networkTopology *ntv1alpha1.
415442
}
416443

417444
// 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) {
419450
for _, w := range networkTopology.Spec.Weights { // Check the weights List
420451
if w.Name != no.weightsName { // If it is not the Preferred algorithm, continue
421452
continue
422453
}
423454

424455
if region != "" { // Add Region Costs
425456
// 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)
427458

428-
if no.weightsName != ntv1alpha1.NetworkTopologyNetperfCosts {
459+
if no.weightsName != nettopov1a1.NetworkTopologyNetperfCosts {
429460
// Sort Costs by origin, might not be sorted since were manually defined
430461
sort.Sort(networkawareutil.ByOrigin(topologyList))
431462
}
@@ -442,9 +473,9 @@ func (no *NetworkOverhead) populateCostMap(costMap map[networkawareutil.CostKey]
442473
}
443474
if zone != "" { // Add Zone Costs
444475
// 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)
446477

447-
if no.weightsName != ntv1alpha1.NetworkTopologyNetperfCosts {
478+
if no.weightsName != nettopov1a1.NetworkTopologyNetperfCosts {
448479
// Sort Costs by origin, might not be sorted since were manually defined
449480
sort.Sort(networkawareutil.ByOrigin(topologyList))
450481
}
@@ -463,9 +494,14 @@ func (no *NetworkOverhead) populateCostMap(costMap map[networkawareutil.CostKey]
463494
}
464495

465496
// 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) {
469505
var satisfied int64 = 0
470506
var violated int64 = 0
471507

@@ -533,9 +569,13 @@ func checkMaxNetworkCostRequirements(scheduledList networkawareutil.ScheduledLis
533569
}
534570

535571
// 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) {
539579
// keep track of the accumulated cost
540580
var cost int64 = 0
541581

@@ -607,34 +647,42 @@ func getPreFilterState(cycleState *framework.CycleState) (*PreFilterState, error
607647
return state, nil
608648
}
609649

610-
func (no *NetworkOverhead) findAppGroupNetworkOverhead(agName string) *agv1alpha1.AppGroup {
650+
func (no *NetworkOverhead) findAppGroupNetworkOverhead(agName string) *appgroupv1a1.AppGroup {
611651
klog.V(6).InfoS("namespaces: %s", no.namespaces)
612652
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)
614654
// 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)
616660
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:")
618662
continue
619663
}
620-
if appGroup != nil {
664+
if appGroup != nil && appGroup.GetUID() != "" {
621665
return appGroup
622666
}
623667
}
624668
return nil
625669
}
626670

627-
func (no *NetworkOverhead) findNetworkTopologyNetworkOverhead() *ntv1alpha1.NetworkTopology {
671+
func (no *NetworkOverhead) findNetworkTopologyNetworkOverhead() *nettopov1a1.NetworkTopology {
628672
klog.V(6).InfoS("namespaces: %s", no.namespaces)
629673
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)
631675
// 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)
633681
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:")
635683
continue
636684
}
637-
if networkTopology != nil {
685+
if networkTopology != nil && networkTopology.GetUID() != "" {
638686
return networkTopology
639687
}
640688
}

0 commit comments

Comments
 (0)