diff --git a/plugin/pkg/scheduler/algorithm/predicates/predicates.go b/plugin/pkg/scheduler/algorithm/predicates/predicates.go index f87bc0c893d..1fdec02bd9d 100644 --- a/plugin/pkg/scheduler/algorithm/predicates/predicates.go +++ b/plugin/pkg/scheduler/algorithm/predicates/predicates.go @@ -909,11 +909,13 @@ func (c *PodAffinityChecker) InterPodAffinityMatches(pod *v1.Pod, meta interface // TODO: Do we really need any pod matching, or all pods matching? I think the latter. func (c *PodAffinityChecker) anyPodMatchesPodAffinityTerm(pod *v1.Pod, allPods []*v1.Pod, node *v1.Node, term *v1.PodAffinityTerm) (bool, bool, error) { matchingPodExists := false + namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(pod, term) + selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) + if err != nil { + return false, false, err + } for _, existingPod := range allPods { - match, err := priorityutil.PodMatchesTermsNamespaceAndSelector(existingPod, pod, term) - if err != nil { - return false, matchingPodExists, err - } + match := priorityutil.PodMatchesTermsNamespaceAndSelector(existingPod, namespaces, selector) if match { matchingPodExists = true existingPodNode, err := c.info.GetNodeInfo(existingPod.Spec.NodeName) @@ -994,11 +996,13 @@ func getMatchingAntiAffinityTerms(pod *v1.Pod, nodeInfoMap map[string]*scheduler continue } for _, term := range getPodAntiAffinityTerms(affinity.PodAntiAffinity) { - match, err := priorityutil.PodMatchesTermsNamespaceAndSelector(pod, existingPod, &term) + namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(pod, &term) + selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) if err != nil { catchError(err) return } + match := priorityutil.PodMatchesTermsNamespaceAndSelector(pod, namespaces, selector) if match { nodeResult = append(nodeResult, matchingPodAntiAffinityTerm{term: &term, node: node}) } @@ -1025,10 +1029,12 @@ func (c *PodAffinityChecker) getMatchingAntiAffinityTerms(pod *v1.Pod, allPods [ return nil, err } for _, term := range getPodAntiAffinityTerms(affinity.PodAntiAffinity) { - match, err := priorityutil.PodMatchesTermsNamespaceAndSelector(pod, existingPod, &term) + namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(existingPod, &term) + selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) if err != nil { return nil, err } + match := priorityutil.PodMatchesTermsNamespaceAndSelector(pod, namespaces, selector) if match { result = append(result, matchingPodAntiAffinityTerm{term: &term, node: existingPodNode}) } @@ -1090,8 +1096,15 @@ func (c *PodAffinityChecker) satisfiesPodsAffinityAntiAffinity(pod *v1.Pod, node // If the requirement matches a pod's own labels are namespace, and there are // no other such pods, then disregard the requirement. This is necessary to // not block forever because the first pod of the collection can't be scheduled. - match, err := priorityutil.PodMatchesTermsNamespaceAndSelector(pod, pod, &term) - if err != nil || !match || matchingPodExists { + namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(pod, &term) + selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) + if err != nil { + glog.V(10).Infof("Cannot parse selector on term %v for pod %v. Details %v", + term, podName(pod), err) + return false + } + match := priorityutil.PodMatchesTermsNamespaceAndSelector(pod, namespaces, selector) + if !match || matchingPodExists { glog.V(10).Infof("Cannot schedule pod %+v onto node %v,because of PodAffinityTerm %v, err: %v", podName(pod), node.Name, term, err) return false diff --git a/plugin/pkg/scheduler/algorithm/priorities/interpod_affinity.go b/plugin/pkg/scheduler/algorithm/priorities/interpod_affinity.go index 5f73183709d..d3ad964e286 100644 --- a/plugin/pkg/scheduler/algorithm/priorities/interpod_affinity.go +++ b/plugin/pkg/scheduler/algorithm/priorities/interpod_affinity.go @@ -21,6 +21,7 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api/v1" + metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/util/workqueue" "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates" @@ -84,11 +85,13 @@ func (p *podAffinityPriorityMap) setError(err error) { } func (p *podAffinityPriorityMap) processTerm(term *v1.PodAffinityTerm, podDefiningAffinityTerm, podToCheck *v1.Pod, fixedNode *v1.Node, weight float64) { - match, err := priorityutil.PodMatchesTermsNamespaceAndSelector(podToCheck, podDefiningAffinityTerm, term) + namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(podDefiningAffinityTerm, term) + selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) if err != nil { p.setError(err) return } + match := priorityutil.PodMatchesTermsNamespaceAndSelector(podToCheck, namespaces, selector) if match { func() { p.Lock() diff --git a/plugin/pkg/scheduler/algorithm/priorities/util/BUILD b/plugin/pkg/scheduler/algorithm/priorities/util/BUILD index 0fa0540859a..270d9b6d9e0 100644 --- a/plugin/pkg/scheduler/algorithm/priorities/util/BUILD +++ b/plugin/pkg/scheduler/algorithm/priorities/util/BUILD @@ -20,7 +20,6 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api/v1:go_default_library", - "//pkg/apis/meta/v1:go_default_library", "//pkg/labels:go_default_library", "//pkg/util/sets:go_default_library", ], diff --git a/plugin/pkg/scheduler/algorithm/priorities/util/topologies.go b/plugin/pkg/scheduler/algorithm/priorities/util/topologies.go index 171daf3e20d..b7735fa024b 100644 --- a/plugin/pkg/scheduler/algorithm/priorities/util/topologies.go +++ b/plugin/pkg/scheduler/algorithm/priorities/util/topologies.go @@ -18,7 +18,6 @@ package util import ( "k8s.io/kubernetes/pkg/api/v1" - metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/util/sets" ) @@ -27,7 +26,7 @@ import ( // according to the namespaces indicated in podAffinityTerm. // 1. If the namespaces is nil considers the given pod's namespace // 2. If the namespaces is empty list then considers all the namespaces -func getNamespacesFromPodAffinityTerm(pod *v1.Pod, podAffinityTerm v1.PodAffinityTerm) sets.String { +func GetNamespacesFromPodAffinityTerm(pod *v1.Pod, podAffinityTerm *v1.PodAffinityTerm) sets.String { names := sets.String{} if podAffinityTerm.Namespaces == nil { names.Insert(pod.Namespace) @@ -39,17 +38,15 @@ func getNamespacesFromPodAffinityTerm(pod *v1.Pod, podAffinityTerm v1.PodAffinit // PodMatchesTermsNamespaceAndSelector returns true if the given // matches the namespace and selector defined by `s . -func PodMatchesTermsNamespaceAndSelector(pod *v1.Pod, affinityPod *v1.Pod, term *v1.PodAffinityTerm) (bool, error) { - namespaces := getNamespacesFromPodAffinityTerm(affinityPod, *term) +func PodMatchesTermsNamespaceAndSelector(pod *v1.Pod, namespaces sets.String, selector labels.Selector) bool { if len(namespaces) != 0 && !namespaces.Has(pod.Namespace) { - return false, nil + return false } - selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) - if err != nil || !selector.Matches(labels.Set(pod.Labels)) { - return false, err + if !selector.Matches(labels.Set(pod.Labels)) { + return false } - return true, nil + return true } // nodesHaveSameTopologyKeyInternal checks if nodeA and nodeB have same label value with given topologyKey as label key.