Break serviceaffinity Filter plugins dependency on predicates package

This commit is contained in:
Haosdent Huang 2020-01-01 19:42:49 +08:00
parent 8b8f2aa4a5
commit 6a82609902
4 changed files with 50 additions and 106 deletions

View File

@ -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",

View File

@ -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 {

View File

@ -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,
}

View File

@ -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
}