Skip to content

Commit f2633a4

Browse files
authored
Merge pull request #5012 from mszacillo/unschedulable-plugin-fix
Account for unschedulable plugin result during maxreplica estimation
2 parents d05b921 + 23c9dc9 commit f2633a4

File tree

5 files changed

+20
-6
lines changed

5 files changed

+20
-6
lines changed

pkg/estimator/server/estimate.go

+6
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ func (es *AccurateSchedulerEstimatorServer) estimateReplicas(
7676

7777
var res int32
7878
replicas, ret := es.estimateFramework.RunEstimateReplicasPlugins(ctx, snapshot, &requirements)
79+
80+
// No replicas can be scheduled on the cluster, skip further checks and return 0
81+
if ret.IsUnschedulable() {
82+
return 0, nil
83+
}
84+
7985
if !ret.IsSuccess() && !ret.IsNoOperation() {
8086
return replicas, fmt.Errorf(fmt.Sprintf("estimate replice plugins fails with %s", ret.Reasons()))
8187
}

pkg/estimator/server/framework/interface.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,12 @@ func (s *Result) IsSuccess() bool {
155155
return s == nil || s.code == Success
156156
}
157157

158-
// IsNoOperation return true if "Result" is not nil and Code is "Nooperation"
158+
// IsUnschedulable returns true if "Result" is not nil and Code is "Unschedulable".
159+
func (s *Result) IsUnschedulable() bool {
160+
return s != nil && s.code == Unschedulable
161+
}
162+
163+
// IsNoOperation returns true if "Result" is not nil and Code is "Nooperation"
159164
// ToDo (wengyao04): we can remove it once we include node resource estimation as the default plugin in the future
160165
func (s *Result) IsNoOperation() bool {
161166
return s != nil && s.code == Noopperation

pkg/estimator/server/framework/runtime/framework.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (frw *frameworkImpl) RunEstimateReplicasPlugins(ctx context.Context, snapsh
125125
results := make(framework.PluginToResult)
126126
for _, pl := range frw.estimateReplicasPlugins {
127127
plReplica, ret := frw.runEstimateReplicasPlugins(ctx, pl, snapshot, replicaRequirements)
128-
if ret.IsSuccess() && plReplica < replica {
128+
if (ret.IsSuccess() || ret.IsUnschedulable()) && plReplica < replica {
129129
replica = plReplica
130130
}
131131
results[pl.Name()] = ret

pkg/estimator/server/framework/runtime/framework_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ func Test_frameworkImpl_RunEstimateReplicasPlugins(t *testing.T) {
117117
},
118118
},
119119
expected: estimateReplicaResult{
120-
replica: 1,
120+
replica: 0,
121121
ret: framework.NewResult(framework.Unschedulable, "plugin 2 is unschedulable"),
122122
},
123123
},
@@ -144,7 +144,7 @@ func Test_frameworkImpl_RunEstimateReplicasPlugins(t *testing.T) {
144144
},
145145
},
146146
expected: estimateReplicaResult{
147-
replica: math.MaxInt32,
147+
replica: 0,
148148
ret: framework.NewResult(framework.Unschedulable, "plugin 1 is unschedulable", "plugin 2 is no operation"),
149149
},
150150
},

pkg/scheduler/core/util.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,25 @@ func calAvailableReplicas(clusters []*clusterv1alpha1.Cluster, spec *workv1alpha
6262

6363
// For non-workload, like ServiceAccount, ConfigMap, Secret and etc, it's unnecessary to calculate available replicas in member clusters.
6464
// See issue: https://github.com/karmada-io/karmada/issues/3743.
65+
namespacedKey := names.NamespacedKey(spec.Resource.Namespace, spec.Resource.Name)
6566
if spec.Replicas == 0 {
6667
klog.V(4).Infof("Do not calculate available replicas for non-workload(%s, kind=%s, %s).", spec.Resource.APIVersion,
67-
spec.Resource.Kind, names.NamespacedKey(spec.Resource.Namespace, spec.Resource.Name))
68+
spec.Resource.Kind, namespacedKey)
6869
return availableTargetClusters
6970
}
7071

7172
// Get the minimum value of MaxAvailableReplicas in terms of all estimators.
7273
estimators := estimatorclient.GetReplicaEstimators()
7374
ctx := context.WithValue(context.TODO(), util.ContextKeyObject,
7475
fmt.Sprintf("kind=%s, name=%s/%s", spec.Resource.Kind, spec.Resource.Namespace, spec.Resource.Name))
75-
for _, estimator := range estimators {
76+
for name, estimator := range estimators {
7677
res, err := estimator.MaxAvailableReplicas(ctx, clusters, spec.ReplicaRequirements)
7778
if err != nil {
7879
klog.Errorf("Max cluster available replicas error: %v", err)
7980
continue
8081
}
82+
klog.V(4).Infof("Invoked MaxAvailableReplicas of estimator %s for workload(%s, kind=%s, %s): %v", name,
83+
spec.Resource.APIVersion, spec.Resource.Kind, namespacedKey, res)
8184
for i := range res {
8285
if res[i].Replicas == estimatorclient.UnauthenticReplica {
8386
continue

0 commit comments

Comments
 (0)