mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
implementation for MatchLabelKeys in TopologySpreadConstraint
Signed-off-by: Alex Wang <wangqingcan1990@gmail.com>
This commit is contained in:
parent
e6c2bf8516
commit
f4bc904376
@ -515,6 +515,13 @@ const (
|
|||||||
// Enables scaling down replicas via logarithmic comparison of creation/ready timestamps
|
// Enables scaling down replicas via logarithmic comparison of creation/ready timestamps
|
||||||
LogarithmicScaleDown featuregate.Feature = "LogarithmicScaleDown"
|
LogarithmicScaleDown featuregate.Feature = "LogarithmicScaleDown"
|
||||||
|
|
||||||
|
// owner: @denkensk
|
||||||
|
// kep: http://kep.k8s.io/3243
|
||||||
|
// alpha: v1.25
|
||||||
|
//
|
||||||
|
// Enable MatchLabelKeys in PodTopologySpread.
|
||||||
|
MatchLabelKeysInPodTopologySpread featuregate.Feature = "MatchLabelKeysInPodTopologySpread"
|
||||||
|
|
||||||
// owner: @krmayankk
|
// owner: @krmayankk
|
||||||
// alpha: v1.24
|
// alpha: v1.24
|
||||||
//
|
//
|
||||||
@ -948,6 +955,8 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
|
|
||||||
LogarithmicScaleDown: {Default: true, PreRelease: featuregate.Beta},
|
LogarithmicScaleDown: {Default: true, PreRelease: featuregate.Beta},
|
||||||
|
|
||||||
|
MatchLabelKeysInPodTopologySpread: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
|
||||||
MaxUnavailableStatefulSet: {Default: false, PreRelease: featuregate.Alpha},
|
MaxUnavailableStatefulSet: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
|
||||||
MemoryManager: {Default: true, PreRelease: featuregate.Beta},
|
MemoryManager: {Default: true, PreRelease: featuregate.Beta},
|
||||||
|
@ -644,8 +644,8 @@ func TestDryRunPreemption(t *testing.T) {
|
|||||||
nodeNames: []string{"node-a/zone1", "node-b/zone1", "node-x/zone2"},
|
nodeNames: []string{"node-a/zone1", "node-b/zone1", "node-x/zone2"},
|
||||||
testPods: []*v1.Pod{
|
testPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p").UID("p").Label("foo", "").Priority(highPriority).
|
st.MakePod().Name("p").UID("p").Label("foo", "").Priority(highPriority).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "hostname", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "hostname", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
},
|
},
|
||||||
initPods: []*v1.Pod{
|
initPods: []*v1.Pod{
|
||||||
@ -1486,8 +1486,8 @@ func TestPreempt(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "preemption for topology spread constraints",
|
name: "preemption for topology spread constraints",
|
||||||
pod: st.MakePod().Name("p").UID("p").Namespace(v1.NamespaceDefault).Label("foo", "").Priority(highPriority).
|
pod: st.MakePod().Name("p").UID("p").Namespace(v1.NamespaceDefault).Label("foo", "").Priority(highPriority).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "hostname", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "hostname", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").UID("p-a1").Namespace(v1.NamespaceDefault).Node("node-a").Label("foo", "").Priority(highPriority).Obj(),
|
st.MakePod().Name("p-a1").UID("p-a1").Namespace(v1.NamespaceDefault).Node("node-a").Label("foo", "").Priority(highPriority).Obj(),
|
||||||
|
@ -24,4 +24,5 @@ type Features struct {
|
|||||||
EnableVolumeCapacityPriority bool
|
EnableVolumeCapacityPriority bool
|
||||||
EnableMinDomainsInPodTopologySpread bool
|
EnableMinDomainsInPodTopologySpread bool
|
||||||
EnableNodeInclusionPolicyInPodTopologySpread bool
|
EnableNodeInclusionPolicyInPodTopologySpread bool
|
||||||
|
EnableMatchLabelKeysInPodTopologySpread bool
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func (tsc *topologySpreadConstraint) matchNodeInclusionPolicies(pod *v1.Pod, nod
|
|||||||
// .DefaultConstraints and the selectors from the services, replication
|
// .DefaultConstraints and the selectors from the services, replication
|
||||||
// controllers, replica sets and stateful sets that match the pod.
|
// controllers, replica sets and stateful sets that match the pod.
|
||||||
func (pl *PodTopologySpread) buildDefaultConstraints(p *v1.Pod, action v1.UnsatisfiableConstraintAction) ([]topologySpreadConstraint, error) {
|
func (pl *PodTopologySpread) buildDefaultConstraints(p *v1.Pod, action v1.UnsatisfiableConstraintAction) ([]topologySpreadConstraint, error) {
|
||||||
constraints, err := filterTopologySpreadConstraints(pl.defaultConstraints, action, pl.enableMinDomainsInPodTopologySpread, pl.enableNodeInclusionPolicyInPodTopologySpread)
|
constraints, err := pl.filterTopologySpreadConstraints(pl.defaultConstraints, p.Labels, action)
|
||||||
if err != nil || len(constraints) == 0 {
|
if err != nil || len(constraints) == 0 {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ func nodeLabelsMatchSpreadConstraints(nodeLabels map[string]string, constraints
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterTopologySpreadConstraints(constraints []v1.TopologySpreadConstraint, action v1.UnsatisfiableConstraintAction, enableMinDomainsInPodTopologySpread, enableNodeInclusionPolicyInPodTopologySpread bool) ([]topologySpreadConstraint, error) {
|
func (pl *PodTopologySpread) filterTopologySpreadConstraints(constraints []v1.TopologySpreadConstraint, podLabels map[string]string, action v1.UnsatisfiableConstraintAction) ([]topologySpreadConstraint, error) {
|
||||||
var result []topologySpreadConstraint
|
var result []topologySpreadConstraint
|
||||||
for _, c := range constraints {
|
for _, c := range constraints {
|
||||||
if c.WhenUnsatisfiable == action {
|
if c.WhenUnsatisfiable == action {
|
||||||
@ -95,6 +95,19 @@ func filterTopologySpreadConstraints(constraints []v1.TopologySpreadConstraint,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pl.enableMatchLabelKeysInPodTopologySpread && len(c.MatchLabelKeys) > 0 {
|
||||||
|
matchLabels := make(labels.Set)
|
||||||
|
for _, labelKey := range c.MatchLabelKeys {
|
||||||
|
if value, ok := podLabels[labelKey]; ok {
|
||||||
|
matchLabels[labelKey] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(matchLabels) > 0 {
|
||||||
|
selector = mergeLabelSetWithSelector(matchLabels, selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tsc := topologySpreadConstraint{
|
tsc := topologySpreadConstraint{
|
||||||
MaxSkew: c.MaxSkew,
|
MaxSkew: c.MaxSkew,
|
||||||
TopologyKey: c.TopologyKey,
|
TopologyKey: c.TopologyKey,
|
||||||
@ -103,10 +116,10 @@ func filterTopologySpreadConstraints(constraints []v1.TopologySpreadConstraint,
|
|||||||
NodeAffinityPolicy: v1.NodeInclusionPolicyHonor, // If NodeAffinityPolicy is nil, we treat NodeAffinityPolicy as "Honor".
|
NodeAffinityPolicy: v1.NodeInclusionPolicyHonor, // If NodeAffinityPolicy is nil, we treat NodeAffinityPolicy as "Honor".
|
||||||
NodeTaintsPolicy: v1.NodeInclusionPolicyIgnore, // If NodeTaintsPolicy is nil, we treat NodeTaintsPolicy as "Ignore".
|
NodeTaintsPolicy: v1.NodeInclusionPolicyIgnore, // If NodeTaintsPolicy is nil, we treat NodeTaintsPolicy as "Ignore".
|
||||||
}
|
}
|
||||||
if enableMinDomainsInPodTopologySpread && c.MinDomains != nil {
|
if pl.enableMinDomainsInPodTopologySpread && c.MinDomains != nil {
|
||||||
tsc.MinDomains = *c.MinDomains
|
tsc.MinDomains = *c.MinDomains
|
||||||
}
|
}
|
||||||
if enableNodeInclusionPolicyInPodTopologySpread {
|
if pl.enableNodeInclusionPolicyInPodTopologySpread {
|
||||||
if c.NodeAffinityPolicy != nil {
|
if c.NodeAffinityPolicy != nil {
|
||||||
tsc.NodeAffinityPolicy = *c.NodeAffinityPolicy
|
tsc.NodeAffinityPolicy = *c.NodeAffinityPolicy
|
||||||
}
|
}
|
||||||
@ -120,6 +133,17 @@ func filterTopologySpreadConstraints(constraints []v1.TopologySpreadConstraint,
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mergeLabelSetWithSelector(matchLabels labels.Set, s labels.Selector) labels.Selector {
|
||||||
|
mergedSelector := labels.SelectorFromSet(matchLabels)
|
||||||
|
if requirements, ok := s.Requirements(); ok {
|
||||||
|
for _, r := range requirements {
|
||||||
|
mergedSelector = mergedSelector.Add(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mergedSelector
|
||||||
|
}
|
||||||
|
|
||||||
func countPodsMatchSelector(podInfos []*framework.PodInfo, selector labels.Selector, ns string) int {
|
func countPodsMatchSelector(podInfos []*framework.PodInfo, selector labels.Selector, ns string) int {
|
||||||
count := 0
|
count := 0
|
||||||
for _, p := range podInfos {
|
for _, p := range podInfos {
|
||||||
|
@ -244,11 +244,10 @@ func (pl *PodTopologySpread) calPreFilterState(ctx context.Context, pod *v1.Pod)
|
|||||||
if len(pod.Spec.TopologySpreadConstraints) > 0 {
|
if len(pod.Spec.TopologySpreadConstraints) > 0 {
|
||||||
// We have feature gating in APIServer to strip the spec
|
// We have feature gating in APIServer to strip the spec
|
||||||
// so don't need to re-check feature gate, just check length of Constraints.
|
// so don't need to re-check feature gate, just check length of Constraints.
|
||||||
constraints, err = filterTopologySpreadConstraints(
|
constraints, err = pl.filterTopologySpreadConstraints(
|
||||||
pod.Spec.TopologySpreadConstraints,
|
pod.Spec.TopologySpreadConstraints,
|
||||||
|
pod.Labels,
|
||||||
v1.DoNotSchedule,
|
v1.DoNotSchedule,
|
||||||
pl.enableMinDomainsInPodTopologySpread,
|
|
||||||
pl.enableNodeInclusionPolicyInPodTopologySpread,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("obtaining pod's hard topology spread constraints: %w", err)
|
return nil, fmt.Errorf("obtaining pod's hard topology spread constraints: %w", err)
|
||||||
|
@ -55,7 +55,8 @@ var (
|
|||||||
honorPolicy = v1.NodeInclusionPolicyHonor
|
honorPolicy = v1.NodeInclusionPolicyHonor
|
||||||
fooSelector = st.MakeLabelSelector().Exists("foo").Obj()
|
fooSelector = st.MakeLabelSelector().Exists("foo").Obj()
|
||||||
barSelector = st.MakeLabelSelector().Exists("bar").Obj()
|
barSelector = st.MakeLabelSelector().Exists("bar").Obj()
|
||||||
taints = []v1.Taint{{Key: v1.TaintNodeUnschedulable, Value: "", Effect: v1.TaintEffectPreferNoSchedule}}
|
|
||||||
|
taints = []v1.Taint{{Key: v1.TaintNodeUnschedulable, Value: "", Effect: v1.TaintEffectPreferNoSchedule}}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *criticalPaths) sort() {
|
func (p *criticalPaths) sort() {
|
||||||
@ -77,11 +78,12 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
want *preFilterState
|
want *preFilterState
|
||||||
enableMinDomains bool
|
enableMinDomains bool
|
||||||
enableNodeInclustionPolicy bool
|
enableNodeInclustionPolicy bool
|
||||||
|
enableMatchLabelKeys bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "clean cluster with one spreadConstraint",
|
name: "clean cluster with one spreadConstraint",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(5, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Label("foo", "bar").Obj(), nil, nil, nil).
|
SpreadConstraint(5, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Label("foo", "bar").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -112,7 +114,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "normal case with one spreadConstraint",
|
name: "normal case with one spreadConstraint",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -150,7 +152,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "normal case with one spreadConstraint, on a 3-zone cluster",
|
name: "normal case with one spreadConstraint, on a 3-zone cluster",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -191,7 +193,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "namespace mismatch doesn't count",
|
name: "namespace mismatch doesn't count",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -229,8 +231,8 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "normal case with two spreadConstraints",
|
name: "normal case with two spreadConstraints",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -283,10 +285,10 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "soft spreadConstraints should be bypassed",
|
name: "soft spreadConstraints should be bypassed",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -337,8 +339,8 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "different labelSelectors - simple version",
|
name: "different labelSelectors - simple version",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -384,8 +386,8 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "different labelSelectors - complex pods",
|
name: "different labelSelectors - complex pods",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -437,8 +439,8 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
name: "two spreadConstraints, and with podAffinity",
|
name: "two spreadConstraints, and with podAffinity",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityNotIn("node", []string{"node-x"}). // exclude node-x
|
NodeAffinityNotIn("node", []string{"node-x"}). // exclude node-x
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -538,8 +540,8 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "default constraints and a service, but pod has constraints",
|
name: "default constraints and a service, but pod has constraints",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "bar").Label("baz", "tar").
|
pod: st.MakePod().Name("p").Label("foo", "bar").Label("baz", "tar").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Label("baz", "tar").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Label("baz", "tar").Obj(), nil, nil, nil, nil).
|
||||||
SpreadConstraint(2, "planet", v1.ScheduleAnyway, st.MakeLabelSelector().Label("fot", "rok").Obj(), nil, nil, nil).
|
SpreadConstraint(2, "planet", v1.ScheduleAnyway, st.MakeLabelSelector().Label("fot", "rok").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
defaultConstraints: []v1.TopologySpreadConstraint{
|
defaultConstraints: []v1.TopologySpreadConstraint{
|
||||||
{MaxSkew: 2, TopologyKey: "node", WhenUnsatisfiable: v1.DoNotSchedule},
|
{MaxSkew: 2, TopologyKey: "node", WhenUnsatisfiable: v1.DoNotSchedule},
|
||||||
@ -578,8 +580,8 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "TpKeyToDomainsNum is calculated when MinDomains is enabled",
|
name: "TpKeyToDomainsNum is calculated when MinDomains is enabled",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -638,7 +640,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
name: "feature gate disabled with NodeAffinityPolicy",
|
name: "feature gate disabled with NodeAffinityPolicy",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -676,7 +678,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy honored with labelSelectors",
|
name: "NodeAffinityPolicy honored with labelSelectors",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -714,7 +716,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy ignored with labelSelectors",
|
name: "NodeAffinityPolicy ignored with labelSelectors",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -753,7 +755,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy honored with nodeAffinity",
|
name: "NodeAffinityPolicy honored with nodeAffinity",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityIn("foo", []string{""}).
|
NodeAffinityIn("foo", []string{""}).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -791,7 +793,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy ignored with nodeAffinity",
|
name: "NodeAffinityPolicy ignored with nodeAffinity",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityIn("foo", []string{""}).
|
NodeAffinityIn("foo", []string{""}).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -829,7 +831,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "feature gate disabled with NodeTaintsPolicy",
|
name: "feature gate disabled with NodeTaintsPolicy",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
||||||
@ -867,7 +869,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "NodeTaintsPolicy ignored",
|
name: "NodeTaintsPolicy ignored",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
||||||
@ -905,7 +907,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "NodeTaintsPolicy honored",
|
name: "NodeTaintsPolicy honored",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, &honorPolicy).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, &honorPolicy, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
||||||
@ -943,7 +945,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
name: "NodeTaintsPolicy honored with tolerated taints",
|
name: "NodeTaintsPolicy honored with tolerated taints",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
Toleration(v1.TaintNodeUnschedulable).
|
Toleration(v1.TaintNodeUnschedulable).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, &honorPolicy).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, &honorPolicy, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
||||||
@ -982,8 +984,8 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
name: "two node inclusion Constraints, zone: honor/ignore, node: ignore/ignore",
|
name: "two node inclusion Constraints, zone: honor/ignore, node: ignore/ignore",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -1031,8 +1033,8 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "two node inclusion Constraints, zone: honor/honor, node: honor/ignore",
|
name: "two node inclusion Constraints, zone: honor/honor, node: honor/ignore",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, &honorPolicy).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, &honorPolicy, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -1081,8 +1083,8 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
name: "two node inclusion Constraints, zone: honor/ignore, node: honor/ignore",
|
name: "two node inclusion Constraints, zone: honor/ignore, node: honor/ignore",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1132,8 +1134,8 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
name: "two node inclusion Constraints, zone: ignore/ignore, node: honor/honor",
|
name: "two node inclusion Constraints, zone: ignore/ignore, node: honor/honor",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, &honorPolicy).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, &honorPolicy, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1180,6 +1182,162 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
},
|
},
|
||||||
enableNodeInclustionPolicy: true,
|
enableNodeInclustionPolicy: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ignored when feature gate disabled",
|
||||||
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, []string{"bar"}).
|
||||||
|
Obj(),
|
||||||
|
nodes: []*v1.Node{
|
||||||
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(),
|
||||||
|
st.MakeNode().Name("node-x").Label("zone", "zone2").Label("node", "node-x").Obj(),
|
||||||
|
st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
|
},
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Obj(),
|
||||||
|
},
|
||||||
|
want: &preFilterState{
|
||||||
|
Constraints: []topologySpreadConstraint{
|
||||||
|
{
|
||||||
|
MaxSkew: 1,
|
||||||
|
TopologyKey: "zone",
|
||||||
|
Selector: mustConvertLabelSelectorAsSelector(t, fooSelector),
|
||||||
|
MinDomains: 1,
|
||||||
|
NodeAffinityPolicy: v1.NodeInclusionPolicyHonor,
|
||||||
|
NodeTaintsPolicy: v1.NodeInclusionPolicyIgnore,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
|
"zone": {{"zone2", 2}, {"zone1", 3}},
|
||||||
|
},
|
||||||
|
TpPairToMatchNum: map[topologyPair]int{
|
||||||
|
{key: "zone", value: "zone1"}: 3,
|
||||||
|
{key: "zone", value: "zone2"}: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
enableMatchLabelKeys: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ANDed with LabelSelector when LabelSelector isn't empty",
|
||||||
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "a").
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, []string{"bar"}).
|
||||||
|
Obj(),
|
||||||
|
nodes: []*v1.Node{
|
||||||
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(),
|
||||||
|
st.MakeNode().Name("node-x").Label("zone", "zone2").Label("node", "node-x").Obj(),
|
||||||
|
st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
|
},
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Label("bar", "a").Obj(),
|
||||||
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Label("bar", "a").Obj(),
|
||||||
|
st.MakePod().Name("p-y2").Node("node-y").Label("bar", "").Obj(),
|
||||||
|
},
|
||||||
|
want: &preFilterState{
|
||||||
|
Constraints: []topologySpreadConstraint{
|
||||||
|
{
|
||||||
|
MaxSkew: 1,
|
||||||
|
TopologyKey: "zone",
|
||||||
|
Selector: mustConvertLabelSelectorAsSelector(t, st.MakeLabelSelector().Exists("foo").Label("bar", "a").Obj()),
|
||||||
|
MinDomains: 1,
|
||||||
|
NodeAffinityPolicy: v1.NodeInclusionPolicyHonor,
|
||||||
|
NodeTaintsPolicy: v1.NodeInclusionPolicyIgnore,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
|
"zone": {{"zone2", 1}, {"zone1", 1}},
|
||||||
|
},
|
||||||
|
TpPairToMatchNum: map[topologyPair]int{
|
||||||
|
{key: "zone", value: "zone1"}: 1,
|
||||||
|
{key: "zone", value: "zone2"}: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
enableMatchLabelKeys: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ANDed with LabelSelector when LabelSelector is empty",
|
||||||
|
pod: st.MakePod().Name("p").Label("foo", "a").
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Obj(), nil, nil, nil, []string{"foo"}).
|
||||||
|
Obj(),
|
||||||
|
nodes: []*v1.Node{
|
||||||
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(),
|
||||||
|
st.MakeNode().Name("node-x").Label("zone", "zone2").Label("node", "node-x").Obj(),
|
||||||
|
st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
|
},
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "a").Obj(),
|
||||||
|
st.MakePod().Name("p-a2").Node("node-a").Label("foo", "a").Obj(),
|
||||||
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "a").Obj(),
|
||||||
|
st.MakePod().Name("p-y1").Node("node-y").Label("foo", "a").Obj(),
|
||||||
|
st.MakePod().Name("p-y2").Node("node-y").Label("foo", "a").Obj(),
|
||||||
|
},
|
||||||
|
want: &preFilterState{
|
||||||
|
Constraints: []topologySpreadConstraint{
|
||||||
|
{
|
||||||
|
MaxSkew: 1,
|
||||||
|
TopologyKey: "zone",
|
||||||
|
Selector: mustConvertLabelSelectorAsSelector(t, st.MakeLabelSelector().Label("foo", "a").Obj()),
|
||||||
|
MinDomains: 1,
|
||||||
|
NodeAffinityPolicy: v1.NodeInclusionPolicyHonor,
|
||||||
|
NodeTaintsPolicy: v1.NodeInclusionPolicyIgnore,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
|
"zone": {{"zone2", 2}, {"zone1", 3}},
|
||||||
|
},
|
||||||
|
TpPairToMatchNum: map[topologyPair]int{
|
||||||
|
{key: "zone", value: "zone1"}: 3,
|
||||||
|
{key: "zone", value: "zone2"}: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
enableMatchLabelKeys: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "key in matchLabelKeys is ignored when it isn't exist in pod.labels",
|
||||||
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, []string{"bar"}).
|
||||||
|
Obj(),
|
||||||
|
nodes: []*v1.Node{
|
||||||
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(),
|
||||||
|
st.MakeNode().Name("node-x").Label("zone", "zone2").Label("node", "node-x").Obj(),
|
||||||
|
st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
|
},
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "a").Obj(),
|
||||||
|
st.MakePod().Name("p-a2").Node("node-a").Label("foo", "a").Obj(),
|
||||||
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "a").Obj(),
|
||||||
|
st.MakePod().Name("p-y1").Node("node-y").Label("foo", "a").Obj(),
|
||||||
|
st.MakePod().Name("p-y2").Node("node-y").Label("foo", "a").Obj(),
|
||||||
|
},
|
||||||
|
want: &preFilterState{
|
||||||
|
Constraints: []topologySpreadConstraint{
|
||||||
|
{
|
||||||
|
MaxSkew: 1,
|
||||||
|
TopologyKey: "zone",
|
||||||
|
Selector: mustConvertLabelSelectorAsSelector(t, fooSelector),
|
||||||
|
MinDomains: 1,
|
||||||
|
NodeAffinityPolicy: v1.NodeInclusionPolicyHonor,
|
||||||
|
NodeTaintsPolicy: v1.NodeInclusionPolicyIgnore,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
|
"zone": {{"zone2", 2}, {"zone1", 3}},
|
||||||
|
},
|
||||||
|
TpPairToMatchNum: map[topologyPair]int{
|
||||||
|
{key: "zone", value: "zone1"}: 3,
|
||||||
|
{key: "zone", value: "zone2"}: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
enableMatchLabelKeys: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@ -1193,6 +1351,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
p := plugintesting.SetupPluginWithInformers(ctx, t, topologySpreadFunc, args, cache.NewSnapshot(tt.existingPods, tt.nodes), tt.objs)
|
p := plugintesting.SetupPluginWithInformers(ctx, t, topologySpreadFunc, args, cache.NewSnapshot(tt.existingPods, tt.nodes), tt.objs)
|
||||||
p.(*PodTopologySpread).enableMinDomainsInPodTopologySpread = tt.enableMinDomains
|
p.(*PodTopologySpread).enableMinDomainsInPodTopologySpread = tt.enableMinDomains
|
||||||
p.(*PodTopologySpread).enableNodeInclusionPolicyInPodTopologySpread = tt.enableNodeInclustionPolicy
|
p.(*PodTopologySpread).enableNodeInclusionPolicyInPodTopologySpread = tt.enableNodeInclustionPolicy
|
||||||
|
p.(*PodTopologySpread).enableMatchLabelKeysInPodTopologySpread = tt.enableMatchLabelKeys
|
||||||
|
|
||||||
cs := framework.NewCycleState()
|
cs := framework.NewCycleState()
|
||||||
if _, s := p.(*PodTopologySpread).PreFilter(ctx, cs, tt.pod); !s.IsSuccess() {
|
if _, s := p.(*PodTopologySpread).PreFilter(ctx, cs, tt.pod); !s.IsSuccess() {
|
||||||
@ -1233,7 +1392,7 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "node a and b both impact current min match",
|
name: "node a and b both impact current min match",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
existingPods: nil, // it's an empty cluster
|
existingPods: nil, // it's an empty cluster
|
||||||
@ -1256,7 +1415,7 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "only node a impacts current min match",
|
name: "only node a impacts current min match",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
@ -1281,7 +1440,7 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "add a pod in a different namespace doesn't change topologyKeyToMinPodsMap",
|
name: "add a pod in a different namespace doesn't change topologyKeyToMinPodsMap",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
addedPod: st.MakePod().Name("p-a1").Namespace("ns1").Node("node-a").Label("foo", "").Obj(),
|
addedPod: st.MakePod().Name("p-a1").Namespace("ns1").Node("node-a").Label("foo", "").Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
@ -1306,7 +1465,7 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "add pod on non-critical node won't trigger re-calculation",
|
name: "add pod on non-critical node won't trigger re-calculation",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
addedPod: st.MakePod().Name("p-b2").Node("node-b").Label("foo", "").Obj(),
|
addedPod: st.MakePod().Name("p-b2").Node("node-b").Label("foo", "").Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
@ -1331,8 +1490,8 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "node a and x both impact topologyKeyToMinPodsMap on zone and node",
|
name: "node a and x both impact topologyKeyToMinPodsMap on zone and node",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
existingPods: nil, // it's an empty cluster
|
existingPods: nil, // it's an empty cluster
|
||||||
@ -1358,8 +1517,8 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "only node a impacts topologyKeyToMinPodsMap on zone and node",
|
name: "only node a impacts topologyKeyToMinPodsMap on zone and node",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
@ -1387,8 +1546,8 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "node a impacts topologyKeyToMinPodsMap on node, node x impacts topologyKeyToMinPodsMap on zone",
|
name: "node a impacts topologyKeyToMinPodsMap on node, node x impacts topologyKeyToMinPodsMap on zone",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
@ -1420,8 +1579,8 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Constraints hold different labelSelectors, node a impacts topologyKeyToMinPodsMap on zone",
|
name: "Constraints hold different labelSelectors, node a impacts topologyKeyToMinPodsMap on zone",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
@ -1463,8 +1622,8 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Constraints hold different labelSelectors, node a impacts topologyKeyToMinPodsMap on both zone and node",
|
name: "Constraints hold different labelSelectors, node a impacts topologyKeyToMinPodsMap on both zone and node",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Label("bar", "").Obj(),
|
addedPod: st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Label("bar", "").Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
@ -1506,7 +1665,7 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "add a pod that doesn't match node affinity when NodeInclustionPolicy disabled",
|
name: "add a pod that doesn't match node affinity when NodeInclustionPolicy disabled",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").NodeAffinityNotIn("foo", []string{"bar"}).
|
preemptor: st.MakePod().Name("p").Label("foo", "").NodeAffinityNotIn("foo", []string{"bar"}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodeIdx: 0,
|
nodeIdx: 0,
|
||||||
addedPod: st.MakePod().Name("p-a1").Node("node-b").Label("foo", "").Label("zone", "zone2").Obj(),
|
addedPod: st.MakePod().Name("p-a1").Node("node-b").Label("foo", "").Label("zone", "zone2").Obj(),
|
||||||
@ -1532,7 +1691,7 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "add a pod that doesn't match node affinity when NodeInclustionPolicy enabled",
|
name: "add a pod that doesn't match node affinity when NodeInclustionPolicy enabled",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").NodeAffinityNotIn("foo", []string{"bar"}).
|
preemptor: st.MakePod().Name("p").Label("foo", "").NodeAffinityNotIn("foo", []string{"bar"}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodeIdx: 0,
|
nodeIdx: 0,
|
||||||
addedPod: st.MakePod().Name("p-a1").Node("node-b").Label("foo", "").Label("zone", "zone2").Obj(),
|
addedPod: st.MakePod().Name("p-a1").Node("node-b").Label("foo", "").Label("zone", "zone2").Obj(),
|
||||||
@ -1612,7 +1771,7 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
|||||||
// So preemption is triggered.
|
// So preemption is triggered.
|
||||||
name: "one spreadConstraint on zone, topologyKeyToMinPodsMap unchanged",
|
name: "one spreadConstraint on zone, topologyKeyToMinPodsMap unchanged",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1640,7 +1799,7 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "one spreadConstraint on node, topologyKeyToMinPodsMap changed",
|
name: "one spreadConstraint on node, topologyKeyToMinPodsMap changed",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1670,7 +1829,7 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "delete an irrelevant pod won't help",
|
name: "delete an irrelevant pod won't help",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1701,7 +1860,7 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "delete a non-existing pod won't help",
|
name: "delete a non-existing pod won't help",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1732,8 +1891,8 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "two spreadConstraints",
|
name: "two spreadConstraints",
|
||||||
preemptor: st.MakePod().Name("p").Label("foo", "").
|
preemptor: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1811,7 +1970,7 @@ func BenchmarkFilter(b *testing.B) {
|
|||||||
{
|
{
|
||||||
name: "1000nodes/single-constraint-zone",
|
name: "1000nodes/single-constraint-zone",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelTopologyZone, v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelTopologyZone, v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPodsNum: 10000,
|
existingPodsNum: 10000,
|
||||||
allNodesNum: 1000,
|
allNodesNum: 1000,
|
||||||
@ -1820,7 +1979,7 @@ func BenchmarkFilter(b *testing.B) {
|
|||||||
{
|
{
|
||||||
name: "1000nodes/single-constraint-node",
|
name: "1000nodes/single-constraint-node",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPodsNum: 10000,
|
existingPodsNum: 10000,
|
||||||
allNodesNum: 1000,
|
allNodesNum: 1000,
|
||||||
@ -1829,8 +1988,8 @@ func BenchmarkFilter(b *testing.B) {
|
|||||||
{
|
{
|
||||||
name: "1000nodes/two-Constraints-zone-node",
|
name: "1000nodes/two-Constraints-zone-node",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, v1.LabelTopologyZone, v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelTopologyZone, v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPodsNum: 10000,
|
existingPodsNum: 10000,
|
||||||
allNodesNum: 1000,
|
allNodesNum: 1000,
|
||||||
@ -1887,7 +2046,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "no existing pods",
|
name: "no existing pods",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1905,7 +2064,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "no existing pods, incoming pod doesn't match itself",
|
name: "no existing pods, incoming pod doesn't match itself",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1923,7 +2082,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "existing pods in a different namespace do not count",
|
name: "existing pods in a different namespace do not count",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1947,7 +2106,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "pods spread across zones as 3/3, all nodes fit",
|
name: "pods spread across zones as 3/3, all nodes fit",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1975,7 +2134,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
// can cause unexpected behavior
|
// can cause unexpected behavior
|
||||||
name: "pods spread across zones as 1/2 due to absence of label 'zone' on node-b",
|
name: "pods spread across zones as 1/2 due to absence of label 'zone' on node-b",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -1999,7 +2158,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "pod cannot be scheduled as all nodes don't have label 'rack'",
|
name: "pod cannot be scheduled as all nodes don't have label 'rack'",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "rack", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "rack", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2013,7 +2172,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "pods spread across nodes as 2/1/0/3, only node-x fits",
|
name: "pods spread across nodes as 2/1/0/3, only node-x fits",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2039,7 +2198,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "pods spread across nodes as 2/1/0/3, maxSkew is 2, node-b and node-x fit",
|
name: "pods spread across nodes as 2/1/0/3, maxSkew is 2, node-b and node-x fit",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(2, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(2, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2069,7 +2228,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
// as the incoming pod doesn't have label "foo"
|
// as the incoming pod doesn't have label "foo"
|
||||||
name: "pods spread across nodes as 2/1/0/3, but pod doesn't match itself",
|
name: "pods spread across nodes as 2/1/0/3, but pod doesn't match itself",
|
||||||
pod: st.MakePod().Name("p").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("bar", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2101,7 +2260,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
name: "incoming pod has nodeAffinity, pods spread as 2/~1~/~0~/3, hence node-a fits",
|
name: "incoming pod has nodeAffinity, pods spread as 2/~1~/~0~/3, hence node-a fits",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityIn("node", []string{"node-a", "node-y"}).
|
NodeAffinityIn("node", []string{"node-a", "node-y"}).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2127,7 +2286,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "terminating Pods should be excluded",
|
name: "terminating Pods should be excluded",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
||||||
@ -2147,7 +2306,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
name: "incoming pod has nodeAffinity, pods spread as 0/~2~/0/1, hence node-a fits",
|
name: "incoming pod has nodeAffinity, pods spread as 0/~2~/0/1, hence node-a fits",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityNotIn("node", []string{"node-b"}).
|
NodeAffinityNotIn("node", []string{"node-b"}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2177,6 +2336,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
pointer.Int32(4), // larger than the number of domains(3)
|
pointer.Int32(4), // larger than the number of domains(3)
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
).Obj(),
|
).Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
||||||
@ -2207,6 +2367,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
pointer.Int32(2), // smaller than the number of domains(3)
|
pointer.Int32(2), // smaller than the number of domains(3)
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
).Obj(),
|
).Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
||||||
@ -2237,6 +2398,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
pointer.Int32(3), // larger than the number of domains(2)
|
pointer.Int32(3), // larger than the number of domains(2)
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
).Obj(),
|
).Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2267,6 +2429,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
pointer.Int32(1), // smaller than the number of domains(2)
|
pointer.Int32(1), // smaller than the number of domains(2)
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
).Obj(),
|
).Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2292,7 +2455,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy honored with labelSelectors",
|
name: "NodeAffinityPolicy honored with labelSelectors",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -2318,7 +2481,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy ignored with labelSelectors",
|
name: "NodeAffinityPolicy ignored with labelSelectors",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -2344,7 +2507,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy honored with nodeAffinity",
|
name: "NodeAffinityPolicy honored with nodeAffinity",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityIn("foo", []string{""}).
|
NodeAffinityIn("foo", []string{""}).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -2370,7 +2533,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy ignored with labelSelectors",
|
name: "NodeAffinityPolicy ignored with labelSelectors",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityIn("foo", []string{""}).
|
NodeAffinityIn("foo", []string{""}).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -2395,7 +2558,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
// pods spread across node as 1/1/0/~0~
|
// pods spread across node as 1/1/0/~0~
|
||||||
name: "NodeTaintsPolicy honored",
|
name: "NodeTaintsPolicy honored",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, &honorPolicy).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, &honorPolicy, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -2420,7 +2583,7 @@ func TestSingleConstraint(t *testing.T) {
|
|||||||
// pods spread across node as 1/1/0/~1~
|
// pods spread across node as 1/1/0/~1~
|
||||||
name: "NodeTaintsPolicy ignored",
|
name: "NodeTaintsPolicy ignored",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -2480,8 +2643,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
// intersection of (1) and (2) returns node-x
|
// intersection of (1) and (2) returns node-x
|
||||||
name: "two Constraints on zone and node, spreads = [3/3, 2/1/0/3]",
|
name: "two Constraints on zone and node, spreads = [3/3, 2/1/0/3]",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2510,8 +2673,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
// intersection of (1) and (2) returns no node
|
// intersection of (1) and (2) returns no node
|
||||||
name: "two Constraints on zone and node, spreads = [3/4, 2/1/0/4]",
|
name: "two Constraints on zone and node, spreads = [3/4, 2/1/0/4]",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2541,8 +2704,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
// intersection of (1) and (2) returns node-x
|
// intersection of (1) and (2) returns node-x
|
||||||
name: "Constraints hold different labelSelectors, spreads = [1/0, 1/0/0/1]",
|
name: "Constraints hold different labelSelectors, spreads = [1/0, 1/0/0/1]",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2567,8 +2730,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
// intersection of (1) and (2) returns no node
|
// intersection of (1) and (2) returns no node
|
||||||
name: "Constraints hold different labelSelectors, spreads = [1/0, 0/0/1/1]",
|
name: "Constraints hold different labelSelectors, spreads = [1/0, 0/0/1/1]",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2594,8 +2757,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
// intersection of (1) and (2) returns node-b
|
// intersection of (1) and (2) returns node-b
|
||||||
name: "Constraints hold different labelSelectors, spreads = [2/3, 1/0/0/1]",
|
name: "Constraints hold different labelSelectors, spreads = [2/3, 1/0/0/1]",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2623,8 +2786,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
// intersection of (1) and (2) returns node-a and node-b
|
// intersection of (1) and (2) returns node-a and node-b
|
||||||
name: "Constraints hold different labelSelectors but pod doesn't match itself on 'zone' constraint",
|
name: "Constraints hold different labelSelectors but pod doesn't match itself on 'zone' constraint",
|
||||||
pod: st.MakePod().Name("p").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2650,8 +2813,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
// intersection of (1) and (2) returns node-b
|
// intersection of (1) and (2) returns node-b
|
||||||
name: "two Constraints on zone and node, absence of label 'node' on node-x, spreads = [1/1, 1/0/0/1]",
|
name: "two Constraints on zone and node, absence of label 'node' on node-x, spreads = [1/1, 1/0/0/1]",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
@ -2677,8 +2840,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
name: "two node inclusion Constraints, zone: honor/ignore, node: ignore/ignore",
|
name: "two node inclusion Constraints, zone: honor/ignore, node: ignore/ignore",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -2705,8 +2868,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
// intersection of (1) and (2) returns node-x
|
// intersection of (1) and (2) returns node-x
|
||||||
name: "two node inclusion Constraints, zone: honor/honor, node: honor/ignore",
|
name: "two node inclusion Constraints, zone: honor/honor, node: honor/ignore",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, &honorPolicy).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, &honorPolicy, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -2734,8 +2897,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
name: "two node inclusion Constraints, zone: honor/ignore, node: honor/ignore",
|
name: "two node inclusion Constraints, zone: honor/ignore, node: honor/ignore",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -2763,8 +2926,8 @@ func TestMultipleConstraints(t *testing.T) {
|
|||||||
name: "two node inclusion Constraints, zone: honor/honor, node: ignore/ignore",
|
name: "two node inclusion Constraints, zone: honor/honor, node: ignore/ignore",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, &honorPolicy).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, fooSelector, nil, nil, &honorPolicy, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, fooSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
|
@ -64,6 +64,7 @@ type PodTopologySpread struct {
|
|||||||
statefulSets appslisters.StatefulSetLister
|
statefulSets appslisters.StatefulSetLister
|
||||||
enableMinDomainsInPodTopologySpread bool
|
enableMinDomainsInPodTopologySpread bool
|
||||||
enableNodeInclusionPolicyInPodTopologySpread bool
|
enableNodeInclusionPolicyInPodTopologySpread bool
|
||||||
|
enableMatchLabelKeysInPodTopologySpread bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ framework.PreFilterPlugin = &PodTopologySpread{}
|
var _ framework.PreFilterPlugin = &PodTopologySpread{}
|
||||||
@ -98,6 +99,7 @@ func New(plArgs runtime.Object, h framework.Handle, fts feature.Features) (frame
|
|||||||
defaultConstraints: args.DefaultConstraints,
|
defaultConstraints: args.DefaultConstraints,
|
||||||
enableMinDomainsInPodTopologySpread: fts.EnableMinDomainsInPodTopologySpread,
|
enableMinDomainsInPodTopologySpread: fts.EnableMinDomainsInPodTopologySpread,
|
||||||
enableNodeInclusionPolicyInPodTopologySpread: fts.EnableNodeInclusionPolicyInPodTopologySpread,
|
enableNodeInclusionPolicyInPodTopologySpread: fts.EnableNodeInclusionPolicyInPodTopologySpread,
|
||||||
|
enableMatchLabelKeysInPodTopologySpread: fts.EnableMatchLabelKeysInPodTopologySpread,
|
||||||
}
|
}
|
||||||
if args.DefaultingType == config.SystemDefaulting {
|
if args.DefaultingType == config.SystemDefaulting {
|
||||||
pl.defaultConstraints = systemDefaultConstraints
|
pl.defaultConstraints = systemDefaultConstraints
|
||||||
|
@ -59,11 +59,10 @@ func (s *preScoreState) Clone() framework.StateData {
|
|||||||
func (pl *PodTopologySpread) initPreScoreState(s *preScoreState, pod *v1.Pod, filteredNodes []*v1.Node, requireAllTopologies bool) error {
|
func (pl *PodTopologySpread) initPreScoreState(s *preScoreState, pod *v1.Pod, filteredNodes []*v1.Node, requireAllTopologies bool) error {
|
||||||
var err error
|
var err error
|
||||||
if len(pod.Spec.TopologySpreadConstraints) > 0 {
|
if len(pod.Spec.TopologySpreadConstraints) > 0 {
|
||||||
s.Constraints, err = filterTopologySpreadConstraints(
|
s.Constraints, err = pl.filterTopologySpreadConstraints(
|
||||||
pod.Spec.TopologySpreadConstraints,
|
pod.Spec.TopologySpreadConstraints,
|
||||||
|
pod.Labels,
|
||||||
v1.ScheduleAnyway,
|
v1.ScheduleAnyway,
|
||||||
pl.enableMinDomainsInPodTopologySpread,
|
|
||||||
pl.enableNodeInclusionPolicyInPodTopologySpread,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("obtaining pod's soft topology spread constraints: %w", err)
|
return fmt.Errorf("obtaining pod's soft topology spread constraints: %w", err)
|
||||||
|
@ -55,8 +55,8 @@ func TestPreScoreStateEmptyNodes(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "normal case",
|
name: "normal case",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label(v1.LabelHostname, "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
@ -96,8 +96,8 @@ func TestPreScoreStateEmptyNodes(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "node-x doesn't have label zone",
|
name: "node-x doesn't have label zone",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label(v1.LabelHostname, "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
@ -253,8 +253,8 @@ func TestPreScoreStateEmptyNodes(t *testing.T) {
|
|||||||
name: "default constraints and a replicaset, but pod has constraints",
|
name: "default constraints and a replicaset, but pod has constraints",
|
||||||
pod: st.MakePod().Name("p").Namespace("default").Label("foo", "bar").Label("baz", "sup").
|
pod: st.MakePod().Name("p").Namespace("default").Label("foo", "bar").Label("baz", "sup").
|
||||||
OwnerReference("rs1", appsv1.SchemeGroupVersion.WithKind("ReplicaSet")).
|
OwnerReference("rs1", appsv1.SchemeGroupVersion.WithKind("ReplicaSet")).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, barSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(2, "planet", v1.ScheduleAnyway, st.MakeLabelSelector().Label("baz", "sup").Obj(), nil, nil, nil).
|
SpreadConstraint(2, "planet", v1.ScheduleAnyway, st.MakeLabelSelector().Label("baz", "sup").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
config: config.PodTopologySpreadArgs{
|
config: config.PodTopologySpreadArgs{
|
||||||
DefaultConstraints: []v1.TopologySpreadConstraint{
|
DefaultConstraints: []v1.TopologySpreadConstraint{
|
||||||
@ -294,7 +294,7 @@ func TestPreScoreStateEmptyNodes(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy honored with labelSelectors",
|
name: "NodeAffinityPolicy honored with labelSelectors",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
@ -328,7 +328,7 @@ func TestPreScoreStateEmptyNodes(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy ignored with labelSelectors",
|
name: "NodeAffinityPolicy ignored with labelSelectors",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
@ -362,7 +362,7 @@ func TestPreScoreStateEmptyNodes(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy honored with nodeAffinity",
|
name: "NodeAffinityPolicy honored with nodeAffinity",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityIn("foo", []string{""}).
|
NodeAffinityIn("foo", []string{""}).
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
@ -396,7 +396,7 @@ func TestPreScoreStateEmptyNodes(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy ignored with nodeAffinity",
|
name: "NodeAffinityPolicy ignored with nodeAffinity",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityIn("foo", []string{""}).
|
NodeAffinityIn("foo", []string{""}).
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
@ -429,7 +429,7 @@ func TestPreScoreStateEmptyNodes(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "NodeTaintsPolicy honored",
|
name: "NodeTaintsPolicy honored",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, nil, &honorPolicy).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, nil, &honorPolicy, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
@ -462,7 +462,7 @@ func TestPreScoreStateEmptyNodes(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "NodeTaintsPolicy ignored",
|
name: "NodeTaintsPolicy ignored",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("foo", "").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
@ -537,6 +537,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
objs []runtime.Object
|
objs []runtime.Object
|
||||||
want framework.NodeScoreList
|
want framework.NodeScoreList
|
||||||
enableNodeInclustionPolicy bool
|
enableNodeInclustionPolicy bool
|
||||||
|
enableMatchLabelKeys bool
|
||||||
}{
|
}{
|
||||||
// Explanation on the Legend:
|
// Explanation on the Legend:
|
||||||
// a) X/Y means there are X matching pods on node1 and Y on node2, both nodes are candidates
|
// a) X/Y means there are X matching pods on node1 and Y on node2, both nodes are candidates
|
||||||
@ -547,7 +548,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "one constraint on node, no existing pods",
|
name: "one constraint on node, no existing pods",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label(v1.LabelHostname, "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
@ -562,7 +563,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
// if there is only one candidate node, it should be scored to 100
|
// if there is only one candidate node, it should be scored to 100
|
||||||
name: "one constraint on node, only one node is candidate",
|
name: "one constraint on node, only one node is candidate",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
@ -582,7 +583,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "one constraint on node, all nodes have the same number of matching pods",
|
name: "one constraint on node, all nodes have the same number of matching pods",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
@ -601,7 +602,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
// matching pods spread as 2/1/0/3.
|
// matching pods spread as 2/1/0/3.
|
||||||
name: "one constraint on node, all 4 nodes are candidates",
|
name: "one constraint on node, all 4 nodes are candidates",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
@ -628,7 +629,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "one constraint on node, all 4 nodes are candidates, maxSkew=2",
|
name: "one constraint on node, all 4 nodes are candidates, maxSkew=2",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(2, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(2, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
// matching pods spread as 2/1/0/3.
|
// matching pods spread as 2/1/0/3.
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
@ -656,7 +657,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "one constraint on node, all 4 nodes are candidates, maxSkew=3",
|
name: "one constraint on node, all 4 nodes are candidates, maxSkew=3",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(3, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(3, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
// matching pods spread as 4/3/2/1.
|
// matching pods spread as 4/3/2/1.
|
||||||
@ -723,7 +724,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
// matching pods spread as 4/2/1/~3~ (node4 is not a candidate)
|
// matching pods spread as 4/2/1/~3~ (node4 is not a candidate)
|
||||||
name: "one constraint on node, 3 out of 4 nodes are candidates",
|
name: "one constraint on node, 3 out of 4 nodes are candidates",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
@ -755,7 +756,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
// matching pods spread as 4/?2?/1/~3~, total = 4+?+1 = 5 (as node2 is problematic)
|
// matching pods spread as 4/?2?/1/~3~, total = 4+?+1 = 5 (as node2 is problematic)
|
||||||
name: "one constraint on node, 3 out of 4 nodes are candidates, one node doesn't match topology key",
|
name: "one constraint on node, 3 out of 4 nodes are candidates, one node doesn't match topology key",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
@ -787,7 +788,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
// matching pods spread as 4/2/1/~3~
|
// matching pods spread as 4/2/1/~3~
|
||||||
name: "one constraint on zone, 3 out of 4 nodes are candidates",
|
name: "one constraint on zone, 3 out of 4 nodes are candidates",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
@ -819,8 +820,8 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
// matching pods spread as 2/~1~/2/~4~.
|
// matching pods spread as 2/~1~/2/~4~.
|
||||||
name: "two Constraints on zone and node, 2 out of 4 nodes are candidates",
|
name: "two Constraints on zone and node, 2 out of 4 nodes are candidates",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
@ -859,8 +860,8 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
// For the second constraint (node): the matching pods spread as 0/1/0/1
|
// For the second constraint (node): the matching pods spread as 0/1/0/1
|
||||||
name: "two Constraints on zone and node, with different labelSelectors",
|
name: "two Constraints on zone and node, with different labelSelectors",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
@ -887,8 +888,8 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
// For the second constraint (node): the matching pods spread as 0/1/0/1
|
// For the second constraint (node): the matching pods spread as 0/1/0/1
|
||||||
name: "two Constraints on zone and node, with different labelSelectors, some nodes have 0 pods",
|
name: "two Constraints on zone and node, with different labelSelectors, some nodes have 0 pods",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-b1").Node("node-b").Label("bar", "").Obj(),
|
st.MakePod().Name("p-b1").Node("node-b").Label("bar", "").Obj(),
|
||||||
@ -914,8 +915,8 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
// For the second constraint (node): the matching pods spread as 0/1/0/~1~
|
// For the second constraint (node): the matching pods spread as 0/1/0/~1~
|
||||||
name: "two Constraints on zone and node, with different labelSelectors, 3 out of 4 nodes are candidates",
|
name: "two Constraints on zone and node, with different labelSelectors, 3 out of 4 nodes are candidates",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
@ -940,7 +941,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "existing pods in a different namespace do not count",
|
name: "existing pods in a different namespace do not count",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p-a1").Namespace("ns1").Node("node-a").Label("foo", "").Obj(),
|
st.MakePod().Name("p-a1").Namespace("ns1").Node("node-a").Label("foo", "").Obj(),
|
||||||
@ -960,7 +961,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "terminating Pods should be excluded",
|
name: "terminating Pods should be excluded",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label(v1.LabelHostname, "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
@ -987,6 +988,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
pointer.Int32(10), // larger than the number of domains(3)
|
pointer.Int32(10), // larger than the number of domains(3)
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
).Obj(),
|
).Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
||||||
@ -1010,7 +1012,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy honoed with labelSelectors",
|
name: "NodeAffinityPolicy honoed with labelSelectors",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -1034,7 +1036,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy ignored with labelSelectors",
|
name: "NodeAffinityPolicy ignored with labelSelectors",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -1058,7 +1060,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy honoed with nodeAffinity",
|
name: "NodeAffinityPolicy honoed with nodeAffinity",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityIn("foo", []string{""}).
|
NodeAffinityIn("foo", []string{""}).
|
||||||
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -1082,7 +1084,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy ignored with nodeAffinity",
|
name: "NodeAffinityPolicy ignored with nodeAffinity",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
NodeAffinityIn("foo", []string{""}).
|
NodeAffinityIn("foo", []string{""}).
|
||||||
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Label("foo", "").Obj(),
|
||||||
@ -1105,7 +1107,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "NodeTaintsPolicy honored",
|
name: "NodeTaintsPolicy honored",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, nil, &honorPolicy).
|
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, nil, &honorPolicy, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
||||||
@ -1128,7 +1130,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "NodeTaintsPolicy ignored",
|
name: "NodeTaintsPolicy ignored",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, "node", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
st.MakeNode().Name("node-a").Label("node", "node-a").Obj(),
|
||||||
@ -1148,6 +1150,85 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
},
|
},
|
||||||
enableNodeInclustionPolicy: true,
|
enableNodeInclustionPolicy: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ignored when feature gate disabled",
|
||||||
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").Label("baz", "").
|
||||||
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil, []string{"baz"}).
|
||||||
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil, []string{"baz"}).
|
||||||
|
Obj(),
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Label("bar", "").Obj(),
|
||||||
|
st.MakePod().Name("p-y1").Node("node-c").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-y2").Node("node-c").Label("bar", "").Obj(),
|
||||||
|
},
|
||||||
|
nodes: []*v1.Node{
|
||||||
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label(v1.LabelHostname, "node-b").Obj(),
|
||||||
|
st.MakeNode().Name("node-c").Label("zone", "zone2").Label(v1.LabelHostname, "node-c").Obj(),
|
||||||
|
st.MakeNode().Name("node-d").Label("zone", "zone2").Label(v1.LabelHostname, "node-d").Obj(),
|
||||||
|
},
|
||||||
|
want: []framework.NodeScore{
|
||||||
|
{Name: "node-a", Score: 60},
|
||||||
|
{Name: "node-b", Score: 20},
|
||||||
|
{Name: "node-c", Score: 60},
|
||||||
|
{Name: "node-d", Score: 100},
|
||||||
|
},
|
||||||
|
enableMatchLabelKeys: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ANDed with LabelSelector when LabelSelector is empty",
|
||||||
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, st.MakeLabelSelector().Obj(), nil, nil, nil, []string{"foo"}).
|
||||||
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, st.MakeLabelSelector().Obj(), nil, nil, nil, []string{"bar"}).
|
||||||
|
Obj(),
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Label("bar", "").Obj(),
|
||||||
|
st.MakePod().Name("p-y1").Node("node-c").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-y2").Node("node-c").Label("bar", "").Obj(),
|
||||||
|
},
|
||||||
|
nodes: []*v1.Node{
|
||||||
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label(v1.LabelHostname, "node-b").Obj(),
|
||||||
|
st.MakeNode().Name("node-c").Label("zone", "zone2").Label(v1.LabelHostname, "node-c").Obj(),
|
||||||
|
st.MakeNode().Name("node-d").Label("zone", "zone2").Label(v1.LabelHostname, "node-d").Obj(),
|
||||||
|
},
|
||||||
|
want: []framework.NodeScore{
|
||||||
|
{Name: "node-a", Score: 60},
|
||||||
|
{Name: "node-b", Score: 20},
|
||||||
|
{Name: "node-c", Score: 60},
|
||||||
|
{Name: "node-d", Score: 100},
|
||||||
|
},
|
||||||
|
enableMatchLabelKeys: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ANDed with LabelSelector when LabelSelector isn't empty",
|
||||||
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").Label("baz", "").
|
||||||
|
SpreadConstraint(1, "zone", v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil, []string{"baz"}).
|
||||||
|
Obj(),
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Label("bar", "").Label("baz", "").Obj(),
|
||||||
|
st.MakePod().Name("p-c1").Node("node-c").Label("foo", "").Obj(),
|
||||||
|
st.MakePod().Name("p-c2").Node("node-c").Label("bar", "").Obj(),
|
||||||
|
st.MakePod().Name("p-d3").Node("node-c").Label("bar", "").Label("baz", "").Obj(),
|
||||||
|
},
|
||||||
|
nodes: []*v1.Node{
|
||||||
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label(v1.LabelHostname, "node-a").Obj(),
|
||||||
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label(v1.LabelHostname, "node-b").Obj(),
|
||||||
|
st.MakeNode().Name("node-c").Label("zone", "zone2").Label(v1.LabelHostname, "node-c").Obj(),
|
||||||
|
st.MakeNode().Name("node-d").Label("zone", "zone2").Label(v1.LabelHostname, "node-d").Obj(),
|
||||||
|
},
|
||||||
|
want: []framework.NodeScore{
|
||||||
|
{Name: "node-a", Score: 60},
|
||||||
|
{Name: "node-b", Score: 20},
|
||||||
|
{Name: "node-c", Score: 60},
|
||||||
|
{Name: "node-d", Score: 100},
|
||||||
|
},
|
||||||
|
enableMatchLabelKeys: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@ -1159,6 +1240,7 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
|||||||
pl := plugintesting.SetupPluginWithInformers(ctx, t, podTopologySpreadFunc, &config.PodTopologySpreadArgs{DefaultingType: config.SystemDefaulting}, cache.NewSnapshot(tt.existingPods, allNodes), tt.objs)
|
pl := plugintesting.SetupPluginWithInformers(ctx, t, podTopologySpreadFunc, &config.PodTopologySpreadArgs{DefaultingType: config.SystemDefaulting}, cache.NewSnapshot(tt.existingPods, allNodes), tt.objs)
|
||||||
p := pl.(*PodTopologySpread)
|
p := pl.(*PodTopologySpread)
|
||||||
p.enableNodeInclusionPolicyInPodTopologySpread = tt.enableNodeInclustionPolicy
|
p.enableNodeInclusionPolicyInPodTopologySpread = tt.enableNodeInclustionPolicy
|
||||||
|
p.enableMatchLabelKeysInPodTopologySpread = tt.enableMatchLabelKeys
|
||||||
|
|
||||||
status := p.PreScore(context.Background(), state, tt.pod, tt.nodes)
|
status := p.PreScore(context.Background(), state, tt.pod, tt.nodes)
|
||||||
if !status.IsSuccess() {
|
if !status.IsSuccess() {
|
||||||
@ -1199,7 +1281,7 @@ func BenchmarkTestPodTopologySpreadScore(b *testing.B) {
|
|||||||
{
|
{
|
||||||
name: "1000nodes/single-constraint-zone",
|
name: "1000nodes/single-constraint-zone",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelTopologyZone, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelTopologyZone, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPodsNum: 10000,
|
existingPodsNum: 10000,
|
||||||
allNodesNum: 1000,
|
allNodesNum: 1000,
|
||||||
@ -1208,7 +1290,7 @@ func BenchmarkTestPodTopologySpreadScore(b *testing.B) {
|
|||||||
{
|
{
|
||||||
name: "1000nodes/single-constraint-node",
|
name: "1000nodes/single-constraint-node",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPodsNum: 10000,
|
existingPodsNum: 10000,
|
||||||
allNodesNum: 1000,
|
allNodesNum: 1000,
|
||||||
@ -1217,8 +1299,8 @@ func BenchmarkTestPodTopologySpreadScore(b *testing.B) {
|
|||||||
{
|
{
|
||||||
name: "1000nodes/two-Constraints-zone-node",
|
name: "1000nodes/two-Constraints-zone-node",
|
||||||
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
SpreadConstraint(1, v1.LabelTopologyZone, v1.ScheduleAnyway, fooSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelTopologyZone, v1.ScheduleAnyway, fooSelector, nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil).
|
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, barSelector, nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPodsNum: 10000,
|
existingPodsNum: 10000,
|
||||||
allNodesNum: 1000,
|
allNodesNum: 1000,
|
||||||
|
@ -49,6 +49,7 @@ func NewInTreeRegistry() runtime.Registry {
|
|||||||
EnableVolumeCapacityPriority: feature.DefaultFeatureGate.Enabled(features.VolumeCapacityPriority),
|
EnableVolumeCapacityPriority: feature.DefaultFeatureGate.Enabled(features.VolumeCapacityPriority),
|
||||||
EnableMinDomainsInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.MinDomainsInPodTopologySpread),
|
EnableMinDomainsInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.MinDomainsInPodTopologySpread),
|
||||||
EnableNodeInclusionPolicyInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.NodeInclusionPolicyInPodTopologySpread),
|
EnableNodeInclusionPolicyInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.NodeInclusionPolicyInPodTopologySpread),
|
||||||
|
EnableMatchLabelKeysInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.MatchLabelKeysInPodTopologySpread),
|
||||||
}
|
}
|
||||||
|
|
||||||
return runtime.Registry{
|
return runtime.Registry{
|
||||||
|
@ -1759,7 +1759,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
|
|||||||
Operator: metav1.LabelSelectorOpExists,
|
Operator: metav1.LabelSelectorOpExists,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, nil, nil, nil).Obj(),
|
}, nil, nil, nil, nil).Obj(),
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
st.MakePod().Name("pod1").UID("pod1").Label("foo", "").Node("node1").Phase(v1.PodRunning).Obj(),
|
st.MakePod().Name("pod1").UID("pod1").Label("foo", "").Node("node1").Phase(v1.PodRunning).Obj(),
|
||||||
},
|
},
|
||||||
@ -1786,7 +1786,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
|
|||||||
Operator: metav1.LabelSelectorOpExists,
|
Operator: metav1.LabelSelectorOpExists,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, nil, nil, nil).Obj(),
|
}, nil, nil, nil, nil).Obj(),
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
st.MakePod().Name("pod1a").UID("pod1a").Label("foo", "").Node("node1").Phase(v1.PodRunning).Obj(),
|
st.MakePod().Name("pod1a").UID("pod1a").Label("foo", "").Node("node1").Phase(v1.PodRunning).Obj(),
|
||||||
st.MakePod().Name("pod1b").UID("pod1b").Label("foo", "").Node("node1").Phase(v1.PodRunning).Obj(),
|
st.MakePod().Name("pod1b").UID("pod1b").Label("foo", "").Node("node1").Phase(v1.PodRunning).Obj(),
|
||||||
|
@ -547,7 +547,7 @@ func (p *PodWrapper) PodAntiAffinityNotIn(labelKey, topologyKey string, vals []s
|
|||||||
|
|
||||||
// SpreadConstraint constructs a TopologySpreadConstraint object and injects
|
// SpreadConstraint constructs a TopologySpreadConstraint object and injects
|
||||||
// into the inner pod.
|
// into the inner pod.
|
||||||
func (p *PodWrapper) SpreadConstraint(maxSkew int, tpKey string, mode v1.UnsatisfiableConstraintAction, selector *metav1.LabelSelector, minDomains *int32, nodeAffinityPolicy, nodeTaintsPolicy *v1.NodeInclusionPolicy) *PodWrapper {
|
func (p *PodWrapper) SpreadConstraint(maxSkew int, tpKey string, mode v1.UnsatisfiableConstraintAction, selector *metav1.LabelSelector, minDomains *int32, nodeAffinityPolicy, nodeTaintsPolicy *v1.NodeInclusionPolicy, matchLabelKeys []string) *PodWrapper {
|
||||||
c := v1.TopologySpreadConstraint{
|
c := v1.TopologySpreadConstraint{
|
||||||
MaxSkew: int32(maxSkew),
|
MaxSkew: int32(maxSkew),
|
||||||
TopologyKey: tpKey,
|
TopologyKey: tpKey,
|
||||||
@ -556,6 +556,7 @@ func (p *PodWrapper) SpreadConstraint(maxSkew int, tpKey string, mode v1.Unsatis
|
|||||||
MinDomains: minDomains,
|
MinDomains: minDomains,
|
||||||
NodeAffinityPolicy: nodeAffinityPolicy,
|
NodeAffinityPolicy: nodeAffinityPolicy,
|
||||||
NodeTaintsPolicy: nodeTaintsPolicy,
|
NodeTaintsPolicy: nodeTaintsPolicy,
|
||||||
|
MatchLabelKeys: matchLabelKeys,
|
||||||
}
|
}
|
||||||
p.Spec.TopologySpreadConstraints = append(p.Spec.TopologySpreadConstraints, c)
|
p.Spec.TopologySpreadConstraints = append(p.Spec.TopologySpreadConstraints, c)
|
||||||
return p
|
return p
|
||||||
|
@ -1076,12 +1076,13 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
candidateNodes []string // nodes expected to schedule onto
|
candidateNodes []string // nodes expected to schedule onto
|
||||||
enableMinDomains bool
|
enableMinDomains bool
|
||||||
enableNodeInclustionPolicy bool
|
enableNodeInclustionPolicy bool
|
||||||
|
enableMatchLabelKeys bool
|
||||||
}{
|
}{
|
||||||
// note: naming starts at index 0
|
// note: naming starts at index 0
|
||||||
{
|
{
|
||||||
name: "place pod on a 1/1/0/1 cluster with MaxSkew=1, node-2 is the only fit",
|
name: "place pod on a 1/1/0/1 cluster with MaxSkew=1, node-2 is the only fit",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p0").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p0").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1095,7 +1096,7 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "place pod on a 2/0/0/1 cluster with MaxSkew=2, node-{1,2,3} are good fits",
|
name: "place pod on a 2/0/0/1 cluster with MaxSkew=2, node-{1,2,3} are good fits",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
SpreadConstraint(2, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(2, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p0a").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p0a").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1110,7 +1111,7 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
name: "pod is required to be placed on zone0, so only node-1 fits",
|
name: "pod is required to be placed on zone0, so only node-1 fits",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
NodeAffinityIn("zone", []string{"zone-0"}).
|
NodeAffinityIn("zone", []string{"zone-0"}).
|
||||||
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p0").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p0").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1123,8 +1124,8 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "two constraints: pod can only be placed to zone-1/node-2",
|
name: "two constraints: pod can only be placed to zone-1/node-2",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p0").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p0").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1140,8 +1141,8 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
name: "pod cannot be placed onto any node",
|
name: "pod cannot be placed onto any node",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
NodeAffinityNotIn("node", []string{"node-0"}). // mock a 3-node cluster
|
NodeAffinityNotIn("node", []string{"node-0"}). // mock a 3-node cluster
|
||||||
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1157,8 +1158,8 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
name: "high priority pod can preempt others",
|
name: "high priority pod can preempt others",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).Priority(100).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).Priority(100).
|
||||||
NodeAffinityNotIn("node", []string{"node-0"}). // mock a 3-node cluster
|
NodeAffinityNotIn("node", []string{"node-0"}). // mock a 3-node cluster
|
||||||
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().ZeroTerminationGracePeriod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().ZeroTerminationGracePeriod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1183,6 +1184,7 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
pointer.Int32(4), // larger than the number of domains (= 3)
|
pointer.Int32(4), // larger than the number of domains (= 3)
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
).
|
).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
@ -1209,6 +1211,7 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
pointer.Int32(2), // smaller than the number of domains (= 3)
|
pointer.Int32(2), // smaller than the number of domains (= 3)
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
).
|
).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
@ -1234,6 +1237,7 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
pointer.Int32(3), // larger than the number of domains(2)
|
pointer.Int32(3), // larger than the number of domains(2)
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
).Obj(),
|
).Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1256,6 +1260,7 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
pointer.Int32(1), // smaller than the number of domains(2)
|
pointer.Int32(1), // smaller than the number of domains(2)
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
).Obj(),
|
).Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1271,7 +1276,7 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy honored with labelSelectors, pods spread across zone as 2/1",
|
name: "NodeAffinityPolicy honored with labelSelectors, pods spread across zone as 2/1",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1293,7 +1298,7 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
name: "NodeAffinityPolicy ignored with nodeAffinity, pods spread across zone as 1/~2~",
|
name: "NodeAffinityPolicy ignored with nodeAffinity, pods spread across zone as 1/~2~",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
NodeAffinityIn("foo", []string{""}).
|
NodeAffinityIn("foo", []string{""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, &ignorePolicy, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1313,7 +1318,7 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "NodeTaintsPolicy honored, pods spread across zone as 2/1",
|
name: "NodeTaintsPolicy honored, pods spread across zone as 2/1",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, &honorPolicy).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, &honorPolicy, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1334,7 +1339,7 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "NodeTaintsPolicy ignored, pods spread across zone as 2/2",
|
name: "NodeTaintsPolicy ignored, pods spread across zone as 2/2",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1359,8 +1364,8 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
name: "two node inclusion Constraints, zone: honor/ignore, node: honor/ignore",
|
name: "two node inclusion Constraints, zone: honor/ignore, node: honor/ignore",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1385,8 +1390,8 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
name: "feature gate disabled, two node inclusion Constraints, zone: honor/ignore, node: honor/ignore",
|
name: "feature gate disabled, two node inclusion Constraints, zone: honor/ignore, node: honor/ignore",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1411,8 +1416,8 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
name: "two node inclusion Constraints, zone: ignore/ignore, node: honor/honor",
|
name: "two node inclusion Constraints, zone: ignore/ignore, node: honor/honor",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, &ignorePolicy, nil, nil).
|
||||||
SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, &honorPolicy).
|
SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, &honorPolicy, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -1430,11 +1435,57 @@ func TestPodTopologySpreadFilter(t *testing.T) {
|
|||||||
candidateNodes: []string{"node-1", "node-4"},
|
candidateNodes: []string{"node-1", "node-4"},
|
||||||
enableNodeInclustionPolicy: true,
|
enableNodeInclustionPolicy: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ignored when feature gate disabled, pods spread across zone as 2/1",
|
||||||
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").Container(pause).
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, []string{"bar"}).
|
||||||
|
Obj(),
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p1a").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p2a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3a").Node("node-2").Label("foo", "").Label("bar", "").Container(pause).Obj(),
|
||||||
|
},
|
||||||
|
fits: true,
|
||||||
|
nodes: defaultNodes,
|
||||||
|
candidateNodes: []string{"node-2", "node-3"},
|
||||||
|
enableMatchLabelKeys: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ANDed with LabelSelector when LabelSelector isn't empty, pods spread across zone as 0/1",
|
||||||
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").Container(pause).
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, []string{"bar"}).
|
||||||
|
Obj(),
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p1a").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p2a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3a").Node("node-2").Label("foo", "").Label("bar", "").Container(pause).Obj(),
|
||||||
|
},
|
||||||
|
fits: true,
|
||||||
|
nodes: defaultNodes,
|
||||||
|
candidateNodes: []string{"node-0", "node-1"},
|
||||||
|
enableMatchLabelKeys: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ANDed with LabelSelector when LabelSelector is empty, pods spread across zone as 2/1",
|
||||||
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
|
SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Obj(), nil, nil, nil, []string{"foo"}).
|
||||||
|
Obj(),
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p1a").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p2a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3a").Node("node-2").Label("foo", "").Container(pause).Obj(),
|
||||||
|
},
|
||||||
|
fits: true,
|
||||||
|
nodes: defaultNodes,
|
||||||
|
candidateNodes: []string{"node-2", "node-3"},
|
||||||
|
enableMatchLabelKeys: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MinDomainsInPodTopologySpread, tt.enableMinDomains)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MinDomainsInPodTopologySpread, tt.enableMinDomains)()
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeInclusionPolicyInPodTopologySpread, tt.enableNodeInclustionPolicy)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeInclusionPolicyInPodTopologySpread, tt.enableNodeInclustionPolicy)()
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodTopologySpread, tt.enableMatchLabelKeys)()
|
||||||
|
|
||||||
testCtx := initTest(t, "pts-predicate")
|
testCtx := initTest(t, "pts-predicate")
|
||||||
cs := testCtx.ClientSet
|
cs := testCtx.ClientSet
|
||||||
|
@ -449,13 +449,14 @@ func TestPodTopologySpreadScoring(t *testing.T) {
|
|||||||
nodes []*v1.Node
|
nodes []*v1.Node
|
||||||
want []string // nodes expected to schedule onto
|
want []string // nodes expected to schedule onto
|
||||||
enableNodeInclustionPolicy bool
|
enableNodeInclustionPolicy bool
|
||||||
|
enableMatchLabelKeys bool
|
||||||
}{
|
}{
|
||||||
// note: naming starts at index 0
|
// note: naming starts at index 0
|
||||||
// the symbol ~X~ means that node is infeasible
|
// the symbol ~X~ means that node is infeasible
|
||||||
{
|
{
|
||||||
name: "place pod on a ~0~/1/2/3 cluster with MaxSkew=1, node-1 is the preferred fit",
|
name: "place pod on a ~0~/1/2/3 cluster with MaxSkew=1, node-1 is the preferred fit",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -472,8 +473,8 @@ func TestPodTopologySpreadScoring(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "combined with hardSpread constraint on a ~4~/0/1/2 cluster",
|
name: "combined with hardSpread constraint on a ~4~/0/1/2 cluster",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p0a").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p0a").Node("node-0").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -495,8 +496,8 @@ func TestPodTopologySpreadScoring(t *testing.T) {
|
|||||||
name: "soft constraint with two node inclusion Constraints, zone: honor/ignore, node: honor/ignore",
|
name: "soft constraint with two node inclusion Constraints, zone: honor/ignore, node: honor/ignore",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "zone", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil).
|
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -521,8 +522,8 @@ func TestPodTopologySpreadScoring(t *testing.T) {
|
|||||||
name: "soft constraint with two node inclusion Constraints, zone: ignore/ignore, node: honor/honor",
|
name: "soft constraint with two node inclusion Constraints, zone: ignore/ignore, node: honor/honor",
|
||||||
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
NodeSelector(map[string]string{"foo": ""}).
|
NodeSelector(map[string]string{"foo": ""}).
|
||||||
SpreadConstraint(1, "zone", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, &ignorePolicy, nil).
|
SpreadConstraint(1, "zone", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, &ignorePolicy, nil, nil).
|
||||||
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, &honorPolicy).
|
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, &honorPolicy, nil).
|
||||||
Obj(),
|
Obj(),
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
st.MakePod().Name("p1a").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
@ -540,10 +541,65 @@ func TestPodTopologySpreadScoring(t *testing.T) {
|
|||||||
want: []string{"node-3"},
|
want: []string{"node-3"},
|
||||||
enableNodeInclustionPolicy: true,
|
enableNodeInclustionPolicy: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ignored when feature gate disabled, node-1 is the preferred fit",
|
||||||
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").Container(pause).
|
||||||
|
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, []string{"bar"}).
|
||||||
|
Obj(),
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p1").Node("node-1").Label("foo", "").Label("bar", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p2a").Node("node-2").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p2b").Node("node-2").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3a").Node("node-3").Label("foo", "").Label("bar", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3b").Node("node-3").Label("foo", "").Label("bar", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3c").Node("node-3").Label("foo", "").Container(pause).Obj(),
|
||||||
|
},
|
||||||
|
fits: true,
|
||||||
|
nodes: defaultNodes,
|
||||||
|
want: []string{"node-1"},
|
||||||
|
enableMatchLabelKeys: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ANDed with LabelSelector when LabelSelector isn't empty, node-2 is the preferred fit",
|
||||||
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").Container(pause).
|
||||||
|
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Exists("foo").Obj(), nil, nil, nil, []string{"bar"}).
|
||||||
|
Obj(),
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p1").Node("node-1").Label("foo", "").Label("bar", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p2a").Node("node-2").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p2b").Node("node-2").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3a").Node("node-3").Label("foo", "").Label("bar", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3b").Node("node-3").Label("foo", "").Label("bar", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3c").Node("node-3").Label("foo", "").Container(pause).Obj(),
|
||||||
|
},
|
||||||
|
fits: true,
|
||||||
|
nodes: defaultNodes,
|
||||||
|
want: []string{"node-2"},
|
||||||
|
enableMatchLabelKeys: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matchLabelKeys ANDed with LabelSelector when LabelSelector is empty, node-1 is the preferred fit",
|
||||||
|
incomingPod: st.MakePod().Name("p").Label("foo", "").Container(pause).
|
||||||
|
SpreadConstraint(1, "node", softSpread, st.MakeLabelSelector().Obj(), nil, nil, nil, []string{"foo"}).
|
||||||
|
Obj(),
|
||||||
|
existingPods: []*v1.Pod{
|
||||||
|
st.MakePod().Name("p1").Node("node-1").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p2a").Node("node-2").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p2b").Node("node-2").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3a").Node("node-3").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3b").Node("node-3").Label("foo", "").Container(pause).Obj(),
|
||||||
|
st.MakePod().Name("p3c").Node("node-3").Label("foo", "").Container(pause).Obj(),
|
||||||
|
},
|
||||||
|
fits: true,
|
||||||
|
nodes: defaultNodes,
|
||||||
|
want: []string{"node-1"},
|
||||||
|
enableMatchLabelKeys: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeInclusionPolicyInPodTopologySpread, tt.enableNodeInclustionPolicy)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeInclusionPolicyInPodTopologySpread, tt.enableNodeInclustionPolicy)()
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodTopologySpread, tt.enableMatchLabelKeys)()
|
||||||
|
|
||||||
testCtx := initTestSchedulerForPriorityTest(t, podtopologyspread.Name)
|
testCtx := initTestSchedulerForPriorityTest(t, podtopologyspread.Name)
|
||||||
defer testutils.CleanupTest(t, testCtx)
|
defer testutils.CleanupTest(t, testCtx)
|
||||||
|
Loading…
Reference in New Issue
Block a user