Skip to content

Commit 29b3ec9

Browse files
authored
Merge pull request kubernetes#72140 from wgliang/feature/adaptive-percentage-find-nodes
Set percentage of nodes scored in each cycle dynamically based on the…
2 parents b2a0315 + 6515c4e commit 29b3ec9

File tree

6 files changed

+77
-15
lines changed

6 files changed

+77
-15
lines changed

cmd/kube-scheduler/app/options/options_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,7 @@ users:
225225
Burst: 100,
226226
ContentType: "application/vnd.kubernetes.protobuf",
227227
},
228-
PercentageOfNodesToScore: 50,
229-
BindTimeoutSeconds: &defaultBindTimeoutSeconds,
228+
BindTimeoutSeconds: &defaultBindTimeoutSeconds,
230229
},
231230
},
232231
{
@@ -306,8 +305,7 @@ users:
306305
Burst: 100,
307306
ContentType: "application/vnd.kubernetes.protobuf",
308307
},
309-
PercentageOfNodesToScore: 50,
310-
BindTimeoutSeconds: &defaultBindTimeoutSeconds,
308+
BindTimeoutSeconds: &defaultBindTimeoutSeconds,
311309
},
312310
},
313311
{

pkg/scheduler/apis/config/types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ type KubeSchedulerConfiguration struct {
7979
// at least "minFeasibleNodesToFind" feasible nodes no matter what the value of this flag is.
8080
// Example: if the cluster size is 500 nodes and the value of this flag is 30,
8181
// then scheduler stops finding further feasible nodes once it finds 150 feasible ones.
82-
// When the value is 0, default percentage (50%) of the nodes will be scored.
82+
// When the value is 0, default percentage (5%--50% based on the size of the cluster) of the
83+
// nodes will be scored.
8384
PercentageOfNodesToScore int32
8485

8586
// DEPRECATED.

pkg/scheduler/apis/config/v1alpha1/defaults.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,6 @@ func SetDefaults_KubeSchedulerConfiguration(obj *kubescedulerconfigv1alpha1.Kube
8181
obj.LeaderElection.LockObjectName = kubescedulerconfigv1alpha1.SchedulerDefaultLockObjectName
8282
}
8383

84-
if obj.PercentageOfNodesToScore == 0 {
85-
// by default, stop finding feasible nodes once the number of feasible nodes is 50% of the cluster.
86-
obj.PercentageOfNodesToScore = 50
87-
}
88-
8984
if len(obj.FailureDomains) == 0 {
9085
obj.FailureDomains = kubeletapis.DefaultFailureDomains
9186
}

pkg/scheduler/core/generic_scheduler.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ const (
5454
// certain minimum of nodes are checked for feasibility. This in turn helps
5555
// ensure a minimum level of spreading.
5656
minFeasibleNodesToFind = 100
57+
// minFeasibleNodesPercentageToFind is the minimum percentage of nodes that
58+
// would be scored in each scheduling cycle. This is a semi-arbitrary value
59+
// to ensure that a certain minimum of nodes are checked for feasibility.
60+
// This in turn helps ensure a minimum level of spreading.
61+
minFeasibleNodesPercentageToFind = 5
5762
)
5863

5964
// FailedPredicateMap declares a map[string][]algorithm.PredicateFailureReason type.
@@ -375,15 +380,24 @@ func (g *genericScheduler) getLowerPriorityNominatedPods(pod *v1.Pod, nodeName s
375380

376381
// numFeasibleNodesToFind returns the number of feasible nodes that once found, the scheduler stops
377382
// its search for more feasible nodes.
378-
func (g *genericScheduler) numFeasibleNodesToFind(numAllNodes int32) int32 {
379-
if numAllNodes < minFeasibleNodesToFind || g.percentageOfNodesToScore <= 0 ||
380-
g.percentageOfNodesToScore >= 100 {
383+
func (g *genericScheduler) numFeasibleNodesToFind(numAllNodes int32) (numNodes int32) {
384+
if numAllNodes < minFeasibleNodesToFind || g.percentageOfNodesToScore >= 100 {
381385
return numAllNodes
382386
}
383-
numNodes := numAllNodes * g.percentageOfNodesToScore / 100
387+
388+
adaptivePercentage := g.percentageOfNodesToScore
389+
if adaptivePercentage <= 0 {
390+
adaptivePercentage = schedulerapi.DefaultPercentageOfNodesToScore - numAllNodes/125
391+
if adaptivePercentage < minFeasibleNodesPercentageToFind {
392+
adaptivePercentage = minFeasibleNodesPercentageToFind
393+
}
394+
}
395+
396+
numNodes = numAllNodes * adaptivePercentage / 100
384397
if numNodes < minFeasibleNodesToFind {
385398
return minFeasibleNodesToFind
386399
}
400+
387401
return numNodes
388402
}
389403

pkg/scheduler/core/generic_scheduler_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,3 +1483,56 @@ func TestPreempt(t *testing.T) {
14831483
})
14841484
}
14851485
}
1486+
1487+
func TestNumFeasibleNodesToFind(t *testing.T) {
1488+
tests := []struct {
1489+
name string
1490+
percentageOfNodesToScore int32
1491+
numAllNodes int32
1492+
wantNumNodes int32
1493+
}{
1494+
{
1495+
name: "not set percentageOfNodesToScore and nodes number not more than 50",
1496+
numAllNodes: 10,
1497+
wantNumNodes: 10,
1498+
},
1499+
{
1500+
name: "set percentageOfNodesToScore and nodes number not more than 50",
1501+
percentageOfNodesToScore: 40,
1502+
numAllNodes: 10,
1503+
wantNumNodes: 10,
1504+
},
1505+
{
1506+
name: "not set percentageOfNodesToScore and nodes number more than 50",
1507+
numAllNodes: 1000,
1508+
wantNumNodes: 420,
1509+
},
1510+
{
1511+
name: "set percentageOfNodesToScore and nodes number more than 50",
1512+
percentageOfNodesToScore: 40,
1513+
numAllNodes: 1000,
1514+
wantNumNodes: 400,
1515+
},
1516+
{
1517+
name: "not set percentageOfNodesToScore and nodes number more than 50*125",
1518+
numAllNodes: 6000,
1519+
wantNumNodes: 300,
1520+
},
1521+
{
1522+
name: "set percentageOfNodesToScore and nodes number more than 50*125",
1523+
percentageOfNodesToScore: 40,
1524+
numAllNodes: 6000,
1525+
wantNumNodes: 2400,
1526+
},
1527+
}
1528+
for _, tt := range tests {
1529+
t.Run(tt.name, func(t *testing.T) {
1530+
g := &genericScheduler{
1531+
percentageOfNodesToScore: tt.percentageOfNodesToScore,
1532+
}
1533+
if gotNumNodes := g.numFeasibleNodesToFind(tt.numAllNodes); gotNumNodes != tt.wantNumNodes {
1534+
t.Errorf("genericScheduler.numFeasibleNodesToFind() = %v, want %v", gotNumNodes, tt.wantNumNodes)
1535+
}
1536+
})
1537+
}
1538+
}

staging/src/k8s.io/kube-scheduler/config/v1alpha1/types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ type KubeSchedulerConfiguration struct {
7575
// at least "minFeasibleNodesToFind" feasible nodes no matter what the value of this flag is.
7676
// Example: if the cluster size is 500 nodes and the value of this flag is 30,
7777
// then scheduler stops finding further feasible nodes once it finds 150 feasible ones.
78-
// When the value is 0, default percentage (50%) of the nodes will be scored.
78+
// When the value is 0, default percentage (5%--50% based on the size of the cluster) of the
79+
// nodes will be scored.
7980
PercentageOfNodesToScore int32 `json:"percentageOfNodesToScore"`
8081

8182
// DEPRECATED.

0 commit comments

Comments
 (0)