Skip to content

Commit

Permalink
chore: disable zero replicas by default (#7788)
Browse files Browse the repository at this point in the history
  • Loading branch information
leon-inf authored Aug 2, 2024
1 parent 49be5b6 commit 07e620f
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 69 deletions.
47 changes: 10 additions & 37 deletions controllers/apps/component_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,32 +380,6 @@ var _ = Describe("Component Controller", func() {
}
}

testChangeReplicasFromZero := func(compName, compDefName string) {
var (
init = int32(0)
target = int32(3)
)

createClusterObjV2(compName, compDefObj.Name, func(f *testapps.MockClusterFactory) {
f.SetReplicas(init)
})

By(fmt.Sprintf("change replicas to %d", target))
changeComponentReplicas(clusterKey, target)

By("checking the number of replicas in component and ITS as expected")
Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) {
g.Expect(comp.Spec.Replicas).Should(Equal(target))
g.Expect(comp.Generation).Should(Equal(comp.Status.ObservedGeneration))
})).Should(Succeed())

By("checking the number of replicas in ITS as expected")
itsKey := compKey
Eventually(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) {
g.Expect(*its.Spec.Replicas).Should(Equal(target))
})).Should(Succeed())
}

testChangeReplicasToZero := func(compName, compDefName string) {
var (
init = int32(3)
Expand Down Expand Up @@ -2134,9 +2108,16 @@ var _ = Describe("Component Controller", func() {
})

It("with component zero replicas", func() {
createClusterObjV2(defaultCompName, compDefName, func(f *testapps.MockClusterFactory) {
f.SetReplicas(0)
})
phase := appsv1alpha1.ClusterPhase("")
createClusterObjVx("", defaultCompName, compDefName, true,
func(f *testapps.MockClusterFactory) {
f.SetReplicas(0)
}, &phase)

By("checking the component status can't be reconciled well")
Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) {
g.Expect(comp.Generation > comp.Status.ObservedGeneration).Should(BeTrue())
})).Should(Succeed())
})

It("with component services", func() {
Expand Down Expand Up @@ -2202,10 +2183,6 @@ var _ = Describe("Component Controller", func() {
testChangeReplicas(replicationCompName, replicationCompDefName)
})

It("scale-out from 0", func() {
testChangeReplicasFromZero(replicationCompName, replicationCompDefName)
})

It("scale-in to 0", func() {
testChangeReplicasToZero(replicationCompName, replicationCompDefName)
})
Expand Down Expand Up @@ -2340,10 +2317,6 @@ var _ = Describe("Component Controller", func() {
It("scale-in to 0 and PVCs should not been deleted", func() {
testHorizontalScale(compName, compDefObj.Name, 3, 0, appsv1alpha1.HScaleDataClonePolicyCloneVolume)
})

It("scale-out from 0 and should work well", func() {
testHorizontalScale(compName, compDefObj.Name, 0, 3, appsv1alpha1.HScaleDataClonePolicyCloneVolume)
})
})

Context(fmt.Sprintf("[comp: %s] scale-out after volume expansion", compName), func() {
Expand Down
42 changes: 10 additions & 32 deletions controllers/apps/transformer_component_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@ package apps

import (
"fmt"
"math"

appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1"
"github.com/apecloud/kubeblocks/pkg/controller/graph"
)

const (
defaultMinReplicas int32 = 0
defaultMinReplicas4ScaleIn int32 = 1
var (
defaultReplicasLimit = appsv1alpha1.ReplicasLimit{
MinReplicas: 1,
MaxReplicas: math.MaxInt32,
}
)

// componentValidationTransformer validates the consistency between spec & definition.
Expand Down Expand Up @@ -86,44 +89,19 @@ func validateEnabledLogConfigs(compDef *appsv1alpha1.ComponentDefinition, enable
}

func validateCompReplicas(comp *appsv1alpha1.Component, compDef *appsv1alpha1.ComponentDefinition) error {
if err := validateCompReplicasGeneral(comp, compDef); err != nil {
return err
replicasLimit := &defaultReplicasLimit
// always respect the replicas limit if set.
if compDef.Spec.ReplicasLimit != nil {
replicasLimit = compDef.Spec.ReplicasLimit
}
return validateCompReplicas4Runtime(comp, compDef)
}

func validateCompReplicasGeneral(comp *appsv1alpha1.Component, compDef *appsv1alpha1.ComponentDefinition) error {
if compDef.Spec.ReplicasLimit == nil {
return nil
}
replicas := comp.Spec.Replicas
replicasLimit := compDef.Spec.ReplicasLimit
if replicas >= replicasLimit.MinReplicas && replicas <= replicasLimit.MaxReplicas {
return nil
}
return replicasOutOfLimitError(replicas, *replicasLimit)
}

func validateCompReplicas4Runtime(comp *appsv1alpha1.Component, compDef *appsv1alpha1.ComponentDefinition) error {
minReplicas := func() int32 {
// always respect the replicas limit if it is set.
if compDef.Spec.ReplicasLimit != nil {
return compDef.Spec.ReplicasLimit.MinReplicas
}
// HACK: take observedGeneration == 0 as the provisioning.
if comp.Status.ObservedGeneration == 0 {
return defaultMinReplicas
}
return min(comp.Spec.Replicas, defaultMinReplicas4ScaleIn)
}()

replicas := comp.Spec.Replicas
if replicas < minReplicas {
return fmt.Errorf("replicas %d is less than required min replicas %d", replicas, minReplicas)
}
return nil
}

func replicasOutOfLimitError(replicas int32, replicasLimit appsv1alpha1.ReplicasLimit) error {
return fmt.Errorf("replicas %d out-of-limit [%d, %d]", replicas, replicasLimit.MinReplicas, replicasLimit.MaxReplicas)
}

0 comments on commit 07e620f

Please sign in to comment.