Skip to content

Commit e7c7905

Browse files
authored
Merge pull request kubernetes#86718 from ahg-g/ahg1-err
Copy nodeaffinity predicate to its filter plugin
2 parents bd33f62 + 4e67476 commit e7c7905

File tree

12 files changed

+795
-85
lines changed

12 files changed

+795
-85
lines changed

pkg/scheduler/algorithm/BUILD

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ go_library(
1212
importpath = "k8s.io/kubernetes/pkg/scheduler/algorithm",
1313
deps = [
1414
"//pkg/apis/apps:go_default_library",
15-
"//pkg/apis/core:go_default_library",
1615
"//pkg/scheduler/apis/extender/v1:go_default_library",
1716
"//pkg/scheduler/nodeinfo:go_default_library",
1817
"//staging/src/k8s.io/api/apps/v1:go_default_library",

pkg/scheduler/algorithm/predicates/BUILD

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@ go_library(
1818
deps = [
1919
"//pkg/apis/core/v1/helper:go_default_library",
2020
"//pkg/features:go_default_library",
21-
"//pkg/scheduler/algorithm:go_default_library",
21+
"//pkg/scheduler/framework/plugins/helper:go_default_library",
2222
"//pkg/scheduler/nodeinfo:go_default_library",
2323
"//pkg/scheduler/util:go_default_library",
2424
"//staging/src/k8s.io/api/core/v1:go_default_library",
25-
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
2625
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
2726
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
2827
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",

pkg/scheduler/algorithm/predicates/predicates.go

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@ import (
2222
"k8s.io/klog"
2323

2424
v1 "k8s.io/api/core/v1"
25-
"k8s.io/apimachinery/pkg/fields"
26-
"k8s.io/apimachinery/pkg/labels"
2725
"k8s.io/apimachinery/pkg/util/sets"
2826
utilfeature "k8s.io/apiserver/pkg/util/feature"
2927
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
3028
"k8s.io/kubernetes/pkg/features"
31-
"k8s.io/kubernetes/pkg/scheduler/algorithm"
29+
pluginhelper "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper"
3230
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
3331
schedutil "k8s.io/kubernetes/pkg/scheduler/util"
3432
)
@@ -237,70 +235,13 @@ func PodFitsResourcesPredicate(pod *v1.Pod, podRequest *schedulernodeinfo.Resour
237235
return len(predicateFails) == 0, predicateFails, nil
238236
}
239237

240-
// nodeMatchesNodeSelectorTerms checks if a node's labels satisfy a list of node selector terms,
241-
// terms are ORed, and an empty list of terms will match nothing.
242-
func nodeMatchesNodeSelectorTerms(node *v1.Node, nodeSelectorTerms []v1.NodeSelectorTerm) bool {
243-
nodeFields := map[string]string{}
244-
for k, f := range algorithm.NodeFieldSelectorKeys {
245-
nodeFields[k] = f(node)
246-
}
247-
return v1helper.MatchNodeSelectorTerms(nodeSelectorTerms, labels.Set(node.Labels), fields.Set(nodeFields))
248-
}
249-
250-
// PodMatchesNodeSelectorAndAffinityTerms checks whether the pod is schedulable onto nodes according to
251-
// the requirements in both NodeAffinity and nodeSelector.
252-
func PodMatchesNodeSelectorAndAffinityTerms(pod *v1.Pod, node *v1.Node) bool {
253-
// Check if node.Labels match pod.Spec.NodeSelector.
254-
if len(pod.Spec.NodeSelector) > 0 {
255-
selector := labels.SelectorFromSet(pod.Spec.NodeSelector)
256-
if !selector.Matches(labels.Set(node.Labels)) {
257-
return false
258-
}
259-
}
260-
261-
// 1. nil NodeSelector matches all nodes (i.e. does not filter out any nodes)
262-
// 2. nil []NodeSelectorTerm (equivalent to non-nil empty NodeSelector) matches no nodes
263-
// 3. zero-length non-nil []NodeSelectorTerm matches no nodes also, just for simplicity
264-
// 4. nil []NodeSelectorRequirement (equivalent to non-nil empty NodeSelectorTerm) matches no nodes
265-
// 5. zero-length non-nil []NodeSelectorRequirement matches no nodes also, just for simplicity
266-
// 6. non-nil empty NodeSelectorRequirement is not allowed
267-
nodeAffinityMatches := true
268-
affinity := pod.Spec.Affinity
269-
if affinity != nil && affinity.NodeAffinity != nil {
270-
nodeAffinity := affinity.NodeAffinity
271-
// if no required NodeAffinity requirements, will do no-op, means select all nodes.
272-
// TODO: Replace next line with subsequent commented-out line when implement RequiredDuringSchedulingRequiredDuringExecution.
273-
if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil {
274-
// if nodeAffinity.RequiredDuringSchedulingRequiredDuringExecution == nil && nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil {
275-
return true
276-
}
277-
278-
// Match node selector for requiredDuringSchedulingRequiredDuringExecution.
279-
// TODO: Uncomment this block when implement RequiredDuringSchedulingRequiredDuringExecution.
280-
// if nodeAffinity.RequiredDuringSchedulingRequiredDuringExecution != nil {
281-
// nodeSelectorTerms := nodeAffinity.RequiredDuringSchedulingRequiredDuringExecution.NodeSelectorTerms
282-
// klog.V(10).Infof("Match for RequiredDuringSchedulingRequiredDuringExecution node selector terms %+v", nodeSelectorTerms)
283-
// nodeAffinityMatches = nodeMatchesNodeSelectorTerms(node, nodeSelectorTerms)
284-
// }
285-
286-
// Match node selector for requiredDuringSchedulingIgnoredDuringExecution.
287-
if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil {
288-
nodeSelectorTerms := nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms
289-
klog.V(10).Infof("Match for RequiredDuringSchedulingIgnoredDuringExecution node selector terms %+v", nodeSelectorTerms)
290-
nodeAffinityMatches = nodeAffinityMatches && nodeMatchesNodeSelectorTerms(node, nodeSelectorTerms)
291-
}
292-
293-
}
294-
return nodeAffinityMatches
295-
}
296-
297238
// PodMatchNodeSelector checks if a pod node selector matches the node label.
298239
func PodMatchNodeSelector(pod *v1.Pod, meta Metadata, nodeInfo *schedulernodeinfo.NodeInfo) (bool, []PredicateFailureReason, error) {
299240
node := nodeInfo.Node()
300241
if node == nil {
301242
return false, nil, fmt.Errorf("node not found")
302243
}
303-
if PodMatchesNodeSelectorAndAffinityTerms(pod, node) {
244+
if pluginhelper.PodMatchesNodeSelectorAndAffinityTerms(pod, node) {
304245
return true, nil, nil
305246
}
306247
return false, []PredicateFailureReason{ErrNodeSelectorNotMatch}, nil

pkg/scheduler/algorithm/types.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,8 @@ import (
2323
appslisters "k8s.io/client-go/listers/apps/v1"
2424
corelisters "k8s.io/client-go/listers/core/v1"
2525
"k8s.io/kubernetes/pkg/apis/apps"
26-
api "k8s.io/kubernetes/pkg/apis/core"
2726
)
2827

29-
// NodeFieldSelectorKeys is a map that: the keys are node field selector keys; the values are
30-
// the functions to get the value of the node field.
31-
var NodeFieldSelectorKeys = map[string]func(*v1.Node) string{
32-
api.ObjectNameField: func(n *v1.Node) string { return n.Name },
33-
}
34-
3528
var _ corelisters.ReplicationControllerLister = &EmptyControllerLister{}
3629

3730
// EmptyControllerLister implements ControllerLister on []v1.ReplicationController returning empty data

pkg/scheduler/framework/plugins/helper/BUILD

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,28 @@ go_library(
99
importpath = "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper",
1010
visibility = ["//visibility:public"],
1111
deps = [
12-
"//pkg/scheduler/algorithm/predicates:go_default_library",
12+
"//pkg/apis/core:go_default_library",
13+
"//pkg/apis/core/v1/helper:go_default_library",
1314
"//pkg/scheduler/framework/v1alpha1:go_default_library",
1415
"//staging/src/k8s.io/api/core/v1:go_default_library",
16+
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
17+
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
1518
],
1619
)
1720

1821
go_test(
1922
name = "go_default_test",
20-
srcs = ["normalize_score_test.go"],
23+
srcs = [
24+
"node_affinity_test.go",
25+
"normalize_score_test.go",
26+
],
2127
embed = [":go_default_library"],
22-
deps = ["//pkg/scheduler/framework/v1alpha1:go_default_library"],
28+
deps = [
29+
"//pkg/apis/core:go_default_library",
30+
"//pkg/scheduler/framework/v1alpha1:go_default_library",
31+
"//staging/src/k8s.io/api/core/v1:go_default_library",
32+
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
33+
],
2334
)
2435

2536
filegroup(

pkg/scheduler/framework/plugins/helper/node_affinity.go

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,63 @@ limitations under the License.
1717
package helper
1818

1919
import (
20-
v1 "k8s.io/api/core/v1"
21-
predicates "k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
20+
"k8s.io/api/core/v1"
21+
"k8s.io/apimachinery/pkg/fields"
22+
"k8s.io/apimachinery/pkg/labels"
23+
api "k8s.io/kubernetes/pkg/apis/core"
24+
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
2225
)
2326

2427
// PodMatchesNodeSelectorAndAffinityTerms checks whether the pod is schedulable onto nodes according to
2528
// the requirements in both NodeAffinity and nodeSelector.
2629
func PodMatchesNodeSelectorAndAffinityTerms(pod *v1.Pod, node *v1.Node) bool {
27-
// TODO(ahg-g): actually move the logic here.
28-
return predicates.PodMatchesNodeSelectorAndAffinityTerms(pod, node)
30+
// Check if node.Labels match pod.Spec.NodeSelector.
31+
if len(pod.Spec.NodeSelector) > 0 {
32+
selector := labels.SelectorFromSet(pod.Spec.NodeSelector)
33+
if !selector.Matches(labels.Set(node.Labels)) {
34+
return false
35+
}
36+
}
37+
38+
// 1. nil NodeSelector matches all nodes (i.e. does not filter out any nodes)
39+
// 2. nil []NodeSelectorTerm (equivalent to non-nil empty NodeSelector) matches no nodes
40+
// 3. zero-length non-nil []NodeSelectorTerm matches no nodes also, just for simplicity
41+
// 4. nil []NodeSelectorRequirement (equivalent to non-nil empty NodeSelectorTerm) matches no nodes
42+
// 5. zero-length non-nil []NodeSelectorRequirement matches no nodes also, just for simplicity
43+
// 6. non-nil empty NodeSelectorRequirement is not allowed
44+
nodeAffinityMatches := true
45+
affinity := pod.Spec.Affinity
46+
if affinity != nil && affinity.NodeAffinity != nil {
47+
nodeAffinity := affinity.NodeAffinity
48+
// if no required NodeAffinity requirements, will do no-op, means select all nodes.
49+
// TODO: Replace next line with subsequent commented-out line when implement RequiredDuringSchedulingRequiredDuringExecution.
50+
if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil {
51+
// if nodeAffinity.RequiredDuringSchedulingRequiredDuringExecution == nil && nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil {
52+
return true
53+
}
54+
55+
// Match node selector for requiredDuringSchedulingRequiredDuringExecution.
56+
// TODO: Uncomment this block when implement RequiredDuringSchedulingRequiredDuringExecution.
57+
// if nodeAffinity.RequiredDuringSchedulingRequiredDuringExecution != nil {
58+
// nodeSelectorTerms := nodeAffinity.RequiredDuringSchedulingRequiredDuringExecution.NodeSelectorTerms
59+
// klog.V(10).Infof("Match for RequiredDuringSchedulingRequiredDuringExecution node selector terms %+v", nodeSelectorTerms)
60+
// nodeAffinityMatches = nodeMatchesNodeSelectorTerms(node, nodeSelectorTerms)
61+
// }
62+
63+
// Match node selector for requiredDuringSchedulingIgnoredDuringExecution.
64+
if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil {
65+
nodeSelectorTerms := nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms
66+
nodeAffinityMatches = nodeAffinityMatches && nodeMatchesNodeSelectorTerms(node, nodeSelectorTerms)
67+
}
68+
69+
}
70+
return nodeAffinityMatches
71+
}
72+
73+
// nodeMatchesNodeSelectorTerms checks if a node's labels satisfy a list of node selector terms,
74+
// terms are ORed, and an empty list of terms will match nothing.
75+
func nodeMatchesNodeSelectorTerms(node *v1.Node, nodeSelectorTerms []v1.NodeSelectorTerm) bool {
76+
return v1helper.MatchNodeSelectorTerms(nodeSelectorTerms, labels.Set(node.Labels), fields.Set{
77+
api.ObjectNameField: node.Name,
78+
})
2979
}

0 commit comments

Comments
 (0)