Skip to content

Commit

Permalink
add preference binpack replicas plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
mrlihanbo committed Dec 8, 2023
1 parent e57d64a commit b4172cf
Show file tree
Hide file tree
Showing 14 changed files with 1,211 additions and 29 deletions.
4 changes: 2 additions & 2 deletions pkg/apis/core/v1alpha1/extensions_schedulingprofile.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"github.com/kubewharf/kubeadmiral/pkg/controllers/scheduler/framework/plugins/names"
)

func GetDefaultEnabledPlugins() *fedcore.EnabledPlugins {
func GetDefaultEnabledPlugins(replicasPlugin string) *fedcore.EnabledPlugins {
filterPlugins := []string{
names.APIResources,
names.TaintToleration,
Expand All @@ -40,7 +40,7 @@ func GetDefaultEnabledPlugins() *fedcore.EnabledPlugins {
}

selectPlugins := []string{names.MaxCluster}
replicasPlugins := []string{names.ClusterCapacityWeight}
replicasPlugins := []string{replicasPlugin}

return &fedcore.EnabledPlugins{
FilterPlugins: filterPlugins,
Expand Down
20 changes: 13 additions & 7 deletions pkg/controllers/automigration/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ func (c *Controller) reconcile(ctx context.Context, qualifiedName common.Qualifi
// auto-migration controller sets AutoMigrationAnnotation to
// feedback auto-migration information back to the scheduler

var estimatedCapacity map[string]int64
var estimatedCapacity, scheduledPods map[string]int64
var result *worker.Result
needsUpdate := false
if unschedulableThreshold == nil {
Expand All @@ -302,8 +302,8 @@ func (c *Controller) reconcile(ctx context.Context, qualifiedName common.Qualifi
} else {
// Keep the annotation up-to-date if auto migration is enabled.
keyedLogger.V(3).Info("Auto migration is enabled")
estimatedCapacity, result = c.estimateCapacity(ctx, ftc, clusterObjs, *unschedulableThreshold)
autoMigrationInfo := &framework.AutoMigrationInfo{EstimatedCapacity: estimatedCapacity}
estimatedCapacity, scheduledPods, result = c.estimateCapacity(ctx, ftc, clusterObjs, *unschedulableThreshold)
autoMigrationInfo := &framework.AutoMigrationInfo{EstimatedCapacity: estimatedCapacity, ScheduledPods: scheduledPods}

// Compare with the existing autoMigration annotation
existingAutoMigrationInfo := &framework.AutoMigrationInfo{EstimatedCapacity: nil}
Expand Down Expand Up @@ -366,19 +366,22 @@ func (c *Controller) estimateCapacity(
typeConfig *fedcorev1a1.FederatedTypeConfig,
clusterObjs []FederatedObject,
unschedulableThreshold time.Duration,
) (map[string]int64, *worker.Result) {
) (map[string]int64, map[string]int64, *worker.Result) {
needsBackoff := false
var retryAfter *time.Duration

estimatedCapacity := make(map[string]int64, len(clusterObjs))
scheduledPods := make(map[string]int64, len(clusterObjs))

for _, clusterObj := range clusterObjs {
ctx, logger := logging.InjectLoggerValues(ctx, "cluster", clusterObj.ClusterName, "ftc", typeConfig.Name)

// This is an optimization to skip pod listing when there are no unschedulable pods.
totalReplicas, readyReplicas, err := c.getTotalAndReadyReplicas(typeConfig, clusterObj.Object)
if err == nil && totalReplicas == readyReplicas {
logger.V(3).Info("No unschedulable pods found, skip estimating capacity")
logger.V(3).Info("No unschedulable pods found, skip estimating capacity",
"readyReplicas", readyReplicas)
scheduledPods[clusterObj.ClusterName] = totalReplicas
continue
}

Expand All @@ -398,13 +401,16 @@ func (c *Controller) estimateCapacity(
continue
}

unschedulable, nextCrossIn := countUnschedulablePods(pods, time.Now(), unschedulableThreshold)
scheduled, unschedulable, nextCrossIn := countScheduledAndUnschedulablePods(pods, time.Now(), unschedulableThreshold)
logger.V(2).Info("Analyzed pods",
"total", len(pods),
"desired", desiredReplicas,
"scheduled", scheduled,
"unschedulable", unschedulable,
)

scheduledPods[clusterObj.ClusterName] = int64(scheduled)

if nextCrossIn != nil && (retryAfter == nil || *nextCrossIn < *retryAfter) {
retryAfter = nextCrossIn
}
Expand Down Expand Up @@ -441,7 +447,7 @@ func (c *Controller) estimateCapacity(
Backoff: needsBackoff,
}
}
return estimatedCapacity, result
return estimatedCapacity, scheduledPods, result
}

func (c *Controller) getTotalAndReadyReplicas(
Expand Down
10 changes: 6 additions & 4 deletions pkg/controllers/automigration/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,21 @@ import (
// unschedulable for more than unschedulableThreshold,
// and a time.Duration representing the time from now
// when the new unschedulable pod will cross the threshold, if any.
func countUnschedulablePods(
func countScheduledAndUnschedulablePods(
podList []*corev1.Pod,
currentTime time.Time,
unschedulableThreshold time.Duration,
) (unschedulableCount int, nextCrossIn *time.Duration) {
) (scheduledCount, unschedulableCount int, nextCrossIn *time.Duration) {
for _, pod := range podList {
if pod.GetDeletionTimestamp() != nil {
continue
}

scheduledCondition, isUnschedulable := getPodScheduledCondition(pod)
if !isUnschedulable {
if scheduledCondition != nil {
scheduledCount++
}
continue
}

Expand All @@ -51,8 +54,7 @@ func countUnschedulablePods(
nextCrossIn = &crossingThresholdIn
}
}

return unschedulableCount, nextCrossIn
return scheduledCount, unschedulableCount, nextCrossIn
}

func getPodScheduledCondition(pod *corev1.Pod) (scheduledCondition *corev1.PodCondition, isUnschedulable bool) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/controllers/automigration/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func doCheck(
t.Helper()
assert := assert.New(t)

unschedulableCount, nextCrossIn := countUnschedulablePods(pods, now, threshold)
unschedulableCount, nextCrossIn := countScheduledAndUnschedulablePods(pods, now, threshold)

Check failure on line 40 in pkg/controllers/automigration/util_test.go

View workflow job for this annotation

GitHub Actions / test (1.19)

assignment mismatch: 2 variables but countScheduledAndUnschedulablePods returns 3 values

Check failure on line 40 in pkg/controllers/automigration/util_test.go

View workflow job for this annotation

GitHub Actions / test (1.20)

assignment mismatch: 2 variables but countScheduledAndUnschedulablePods returns 3 values
assert.Equal(expectedUnschedulable, unschedulableCount)
assert.Equal(expectedNextCrossIn, nextCrossIn)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/controllers/scheduler/framework/plugins/names/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ const (
MaxCluster = "MaxCluster"
ClusterCapacityWeight = "ClusterCapacityWeight"
ClusterEvicted = "ClusterEvicted"
PreferenceBinPack = "PreferenceBinPack"
)
Loading

0 comments on commit b4172cf

Please sign in to comment.