@@ -28,8 +28,7 @@ import (
2828)
2929
3030// SelectClusters selects clusters based on the placement and resource binding spec.
31- func SelectClusters (clustersScore framework.ClusterScoreList ,
32- placement * policyv1alpha1.Placement , spec * workv1alpha2.ResourceBindingSpec ) ([]spreadconstraint.ClusterDetailInfo , error ) {
31+ func SelectClusters (clustersScore framework.ClusterScoreList , placement * policyv1alpha1.Placement , spec * workv1alpha2.ResourceBindingSpec ) ([]spreadconstraint.ClusterDetailInfo , error ) {
3332 startTime := time .Now ()
3433 defer metrics .ScheduleStep (metrics .ScheduleStepSelect , startTime )
3534
@@ -38,19 +37,24 @@ func SelectClusters(clustersScore framework.ClusterScoreList,
3837}
3938
4039// AssignReplicas assigns replicas to clusters based on the placement and resource binding spec.
41- func AssignReplicas (
42- clusters []spreadconstraint.ClusterDetailInfo ,
43- spec * workv1alpha2.ResourceBindingSpec ,
44- status * workv1alpha2.ResourceBindingStatus ,
45- ) ([]workv1alpha2.TargetCluster , error ) {
40+ func AssignReplicas (clusters []spreadconstraint.ClusterDetailInfo , spec * workv1alpha2.ResourceBindingSpec , status * workv1alpha2.ResourceBindingStatus ) ([]workv1alpha2.TargetCluster , error ) {
4641 startTime := time .Now ()
4742 defer metrics .ScheduleStep (metrics .ScheduleStepAssignReplicas , startTime )
4843
4944 if len (clusters ) == 0 {
5045 return nil , fmt .Errorf ("no clusters available to schedule" )
5146 }
5247
53- if spec .Replicas > 0 {
48+ // Only workloads should participate in replica assignments.
49+ // Workloads with multiple components should be excluded from replica assignment because:
50+ // 1) They don't support replica division.
51+ // 2) They usually don't implement the ReviseReplica interpreter; even if replicas are assigned, the result cannot be applied by the controller.
52+ // For single pod template workloads (like Deployment), if the replica is 0 and no resource requirements are specified,
53+ // assignment is bypassed, causing the workload to be propagated to all candidate clusters. This is a known issue, and
54+ // a suggested fix is: when parsing replicas and requirements, set them to components. This should be addressed along with
55+ // the deprecation of binding.spec.replicas and binding.spec.ReplicaRequirements. After that, the check should be changed to
56+ // len(spec.Components) == 1.
57+ if (spec .Replicas > 0 || spec .ReplicaRequirements != nil ) && len (spec .Components ) <= 1 {
5458 state := newAssignState (clusters , spec , status )
5559 assignFunc , ok := assignFuncMap [state .strategyType ]
5660 if ! ok {
@@ -65,7 +69,7 @@ func AssignReplicas(
6569 return removeZeroReplicasCluster (assignResults ), nil
6670 }
6771
68- // If not workload, assign all clusters without considering replicas .
72+ // For non-workloads (e.g., Service, Config) and multi-component workloads (e.g., FlinkDeployment), propagate to all candidate clusters .
6973 targetClusters := make ([]workv1alpha2.TargetCluster , len (clusters ))
7074 for i , cluster := range clusters {
7175 targetClusters [i ] = workv1alpha2.TargetCluster {Name : cluster .Cluster .Name }
0 commit comments