mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
fix(topologyspread): register UpdatePodTolerations when QHint is enabled
This commit is contained in:
parent
048c8536d6
commit
9c3d4a6fe4
@ -69,6 +69,7 @@ type PodTopologySpread struct {
|
|||||||
statefulSets appslisters.StatefulSetLister
|
statefulSets appslisters.StatefulSetLister
|
||||||
enableNodeInclusionPolicyInPodTopologySpread bool
|
enableNodeInclusionPolicyInPodTopologySpread bool
|
||||||
enableMatchLabelKeysInPodTopologySpread bool
|
enableMatchLabelKeysInPodTopologySpread bool
|
||||||
|
enableSchedulingQueueHint bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ framework.PreFilterPlugin = &PodTopologySpread{}
|
var _ framework.PreFilterPlugin = &PodTopologySpread{}
|
||||||
@ -103,6 +104,7 @@ func New(_ context.Context, plArgs runtime.Object, h framework.Handle, fts featu
|
|||||||
defaultConstraints: args.DefaultConstraints,
|
defaultConstraints: args.DefaultConstraints,
|
||||||
enableNodeInclusionPolicyInPodTopologySpread: fts.EnableNodeInclusionPolicyInPodTopologySpread,
|
enableNodeInclusionPolicyInPodTopologySpread: fts.EnableNodeInclusionPolicyInPodTopologySpread,
|
||||||
enableMatchLabelKeysInPodTopologySpread: fts.EnableMatchLabelKeysInPodTopologySpread,
|
enableMatchLabelKeysInPodTopologySpread: fts.EnableMatchLabelKeysInPodTopologySpread,
|
||||||
|
enableSchedulingQueueHint: fts.EnableSchedulingQueueHint,
|
||||||
}
|
}
|
||||||
if args.DefaultingType == config.SystemDefaulting {
|
if args.DefaultingType == config.SystemDefaulting {
|
||||||
pl.defaultConstraints = systemDefaultConstraints
|
pl.defaultConstraints = systemDefaultConstraints
|
||||||
@ -135,6 +137,18 @@ func (pl *PodTopologySpread) setListers(factory informers.SharedInformerFactory)
|
|||||||
// EventsToRegister returns the possible events that may make a Pod
|
// EventsToRegister returns the possible events that may make a Pod
|
||||||
// failed by this plugin schedulable.
|
// failed by this plugin schedulable.
|
||||||
func (pl *PodTopologySpread) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) {
|
func (pl *PodTopologySpread) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) {
|
||||||
|
podActionType := framework.Add | framework.UpdatePodLabel | framework.Delete
|
||||||
|
if pl.enableSchedulingQueueHint {
|
||||||
|
// When the QueueingHint feature is enabled,
|
||||||
|
// the scheduling queue uses Pod/Update Queueing Hint
|
||||||
|
// to determine whether a Pod's update makes the Pod schedulable or not.
|
||||||
|
// https://github.com/kubernetes/kubernetes/pull/122234
|
||||||
|
// The Pod rejected by this plugin can be schedulable when the Pod has a spread constraint with NodeTaintsPolicy:Honor
|
||||||
|
// and has got a new toleration.
|
||||||
|
// So, we add UpdatePodTolerations here only when QHint is enabled.
|
||||||
|
podActionType = framework.Add | framework.UpdatePodLabel | framework.UpdatePodTolerations | framework.Delete
|
||||||
|
}
|
||||||
|
|
||||||
return []framework.ClusterEventWithHint{
|
return []framework.ClusterEventWithHint{
|
||||||
// All ActionType includes the following events:
|
// All ActionType includes the following events:
|
||||||
// - Add. An unschedulable Pod may fail due to violating topology spread constraints,
|
// - Add. An unschedulable Pod may fail due to violating topology spread constraints,
|
||||||
@ -143,15 +157,27 @@ func (pl *PodTopologySpread) EventsToRegister(_ context.Context) ([]framework.Cl
|
|||||||
// an unschedulable Pod schedulable.
|
// an unschedulable Pod schedulable.
|
||||||
// - Delete. An unschedulable Pod may fail due to violating an existing Pod's topology spread constraints,
|
// - Delete. An unschedulable Pod may fail due to violating an existing Pod's topology spread constraints,
|
||||||
// deleting an existing Pod may make it schedulable.
|
// deleting an existing Pod may make it schedulable.
|
||||||
{Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.Add | framework.UpdatePodLabel | framework.Delete}, QueueingHintFn: pl.isSchedulableAfterPodChange},
|
{Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: podActionType}, QueueingHintFn: pl.isSchedulableAfterPodChange},
|
||||||
// Node add|delete|update maybe lead an topology key changed,
|
// Node add|delete|update maybe lead an topology key changed,
|
||||||
// and make these pod in scheduling schedulable or unschedulable.
|
// and make these pod in scheduling schedulable or unschedulable.
|
||||||
{Event: framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Add | framework.Delete | framework.UpdateNodeLabel | framework.UpdateNodeTaint}, QueueingHintFn: pl.isSchedulableAfterNodeChange},
|
{Event: framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Add | framework.Delete | framework.UpdateNodeLabel | framework.UpdateNodeTaint}, QueueingHintFn: pl.isSchedulableAfterNodeChange},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// involvedInTopologySpreading returns true if the incomingPod is involved in the topology spreading of podWithSpreading.
|
||||||
func involvedInTopologySpreading(incomingPod, podWithSpreading *v1.Pod) bool {
|
func involvedInTopologySpreading(incomingPod, podWithSpreading *v1.Pod) bool {
|
||||||
return incomingPod.Spec.NodeName != "" && incomingPod.Namespace == podWithSpreading.Namespace
|
return incomingPod.UID == podWithSpreading.UID ||
|
||||||
|
(incomingPod.Spec.NodeName != "" && incomingPod.Namespace == podWithSpreading.Namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasConstraintWithNodeTaintsPolicyHonor returns true if any constraint has `NodeTaintsPolicy: Honor`.
|
||||||
|
func hasConstraintWithNodeTaintsPolicyHonor(constraints []topologySpreadConstraint) bool {
|
||||||
|
for _, c := range constraints {
|
||||||
|
if c.NodeTaintsPolicy == v1.NodeInclusionPolicyHonor {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pl *PodTopologySpread) isSchedulableAfterPodChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
|
func (pl *PodTopologySpread) isSchedulableAfterPodChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
|
||||||
@ -173,8 +199,15 @@ func (pl *PodTopologySpread) isSchedulableAfterPodChange(logger klog.Logger, pod
|
|||||||
|
|
||||||
// Pod is modified. Return Queue when the label(s) matching topologySpread's selector is added, changed, or deleted.
|
// Pod is modified. Return Queue when the label(s) matching topologySpread's selector is added, changed, or deleted.
|
||||||
if modifiedPod != nil && originalPod != nil {
|
if modifiedPod != nil && originalPod != nil {
|
||||||
|
if pod.UID == modifiedPod.UID && !reflect.DeepEqual(modifiedPod.Spec.Tolerations, originalPod.Spec.Tolerations) && hasConstraintWithNodeTaintsPolicyHonor(constraints) {
|
||||||
|
// If any constraint has `NodeTaintsPolicy: Honor`, we can return Queue when the target Pod has got a new toleration.
|
||||||
|
logger.V(5).Info("the unschedulable pod has got a new toleration, which could make it schedulable",
|
||||||
|
"pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod))
|
||||||
|
return framework.Queue, nil
|
||||||
|
}
|
||||||
|
|
||||||
if reflect.DeepEqual(modifiedPod.Labels, originalPod.Labels) {
|
if reflect.DeepEqual(modifiedPod.Labels, originalPod.Labels) {
|
||||||
logger.V(5).Info("the updated pod is unscheduled or has no updated labels or has different namespace with target pod, so it doesn't make the target pod schedulable",
|
logger.V(5).Info("the pod's update doesn't include the label update, which doesn't make the target pod schedulable",
|
||||||
"pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod))
|
"pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod))
|
||||||
return framework.QueueSkip, nil
|
return framework.QueueSkip, nil
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
plugintesting "k8s.io/kubernetes/pkg/scheduler/framework/plugins/testing"
|
plugintesting "k8s.io/kubernetes/pkg/scheduler/framework/plugins/testing"
|
||||||
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
|
"k8s.io/utils/ptr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_isSchedulableAfterNodeChange(t *testing.T) {
|
func Test_isSchedulableAfterNodeChange(t *testing.T) {
|
||||||
@ -150,150 +151,192 @@ func Test_isSchedulableAfterNodeChange(t *testing.T) {
|
|||||||
|
|
||||||
func Test_isSchedulableAfterPodChange(t *testing.T) {
|
func Test_isSchedulableAfterPodChange(t *testing.T) {
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
name string
|
name string
|
||||||
pod *v1.Pod
|
pod *v1.Pod
|
||||||
oldPod, newPod *v1.Pod
|
oldPod, newPod *v1.Pod
|
||||||
expectedHint framework.QueueingHint
|
expectedHint framework.QueueingHint
|
||||||
expectedErr bool
|
expectedErr bool
|
||||||
|
enableNodeInclusionPolicyInPodTopologySpread bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "add pod with labels match topologySpreadConstraints selector",
|
name: "add pod with labels match topologySpreadConstraints selector",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Label("foo", "").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Obj(),
|
||||||
expectedHint: framework.Queue,
|
expectedHint: framework.Queue,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "add un-scheduled pod",
|
name: "add un-scheduled pod",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
newPod: st.MakePod().Label("foo", "").Obj(),
|
newPod: st.MakePod().UID("p2").Label("foo", "").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "update un-scheduled pod",
|
name: "update un-scheduled pod",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
newPod: st.MakePod().Label("foo", "").Obj(),
|
newPod: st.MakePod().UID("p2").Label("foo", "").Obj(),
|
||||||
oldPod: st.MakePod().Label("bar", "").Obj(),
|
oldPod: st.MakePod().UID("p2").Label("bar", "").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "delete un-scheduled pod",
|
name: "delete un-scheduled pod",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Label("foo", "").Obj(),
|
oldPod: st.MakePod().UID("p2").Label("foo", "").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "add pod with different namespace",
|
name: "add pod with different namespace",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Namespace("fake-namespace").Label("foo", "").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Namespace("fake-namespace").Label("foo", "").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "add pod with labels don't match topologySpreadConstraints selector",
|
name: "add pod with labels don't match topologySpreadConstraints selector",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Label("bar", "").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Label("bar", "").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "delete pod with labels that match topologySpreadConstraints selector",
|
name: "delete pod with labels that match topologySpreadConstraints selector",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Node("fake-node").Label("foo", "").Obj(),
|
oldPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Obj(),
|
||||||
expectedHint: framework.Queue,
|
expectedHint: framework.Queue,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "delete pod with labels that don't match topologySpreadConstraints selector",
|
name: "delete pod with labels that don't match topologySpreadConstraints selector",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Node("fake-node").Label("bar", "").Obj(),
|
oldPod: st.MakePod().UID("p2").Node("fake-node").Label("bar", "").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "update pod's non-related label",
|
name: "update pod's non-related label",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Node("fake-node").Label("foo", "").Label("bar", "bar1").Obj(),
|
oldPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Label("bar", "bar1").Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Label("foo", "").Label("bar", "bar2").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Label("bar", "bar2").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "add pod's label that matches topologySpreadConstraints selector",
|
name: "add pod's label that matches topologySpreadConstraints selector",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Node("fake-node").Obj(),
|
oldPod: st.MakePod().UID("p2").Node("fake-node").Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Label("foo", "").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Obj(),
|
||||||
expectedHint: framework.Queue,
|
expectedHint: framework.Queue,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "delete pod label that matches topologySpreadConstraints selector",
|
name: "delete pod label that matches topologySpreadConstraints selector",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Node("fake-node").Label("foo", "").Obj(),
|
oldPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Obj(),
|
||||||
expectedHint: framework.Queue,
|
expectedHint: framework.Queue,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "change pod's label that matches topologySpreadConstraints selector",
|
name: "change pod's label that matches topologySpreadConstraints selector",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Node("fake-node").Label("foo", "foo1").Obj(),
|
oldPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "foo1").Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Label("foo", "foo2").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "foo2").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "change pod's label that doesn't match topologySpreadConstraints selector",
|
name: "change pod's label that doesn't match topologySpreadConstraints selector",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Node("fake-node").Label("foo", "").Label("bar", "bar1").Obj(),
|
oldPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Label("bar", "bar1").Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Label("foo", "").Label("bar", "bar2").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Label("bar", "bar2").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "add pod's label that matches topologySpreadConstraints selector with multi topologySpreadConstraints",
|
name: "add pod's label that matches topologySpreadConstraints selector with multi topologySpreadConstraints",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Node("fake-node").Label("foo", "").Obj(),
|
oldPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Label("foo", "").Label("bar", "bar2").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Label("bar", "bar2").Obj(),
|
||||||
expectedHint: framework.Queue,
|
expectedHint: framework.Queue,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "change pod's label that doesn't match topologySpreadConstraints selector with multi topologySpreadConstraints",
|
name: "change pod's label that doesn't match topologySpreadConstraints selector with multi topologySpreadConstraints",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Node("fake-node").Label("foo", "").Obj(),
|
oldPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Label("foo", "").Label("baz", "").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Label("baz", "").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "change pod's label that match topologySpreadConstraints selector with multi topologySpreadConstraints",
|
name: "change pod's label that match topologySpreadConstraints selector with multi topologySpreadConstraints",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
oldPod: st.MakePod().Node("fake-node").Label("foo", "").Label("bar", "").Obj(),
|
oldPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Label("bar", "").Obj(),
|
||||||
newPod: st.MakePod().Node("fake-node").Label("foo", "").Label("bar", "bar2").Obj(),
|
newPod: st.MakePod().UID("p2").Node("fake-node").Label("foo", "").Label("bar", "bar2").Obj(),
|
||||||
|
expectedHint: framework.QueueSkip,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "the unschedulable Pod has topologySpreadConstraint with NodeTaintsPolicy:Honor and has got a new toleration",
|
||||||
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, ptr.To(v1.NodeInclusionPolicyHonor), nil).
|
||||||
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
|
Obj(),
|
||||||
|
oldPod: st.MakePod().UID("p").Name("p").Label("foo", "").Obj(),
|
||||||
|
newPod: st.MakePod().UID("p").Name("p").Label("foo", "").Toleration(v1.TaintNodeUnschedulable).Obj(),
|
||||||
|
expectedHint: framework.Queue,
|
||||||
|
enableNodeInclusionPolicyInPodTopologySpread: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "the unschedulable Pod has topologySpreadConstraint without NodeTaintsPolicy:Honor and has got a new toleration",
|
||||||
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, ptr.To(v1.NodeInclusionPolicyIgnore), nil).
|
||||||
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
|
Obj(),
|
||||||
|
oldPod: st.MakePod().UID("p").Name("p").Label("foo", "").Obj(),
|
||||||
|
newPod: st.MakePod().UID("p").Name("p").Label("foo", "").Toleration(v1.TaintNodeUnschedulable).Obj(),
|
||||||
|
expectedHint: framework.QueueSkip,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "the unschedulable Pod has topologySpreadConstraint and has got a new label matching the selector of the constraint",
|
||||||
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, ptr.To(v1.NodeInclusionPolicyIgnore), nil).
|
||||||
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
|
Obj(),
|
||||||
|
oldPod: st.MakePod().UID("p").Name("p").Obj(),
|
||||||
|
newPod: st.MakePod().UID("p").Name("p").Label("foo", "").Obj(),
|
||||||
|
expectedHint: framework.Queue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "the unschedulable Pod has topologySpreadConstraint and has got a new unrelated label",
|
||||||
|
pod: st.MakePod().UID("p").Name("p").Label("foo", "").
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, ptr.To(v1.NodeInclusionPolicyIgnore), nil).
|
||||||
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
|
Obj(),
|
||||||
|
oldPod: st.MakePod().UID("p").Name("p").Obj(),
|
||||||
|
newPod: st.MakePod().UID("p").Name("p").Label("unrelated", "").Obj(),
|
||||||
expectedHint: framework.QueueSkip,
|
expectedHint: framework.QueueSkip,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -303,6 +346,8 @@ func Test_isSchedulableAfterPodChange(t *testing.T) {
|
|||||||
snapshot := cache.NewSnapshot(nil, nil)
|
snapshot := cache.NewSnapshot(nil, nil)
|
||||||
pl := plugintesting.SetupPlugin(ctx, t, topologySpreadFunc, &config.PodTopologySpreadArgs{DefaultingType: config.ListDefaulting}, snapshot)
|
pl := plugintesting.SetupPlugin(ctx, t, topologySpreadFunc, &config.PodTopologySpreadArgs{DefaultingType: config.ListDefaulting}, snapshot)
|
||||||
p := pl.(*PodTopologySpread)
|
p := pl.(*PodTopologySpread)
|
||||||
|
p.enableNodeInclusionPolicyInPodTopologySpread = tc.enableNodeInclusionPolicyInPodTopologySpread
|
||||||
|
|
||||||
actualHint, err := p.isSchedulableAfterPodChange(logger, tc.pod, tc.oldPod, tc.newPod)
|
actualHint, err := p.isSchedulableAfterPodChange(logger, tc.pod, tc.oldPod, tc.newPod)
|
||||||
if tc.expectedErr {
|
if tc.expectedErr {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
Loading…
Reference in New Issue
Block a user