Skip to content

Commit

Permalink
support expectation
Browse files Browse the repository at this point in the history
Signed-off-by: AiRanthem <[email protected]>
  • Loading branch information
AiRanthem committed Sep 9, 2024
1 parent 68e8262 commit 9cb391b
Show file tree
Hide file tree
Showing 12 changed files with 298 additions and 209 deletions.
21 changes: 19 additions & 2 deletions apis/apps/v1alpha1/uniteddeployment_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1

import (
"strconv"
"time"

appsv1 "k8s.io/api/apps/v1"
Expand Down Expand Up @@ -323,7 +324,7 @@ type UnitedDeploymentStatus struct {

// Record whether each subset is unschedulable.
// +optional
SubsetUnschedulable map[string]UnschedulableStatus `json:"subsetUnschedulable,omitempty"`
SubsetUnschedulable *SubsetUnschedulable `json:"subsetUnschedulable,omitempty"`

// Represents the latest available observations of a UnitedDeployment's current state.
// +optional
Expand Down Expand Up @@ -366,12 +367,28 @@ type UpdateStatus struct {
CurrentPartitions map[string]int32 `json:"currentPartitions,omitempty"`
}

type SubsetUnschedulable struct {
Version int32 `json:"version"`
Status map[string]UnschedulableStatus `json:"status"`
}

func (s *SubsetUnschedulable) GetVersion() string {
return strconv.Itoa(int(s.Version))
}

func (s *SubsetUnschedulable) NotOlderThan(version string) bool {
if v, err := strconv.Atoi(version); err == nil {
return s.Version >= int32(v)

Check failure

Code scanning / CodeQL

Incorrect conversion between integer types High

Incorrect conversion of an integer with architecture-dependent bit size from
strconv.Atoi
to a lower bit size type int32 without an upper bound check.
}
return false
}

type UnschedulableStatus struct {
Unschedulable bool `json:"unschedulable"`
// +optional
UnschedulableTimestamp *metav1.Time `json:"unschedulableTimestamp,omitempty"`
// +optional
PendingPods int32 `json:"pendingPods,omitempty"`
PendingPods int32 `json:"-"`
}

// +genclient
Expand Down
28 changes: 24 additions & 4 deletions apis/apps/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 19 additions & 13 deletions config/crd/bases/apps.kruise.io_uniteddeployments.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1249,20 +1249,26 @@ spec:
of each subset.
type: object
subsetUnschedulable:
additionalProperties:
properties:
pendingPods:
format: int32
type: integer
unschedulable:
type: boolean
unschedulableTimestamp:
format: date-time
type: string
required:
- unschedulable
type: object
description: Record whether each subset is unschedulable.
properties:
status:
additionalProperties:
properties:
unschedulable:
type: boolean
unschedulableTimestamp:
format: date-time
type: string
required:
- unschedulable
type: object
type: object
version:
format: int32
type: integer
required:
- status
- version
type: object
updateStatus:
description: Records the information of update progress.
Expand Down
14 changes: 3 additions & 11 deletions pkg/controller/uniteddeployment/allocator.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (s *specificAllocator) Alloc(nameToSubset *map[string]*Subset) (*map[string
expectedReplicas = *s.Spec.Replicas
}

specifiedReplicas := getSpecifiedSubsetReplicas(expectedReplicas, s.UnitedDeployment, nameToSubset)
specifiedReplicas := getSpecifiedSubsetReplicas(expectedReplicas, s.UnitedDeployment)
klog.V(4).InfoS("UnitedDeployment specifiedReplicas", "unitedDeployment", klog.KObj(s), "specifiedReplicas", specifiedReplicas)
return s.AllocateReplicas(expectedReplicas, specifiedReplicas)
}
Expand Down Expand Up @@ -148,27 +148,19 @@ func (s *specificAllocator) validateReplicas(replicas int32, subsetReplicasLimit
return nil
}

func getSpecifiedSubsetReplicas(replicas int32, ud *appsv1alpha1.UnitedDeployment, nameToSubset *map[string]*Subset) *map[string]int32 {
func getSpecifiedSubsetReplicas(replicas int32, ud *appsv1alpha1.UnitedDeployment) *map[string]int32 {
replicaLimits := map[string]int32{}
if ud.Spec.Topology.Subsets == nil {
return &replicaLimits
}

safeReplicasMap := getNotPendingReplicasMap(nameToSubset)
for _, subsetDef := range ud.Spec.Topology.Subsets {
if subsetDef.Replicas == nil {
continue
}

if specifiedReplicas, err := ParseSubsetReplicas(replicas, *subsetDef.Replicas); err == nil {
limit := specifiedReplicas
if ud.Spec.Topology.ScheduleStrategy.IsAdaptive() {
// This means that in the Adaptive scheduling strategy, an unschedulable subset can only be scaled down, not scaled up.
if safeReplicas, ok := safeReplicasMap[subsetDef.Name]; getSubSetUnschedulable(subsetDef.Name, nameToSubset) && ok {
limit = integer.Int32Min(safeReplicas, specifiedReplicas)
}
}
replicaLimits[subsetDef.Name] = limit
replicaLimits[subsetDef.Name] = specifiedReplicas
} else {
klog.ErrorS(err, "Failed to consider the replicas of subset when parsing replicaLimits during managing replicas of UnitedDeployment",
"subsetName", subsetDef.Name, "unitedDeployment", klog.KObj(ud))
Expand Down
44 changes: 0 additions & 44 deletions pkg/controller/uniteddeployment/allocator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,50 +307,6 @@ func TestCapacityAllocator(t *testing.T) {
}
}

func TestAdaptiveSpecificAllocator(t *testing.T) {
five, seven := intstr.FromInt32(5), int32(7)
ud := &appsv1alpha1.UnitedDeployment{
Spec: appsv1alpha1.UnitedDeploymentSpec{
Replicas: &seven,
Topology: appsv1alpha1.Topology{
Subsets: []appsv1alpha1.Subset{
{
Name: "subset-1",
Replicas: &five,
},
{
Name: "subset-2",
},
},
ScheduleStrategy: appsv1alpha1.UnitedDeploymentScheduleStrategy{
Type: appsv1alpha1.AdaptiveUnitedDeploymentScheduleStrategyType,
},
},
},
}
subsets := map[string]*Subset{
"subset-1": {
Status: SubsetStatus{
UnschedulableStatus: appsv1alpha1.UnschedulableStatus{
Unschedulable: true,
PendingPods: 2,
},
Replicas: 5,
},
Spec: SubsetSpec{Replicas: 5},
},
}
if alloc, err := NewReplicaAllocator(ud).Alloc(&subsets); err != nil {
t.Fatalf("unexpected alloc error %v", err)
} else {
subset1Replicas, subset2Replicas := (*alloc)["subset-1"], (*alloc)["subset-2"]
if subset1Replicas != 3 || subset2Replicas != 4 {
t.Fatalf("unexpected alloc result subset1Replicas = %d not 3, subset2Replicas = %d not 4",
subset1Replicas, subset2Replicas)
}
}
}

func TestAdaptiveElasticAllocator(t *testing.T) {
getUnitedDeploymentAndSubsets := func(totalReplicas, minReplicas, maxReplicas, failedPods int32) (
*appsv1alpha1.UnitedDeployment, map[string]*Subset) {
Expand Down
Loading

0 comments on commit 9cb391b

Please sign in to comment.