...
1
16
17 package nodeunschedulable
18
19 import (
20 "context"
21
22 v1 "k8s.io/api/core/v1"
23 "k8s.io/apimachinery/pkg/runtime"
24 v1helper "k8s.io/component-helpers/scheduling/corev1"
25 "k8s.io/klog/v2"
26 "k8s.io/kubernetes/pkg/scheduler/framework"
27 "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names"
28 "k8s.io/kubernetes/pkg/scheduler/util"
29 )
30
31
32
33 type NodeUnschedulable struct {
34 }
35
36 var _ framework.FilterPlugin = &NodeUnschedulable{}
37 var _ framework.EnqueueExtensions = &NodeUnschedulable{}
38
39
40 const Name = names.NodeUnschedulable
41
42 const (
43
44 ErrReasonUnknownCondition = "node(s) had unknown conditions"
45
46 ErrReasonUnschedulable = "node(s) were unschedulable"
47 )
48
49
50
51 func (pl *NodeUnschedulable) EventsToRegister() []framework.ClusterEventWithHint {
52 return []framework.ClusterEventWithHint{
53 {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterNodeChange},
54 }
55 }
56
57
58
59
60 func (pl *NodeUnschedulable) isSchedulableAfterNodeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
61 _, modifiedNode, err := util.As[*v1.Node](oldObj, newObj)
62 if err != nil {
63 return framework.Queue, err
64 }
65
66 if !modifiedNode.Spec.Unschedulable {
67 logger.V(5).Info("node was created or updated, pod may be schedulable now", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode))
68 return framework.Queue, nil
69 }
70
71
72
73
74 logger.V(5).Info("node was created or updated, but it doesn't make this pod schedulable", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode))
75 return framework.QueueSkip, nil
76 }
77
78
79 func (pl *NodeUnschedulable) Name() string {
80 return Name
81 }
82
83
84 func (pl *NodeUnschedulable) Filter(ctx context.Context, _ *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status {
85 node := nodeInfo.Node()
86
87 if !node.Spec.Unschedulable {
88 return nil
89 }
90
91
92 podToleratesUnschedulable := v1helper.TolerationsTolerateTaint(pod.Spec.Tolerations, &v1.Taint{
93 Key: v1.TaintNodeUnschedulable,
94 Effect: v1.TaintEffectNoSchedule,
95 })
96 if !podToleratesUnschedulable {
97 return framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonUnschedulable)
98 }
99
100 return nil
101 }
102
103
104 func New(_ context.Context, _ runtime.Object, _ framework.Handle) (framework.Plugin, error) {
105 return &NodeUnschedulable{}, nil
106 }
107
View as plain text