mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Optimize topology spreading for null selector
Change-Id: I28f031a040b143fa9452b4400cc3ae85d58e572c
This commit is contained in:
parent
1cb334960c
commit
3dae9ba6d6
@ -145,6 +145,9 @@ func mergeLabelSetWithSelector(matchLabels labels.Set, s labels.Selector) labels
|
||||
}
|
||||
|
||||
func countPodsMatchSelector(podInfos []*framework.PodInfo, selector labels.Selector, ns string) int {
|
||||
if selector.Empty() {
|
||||
return 0
|
||||
}
|
||||
count := 0
|
||||
for _, p := range podInfos {
|
||||
// Bypass terminating Pod (see #87621).
|
||||
|
@ -149,6 +149,44 @@ func TestPreFilterState(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "normal case with null label selector",
|
||||
pod: st.MakePod().Name("p").Label("foo", "").
|
||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, nil, nil, nil, nil, nil).
|
||||
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: labels.Nothing(),
|
||||
MinDomains: 1,
|
||||
NodeAffinityPolicy: v1.NodeInclusionPolicyHonor,
|
||||
NodeTaintsPolicy: v1.NodeInclusionPolicyIgnore,
|
||||
},
|
||||
},
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"zone": {{"zone2", 0}, {"zone1", 0}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int{
|
||||
{key: "zone", value: "zone1"}: 0,
|
||||
{key: "zone", value: "zone2"}: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "normal case with one spreadConstraint, on a 3-zone cluster",
|
||||
pod: st.MakePod().Name("p").Label("foo", "").
|
||||
@ -2347,6 +2385,28 @@ func TestSingleConstraint(t *testing.T) {
|
||||
"node-y": framework.Unschedulable,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "existing pods do not match null selector",
|
||||
pod: st.MakePod().Name("p").Label("foo", "").
|
||||
SpreadConstraint(1, "zone", v1.DoNotSchedule, nil, nil, nil, nil, nil).
|
||||
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-x1").Node("node-x").Label("foo", "").Obj(),
|
||||
st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(),
|
||||
},
|
||||
wantStatusCode: map[string]framework.Code{
|
||||
"node-a": framework.Success,
|
||||
"node-b": framework.Success,
|
||||
"node-x": framework.Success,
|
||||
"node-y": framework.Success,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "pods spread across zones as 3/3, all nodes fit",
|
||||
pod: st.MakePod().Name("p").Label("foo", "").
|
||||
|
@ -18,13 +18,13 @@ package podtopologyspread
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/informers"
|
||||
@ -92,6 +92,38 @@ func TestPreScoreStateEmptyNodes(t *testing.T) {
|
||||
TopologyNormalizingWeight: []float64{topologyNormalizingWeight(2), topologyNormalizingWeight(3)},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "null selector",
|
||||
pod: st.MakePod().Name("p").Label("foo", "").
|
||||
SpreadConstraint(1, "zone", v1.ScheduleAnyway, nil, nil, nil, nil, nil).
|
||||
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-x").Label("zone", "zone2").Label(v1.LabelHostname, "node-x").Obj(),
|
||||
},
|
||||
config: config.PodTopologySpreadArgs{
|
||||
DefaultingType: config.ListDefaulting,
|
||||
},
|
||||
want: &preScoreState{
|
||||
Constraints: []topologySpreadConstraint{
|
||||
{
|
||||
MaxSkew: 1,
|
||||
TopologyKey: "zone",
|
||||
Selector: labels.Nothing(),
|
||||
MinDomains: 1,
|
||||
NodeAffinityPolicy: v1.NodeInclusionPolicyHonor,
|
||||
NodeTaintsPolicy: v1.NodeInclusionPolicyIgnore,
|
||||
},
|
||||
},
|
||||
IgnoredNodes: sets.NewString(),
|
||||
TopologyPairToPodCounts: map[topologyPair]*int64{
|
||||
{key: "zone", value: "zone1"}: pointer.Int64(0),
|
||||
{key: "zone", value: "zone2"}: pointer.Int64(0),
|
||||
},
|
||||
TopologyNormalizingWeight: []float64{topologyNormalizingWeight(2)},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "node-x doesn't have label zone",
|
||||
pod: st.MakePod().Name("p").Label("foo", "").
|
||||
@ -625,6 +657,32 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
||||
{Name: "node-d", Score: 0},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "one constraint on node, null selector",
|
||||
pod: st.MakePod().Name("p").Label("foo", "").
|
||||
SpreadConstraint(1, v1.LabelHostname, v1.ScheduleAnyway, nil, nil, nil, nil, nil).
|
||||
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-d1").Node("node-d").Label("foo", "").Obj(),
|
||||
st.MakePod().Name("p-d2").Node("node-d").Label("foo", "").Obj(),
|
||||
st.MakePod().Name("p-d3").Node("node-d").Label("foo", "").Obj(),
|
||||
},
|
||||
nodes: []*v1.Node{
|
||||
st.MakeNode().Name("node-a").Label(v1.LabelHostname, "node-a").Obj(),
|
||||
st.MakeNode().Name("node-b").Label(v1.LabelHostname, "node-b").Obj(),
|
||||
st.MakeNode().Name("node-c").Label(v1.LabelHostname, "node-c").Obj(),
|
||||
st.MakeNode().Name("node-d").Label(v1.LabelHostname, "node-d").Obj(),
|
||||
},
|
||||
want: []framework.NodeScore{
|
||||
{Name: "node-a", Score: 100},
|
||||
{Name: "node-b", Score: 100},
|
||||
{Name: "node-c", Score: 100},
|
||||
{Name: "node-d", Score: 100},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "one constraint on node, all 4 nodes are candidates, maxSkew=2",
|
||||
pod: st.MakePod().Name("p").Label("foo", "").
|
||||
@ -1250,14 +1308,12 @@ func TestPodTopologySpreadScore(t *testing.T) {
|
||||
for _, n := range tt.nodes {
|
||||
nodeName := n.Name
|
||||
score, status := p.Score(ctx, state, tt.pod, nodeName)
|
||||
fmt.Println("get score", score)
|
||||
if !status.IsSuccess() {
|
||||
t.Errorf("unexpected error: %v", status)
|
||||
}
|
||||
gotList = append(gotList, framework.NodeScore{Name: nodeName, Score: score})
|
||||
}
|
||||
|
||||
fmt.Println(gotList)
|
||||
status = p.NormalizeScore(ctx, state, tt.pod, gotList)
|
||||
if !status.IsSuccess() {
|
||||
t.Errorf("unexpected error: %v", status)
|
||||
|
Loading…
Reference in New Issue
Block a user