From 6a82609902e75f30a8e5efb88faf85b6c487fceb Mon Sep 17 00:00:00 2001 From: Haosdent Huang Date: Wed, 1 Jan 2020 19:42:49 +0800 Subject: [PATCH] Break serviceaffinity Filter plugins dependency on predicates package --- pkg/scheduler/algorithm/predicates/BUILD | 2 - pkg/scheduler/algorithm/predicates/utils.go | 45 --------------- .../algorithm/predicates/utils_test.go | 53 ------------------ .../serviceaffinity/service_affinity.go | 56 +++++++++++++++++-- 4 files changed, 50 insertions(+), 106 deletions(-) diff --git a/pkg/scheduler/algorithm/predicates/BUILD b/pkg/scheduler/algorithm/predicates/BUILD index 15df4235adf..fad75d23805 100644 --- a/pkg/scheduler/algorithm/predicates/BUILD +++ b/pkg/scheduler/algorithm/predicates/BUILD @@ -22,7 +22,6 @@ go_library( "//pkg/scheduler/nodeinfo:go_default_library", "//pkg/scheduler/util:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//vendor/k8s.io/klog:go_default_library", @@ -44,7 +43,6 @@ go_test( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/component-base/featuregate/testing:go_default_library", diff --git a/pkg/scheduler/algorithm/predicates/utils.go b/pkg/scheduler/algorithm/predicates/utils.go index a9276763e0d..167ada37340 100644 --- a/pkg/scheduler/algorithm/predicates/utils.go +++ b/pkg/scheduler/algorithm/predicates/utils.go @@ -18,54 +18,9 @@ package predicates import ( v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo" ) -// FindLabelsInSet gets as many key/value pairs as possible out of a label set. -func FindLabelsInSet(labelsToKeep []string, selector labels.Set) map[string]string { - aL := make(map[string]string) - for _, l := range labelsToKeep { - if selector.Has(l) { - aL[l] = selector.Get(l) - } - } - return aL -} - -// AddUnsetLabelsToMap backfills missing values with values we find in a map. -func AddUnsetLabelsToMap(aL map[string]string, labelsToAdd []string, labelSet labels.Set) { - for _, l := range labelsToAdd { - // if the label is already there, dont overwrite it. - if _, exists := aL[l]; exists { - continue - } - // otherwise, backfill this label. - if labelSet.Has(l) { - aL[l] = labelSet.Get(l) - } - } -} - -// FilterPodsByNamespace filters pods outside a namespace from the given list. -func FilterPodsByNamespace(pods []*v1.Pod, ns string) []*v1.Pod { - filtered := []*v1.Pod{} - for _, nsPod := range pods { - if nsPod.Namespace == ns { - filtered = append(filtered, nsPod) - } - } - return filtered -} - -// CreateSelectorFromLabels is used to define a selector that corresponds to the keys in a map. -func CreateSelectorFromLabels(aL map[string]string) labels.Selector { - if len(aL) == 0 { - return labels.Everything() - } - return labels.Set(aL).AsSelector() -} - // portsConflict check whether existingPorts and wantPorts conflict with each other // return true if we have a conflict func portsConflict(existingPorts schedulernodeinfo.HostPortInfo, wantPorts []*v1.ContainerPort) bool { diff --git a/pkg/scheduler/algorithm/predicates/utils_test.go b/pkg/scheduler/algorithm/predicates/utils_test.go index 305a27d1304..b50b697c918 100644 --- a/pkg/scheduler/algorithm/predicates/utils_test.go +++ b/pkg/scheduler/algorithm/predicates/utils_test.go @@ -15,56 +15,3 @@ limitations under the License. */ package predicates - -import ( - "fmt" - - "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" -) - -// ExampleUtils is a https://blog.golang.org/examples styled unit test. -func ExampleFindLabelsInSet() { - labelSubset := labels.Set{} - labelSubset["label1"] = "value1" - labelSubset["label2"] = "value2" - // Lets make believe that these pods are on the cluster. - // Utility functions will inspect their labels, filter them, and so on. - nsPods := []*v1.Pod{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "pod1", - Namespace: "ns1", - Labels: map[string]string{ - "label1": "wontSeeThis", - "label2": "wontSeeThis", - "label3": "will_see_this", - }, - }, - }, // first pod which will be used via the utilities - { - ObjectMeta: metav1.ObjectMeta{ - Name: "pod2", - Namespace: "ns1", - }, - }, - - { - ObjectMeta: metav1.ObjectMeta{ - Name: "pod3ThatWeWontSee", - }, - }, - } - fmt.Println(FindLabelsInSet([]string{"label1", "label2", "label3"}, nsPods[0].ObjectMeta.Labels)["label3"]) - AddUnsetLabelsToMap(labelSubset, []string{"label1", "label2", "label3"}, nsPods[0].ObjectMeta.Labels) - fmt.Println(labelSubset) - - for _, pod := range FilterPodsByNamespace(nsPods, "ns1") { - fmt.Print(pod.Name, ",") - } - // Output: - // will_see_this - // label1=value1,label2=value2,label3=will_see_this - // pod1,pod2, -} diff --git a/pkg/scheduler/framework/plugins/serviceaffinity/service_affinity.go b/pkg/scheduler/framework/plugins/serviceaffinity/service_affinity.go index cd4d1f499ed..982a6a45ac2 100644 --- a/pkg/scheduler/framework/plugins/serviceaffinity/service_affinity.go +++ b/pkg/scheduler/framework/plugins/serviceaffinity/service_affinity.go @@ -113,14 +113,14 @@ func (pl *ServiceAffinity) createPreFilterState(pod *v1.Pod) (*preFilterState, e if err != nil { return nil, fmt.Errorf("listing pod services: %v", err.Error()) } - selector := predicates.CreateSelectorFromLabels(pod.Labels) + selector := createSelectorFromLabels(pod.Labels) allMatches, err := pl.sharedLister.Pods().List(selector) if err != nil { return nil, fmt.Errorf("listing pods: %v", err.Error()) } // consider only the pods that belong to the same namespace - matchingPodList := predicates.FilterPodsByNamespace(allMatches, pod.Namespace) + matchingPodList := filterPodsByNamespace(allMatches, pod.Namespace) return &preFilterState{ matchingPodList: matchingPodList, @@ -157,7 +157,7 @@ func (pl *ServiceAffinity) AddPod(ctx context.Context, cycleState *framework.Cyc return nil } - selector := predicates.CreateSelectorFromLabels(podToSchedule.Labels) + selector := createSelectorFromLabels(podToSchedule.Labels) if selector.Matches(labels.Set(podToAdd.Labels)) { s.matchingPodList = append(s.matchingPodList, podToAdd) } @@ -258,7 +258,7 @@ func (pl *ServiceAffinity) Filter(ctx context.Context, cycleState *framework.Cyc pods, services := s.matchingPodList, s.matchingPodServices filteredPods := nodeInfo.FilterOutPods(pods) // check if the pod being scheduled has the affinity labels specified in its NodeSelector - affinityLabels := predicates.FindLabelsInSet(pl.args.AffinityLabels, labels.Set(pod.Spec.NodeSelector)) + affinityLabels := findLabelsInSet(pl.args.AffinityLabels, labels.Set(pod.Spec.NodeSelector)) // Step 1: If we don't have all constraints, introspect nodes to find the missing constraints. if len(pl.args.AffinityLabels) > len(affinityLabels) { if len(services) > 0 { @@ -267,12 +267,12 @@ func (pl *ServiceAffinity) Filter(ctx context.Context, cycleState *framework.Cyc if err != nil { return framework.NewStatus(framework.Error, "node not found") } - predicates.AddUnsetLabelsToMap(affinityLabels, pl.args.AffinityLabels, labels.Set(nodeWithAffinityLabels.Node().Labels)) + addUnsetLabelsToMap(affinityLabels, pl.args.AffinityLabels, labels.Set(nodeWithAffinityLabels.Node().Labels)) } } } // Step 2: Finally complete the affinity predicate based on whatever set of predicates we were able to find. - if predicates.CreateSelectorFromLabels(affinityLabels).Matches(labels.Set(node.Labels)) { + if createSelectorFromLabels(affinityLabels).Matches(labels.Set(node.Labels)) { return nil } @@ -390,3 +390,47 @@ func (pl *ServiceAffinity) updateNodeScoresForLabel(sharedLister schedulerlister func (pl *ServiceAffinity) ScoreExtensions() framework.ScoreExtensions { return pl } + +// addUnsetLabelsToMap backfills missing values with values we find in a map. +func addUnsetLabelsToMap(aL map[string]string, labelsToAdd []string, labelSet labels.Set) { + for _, l := range labelsToAdd { + // if the label is already there, dont overwrite it. + if _, exists := aL[l]; exists { + continue + } + // otherwise, backfill this label. + if labelSet.Has(l) { + aL[l] = labelSet.Get(l) + } + } +} + +// createSelectorFromLabels is used to define a selector that corresponds to the keys in a map. +func createSelectorFromLabels(aL map[string]string) labels.Selector { + if len(aL) == 0 { + return labels.Everything() + } + return labels.Set(aL).AsSelector() +} + +// filterPodsByNamespace filters pods outside a namespace from the given list. +func filterPodsByNamespace(pods []*v1.Pod, ns string) []*v1.Pod { + filtered := []*v1.Pod{} + for _, nsPod := range pods { + if nsPod.Namespace == ns { + filtered = append(filtered, nsPod) + } + } + return filtered +} + +// findLabelsInSet gets as many key/value pairs as possible out of a label set. +func findLabelsInSet(labelsToKeep []string, selector labels.Set) map[string]string { + aL := make(map[string]string) + for _, l := range labelsToKeep { + if selector.Has(l) { + aL[l] = selector.Get(l) + } + } + return aL +}