@@ -18,31 +18,85 @@ package nodeports
18
18
19
19
import (
20
20
"context"
21
+ "fmt"
21
22
22
23
v1 "k8s.io/api/core/v1"
23
24
"k8s.io/apimachinery/pkg/runtime"
25
+ "k8s.io/klog"
26
+
24
27
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
25
28
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/migration"
26
29
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
27
30
"k8s.io/kubernetes/pkg/scheduler/nodeinfo"
31
+ schedutil "k8s.io/kubernetes/pkg/scheduler/util"
28
32
)
29
33
30
34
// NodePorts is a plugin that checks if a node has free ports for the requested pod ports.
31
35
type NodePorts struct {}
32
36
33
37
var _ framework.FilterPlugin = & NodePorts {}
34
38
35
- // Name is the name of the plugin used in the plugin registry and configurations.
36
- const Name = "NodePorts"
39
+ const (
40
+ // Name is the name of the plugin used in the plugin registry and configurations.
41
+ Name = "NodePorts"
42
+
43
+ // preFilterStateKey is the key in CycleState to InterPodAffinity pre-computed data.
44
+ // Using the name of the plugin will likely help us avoid collisions with other plugins.
45
+ preFilterStateKey = "PreFilter" + Name
46
+ )
47
+
48
+ type preFilterState []* v1.ContainerPort
49
+
50
+ // Clone the prefilter state.
51
+ func (s preFilterState ) Clone () framework.StateData {
52
+ // The state is not impacted by adding/removing existing pods, hence we don't need to make a deep copy.
53
+ return s
54
+ }
37
55
38
56
// Name returns name of the plugin. It is used in logs, etc.
39
57
func (pl * NodePorts ) Name () string {
40
58
return Name
41
59
}
42
60
61
+ // PreFilter invoked at the prefilter extension point.
62
+ func (pl * NodePorts ) PreFilter (ctx context.Context , cycleState * framework.CycleState , pod * v1.Pod ) * framework.Status {
63
+ s := schedutil .GetContainerPorts (pod )
64
+ cycleState .Write (preFilterStateKey , preFilterState (s ))
65
+ return nil
66
+ }
67
+
68
+ // PreFilterExtensions do not exist for this plugin.
69
+ func (pl * NodePorts ) PreFilterExtensions () framework.PreFilterExtensions {
70
+ return nil
71
+ }
72
+
73
+ func getPreFilterState (cycleState * framework.CycleState ) (preFilterState , error ) {
74
+ if cycleState == nil {
75
+ return nil , fmt .Errorf ("invalid nil CycleState" )
76
+ }
77
+
78
+ c , err := cycleState .Read (preFilterStateKey )
79
+ if err != nil {
80
+ // The metadata wasn't pre-computed in prefilter. We ignore the error for now since
81
+ // Filter is able to handle that by computing it again.
82
+ klog .Error (err )
83
+ return nil , nil
84
+ }
85
+
86
+ s , ok := c .(preFilterState )
87
+ if ! ok {
88
+ return nil , fmt .Errorf ("%+v convert to nodeports.preFilterState error" , c )
89
+ }
90
+ return s , nil
91
+ }
92
+
43
93
// Filter invoked at the filter extension point.
44
- func (pl * NodePorts ) Filter (ctx context.Context , _ * framework.CycleState , pod * v1.Pod , nodeInfo * nodeinfo.NodeInfo ) * framework.Status {
45
- _ , reasons , err := predicates .PodFitsHostPorts (pod , nil , nodeInfo )
94
+ func (pl * NodePorts ) Filter (ctx context.Context , cycleState * framework.CycleState , pod * v1.Pod , nodeInfo * nodeinfo.NodeInfo ) * framework.Status {
95
+ state , err := getPreFilterState (cycleState )
96
+ if err != nil {
97
+ return framework .NewStatus (framework .Error , err .Error ())
98
+ }
99
+ _ , reasons , err := predicates .PodFitsHostPortsPredicate (pod , state , nodeInfo )
46
100
return migration .PredicateResultToFrameworkStatus (reasons , err )
47
101
}
48
102
0 commit comments