diff --git a/apis/v1alpha1/defaulting.go b/apis/v1alpha1/defaulting.go
index be01992..9e41119 100644
--- a/apis/v1alpha1/defaulting.go
+++ b/apis/v1alpha1/defaulting.go
@@ -15,9 +15,11 @@
package v1alpha1
import (
+ "reflect"
"strings"
"dario.cat/mergo"
+ appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/util/intstr"
@@ -34,7 +36,7 @@ func (in *GreptimeDBCluster) SetDefaults() error {
in.Spec.Version = getVersionFromImage(in.GetBaseMainContainer().GetImage())
// Merge the default settings into the GreptimeDBClusterSpec.
- if err := mergo.Merge(&in.Spec, in.defaultSpec()); err != nil {
+ if err := mergo.Merge(&in.Spec, in.defaultSpec(), mergo.WithTransformers(intOrStringTransformer{})); err != nil {
return err
}
@@ -171,6 +173,7 @@ func (in *GreptimeDBCluster) defaultFrontend() *FrontendSpec {
Service: &ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
},
+ RollingUpdate: defaultRollingUpdateForDeployment(),
}
}
@@ -188,6 +191,7 @@ func (in *GreptimeDBCluster) defaultMeta() *MetaSpec {
RPCPort: DefaultMetaRPCPort,
HTTPPort: DefaultHTTPPort,
EnableRegionFailover: &enableRegionFailover,
+ RollingUpdate: defaultRollingUpdateForDeployment(),
}
}
@@ -198,9 +202,10 @@ func (in *GreptimeDBCluster) defaultDatanode() *DatanodeSpec {
Replicas: pointer.Int32(DefaultReplicas),
Logging: &LoggingSpec{},
},
- RPCPort: DefaultRPCPort,
- HTTPPort: DefaultHTTPPort,
- Storage: defaultDatanodeStorage(),
+ RPCPort: DefaultRPCPort,
+ HTTPPort: DefaultHTTPPort,
+ Storage: defaultDatanodeStorage(),
+ RollingUpdate: defaultRollingUpdateForStatefulSet(),
}
}
@@ -312,7 +317,7 @@ func (in *GreptimeDBStandalone) SetDefaults() error {
in.Spec.Version = getVersionFromImage(in.GetBaseMainContainer().GetImage())
- if err := mergo.Merge(&in.Spec, in.defaultSpec()); err != nil {
+ if err := mergo.Merge(&in.Spec, in.defaultSpec(), mergo.WithTransformers(intOrStringTransformer{})); err != nil {
return err
}
@@ -344,6 +349,7 @@ func (in *GreptimeDBStandalone) defaultSpec() *GreptimeDBStandaloneSpec {
OnlyLogToStdout: pointer.Bool(false),
},
DatanodeStorage: defaultDatanodeStorage(),
+ RollingUpdate: defaultRollingUpdateForStatefulSet(),
}
return defaultSpec
@@ -427,3 +433,58 @@ func defaultReadinessProbe() *corev1.Probe {
FailureThreshold: 10,
}
}
+
+// Same as the default rolling update strategy of Deployment.
+func defaultRollingUpdateForDeployment() *appsv1.RollingUpdateDeployment {
+ return &appsv1.RollingUpdateDeployment{
+ MaxUnavailable: &intstr.IntOrString{Type: intstr.String, StrVal: "25%"},
+ MaxSurge: &intstr.IntOrString{Type: intstr.String, StrVal: "25%"},
+ }
+}
+
+// Same as the default rolling update strategy of StatefulSet.
+func defaultRollingUpdateForStatefulSet() *appsv1.RollingUpdateStatefulSetStrategy {
+ return &appsv1.RollingUpdateStatefulSetStrategy{
+ Partition: pointer.Int32(0),
+ MaxUnavailable: &intstr.IntOrString{
+ Type: intstr.Int,
+ IntVal: 1,
+ },
+ }
+}
+
+// This transformer handles merging of intstr.IntOrString values.
+// The `Type` field in IntOrString is an int starting from 0, which means it would be considered "empty" during merging and get overwritten.
+// We want to preserve the original Type of the destination value while only merging the actual int/string content.
+type intOrStringTransformer struct{}
+
+func (t intOrStringTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
+ if typ != reflect.TypeOf(&intstr.IntOrString{}) {
+ return nil
+ }
+
+ return func(dst, src reflect.Value) error {
+ if dst.IsNil() || src.IsNil() {
+ return nil
+ }
+
+ dstVal, srcVal := dst.Interface().(*intstr.IntOrString), src.Interface().(*intstr.IntOrString)
+
+ // Don't override the type of dst.
+ if dstVal.Type == intstr.Int {
+ if dstVal.IntVal == 0 {
+ dstVal.IntVal = srcVal.IntVal
+ }
+ dstVal.StrVal = ""
+ }
+
+ if dstVal.Type == intstr.String {
+ if dstVal.StrVal == "" {
+ dstVal.StrVal = srcVal.StrVal
+ }
+ dstVal.IntVal = 0
+ }
+
+ return nil
+ }
+}
diff --git a/apis/v1alpha1/defaulting_test.go b/apis/v1alpha1/defaulting_test.go
index cf9d97f..f12d494 100644
--- a/apis/v1alpha1/defaulting_test.go
+++ b/apis/v1alpha1/defaulting_test.go
@@ -20,7 +20,9 @@ import (
"reflect"
"testing"
+ "dario.cat/mergo"
"github.com/sergi/go-diff/diffmatchpatch"
+ "k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/yaml"
)
@@ -211,3 +213,47 @@ func TestStandaloneSetDefaults(t *testing.T) {
}
}
}
+
+func TestIntOrStringTransformer(t *testing.T) {
+ type foo struct {
+ Val *intstr.IntOrString
+ }
+ type testStruct struct {
+ Src foo
+ Dst foo
+ Expect foo
+ }
+
+ tests := []testStruct{
+ {
+ Src: foo{Val: &intstr.IntOrString{Type: intstr.String, StrVal: "1"}},
+ Dst: foo{Val: &intstr.IntOrString{Type: intstr.Int, IntVal: 10}},
+ Expect: foo{Val: &intstr.IntOrString{Type: intstr.Int, IntVal: 10}},
+ },
+ {
+ Src: foo{Val: &intstr.IntOrString{Type: intstr.String, StrVal: "25%"}},
+ Dst: foo{Val: &intstr.IntOrString{Type: intstr.String, StrVal: "75%"}},
+ Expect: foo{Val: &intstr.IntOrString{Type: intstr.String, StrVal: "75%"}},
+ },
+ {
+ Src: foo{Val: &intstr.IntOrString{Type: intstr.String, StrVal: "25%"}},
+ Dst: foo{},
+ Expect: foo{Val: &intstr.IntOrString{Type: intstr.String, StrVal: "25%"}},
+ },
+ {
+ Src: foo{Val: &intstr.IntOrString{Type: intstr.Int, IntVal: 10}},
+ Dst: foo{},
+ Expect: foo{Val: &intstr.IntOrString{Type: intstr.Int, IntVal: 10}},
+ },
+ }
+
+ for i, tt := range tests {
+ if err := mergo.Merge(&tt.Dst, &tt.Src, mergo.WithTransformers(intOrStringTransformer{})); err != nil {
+ t.Errorf("test [%d] failed: %v", i, err)
+ }
+
+ if !reflect.DeepEqual(tt.Dst, tt.Expect) {
+ t.Errorf("test [%d] failed: expected '%v', got '%v'", i, tt.Expect, tt.Dst)
+ }
+ }
+}
diff --git a/apis/v1alpha1/greptimedbcluster_types.go b/apis/v1alpha1/greptimedbcluster_types.go
index 9ef7666..8850211 100644
--- a/apis/v1alpha1/greptimedbcluster_types.go
+++ b/apis/v1alpha1/greptimedbcluster_types.go
@@ -15,6 +15,7 @@
package v1alpha1
import (
+ appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -70,6 +71,10 @@ type MetaSpec struct {
// StoreKeyPrefix is the prefix of the key in the etcd. We can use it to isolate the data of different clusters.
// +optional
StoreKeyPrefix string `json:"storeKeyPrefix,omitempty"`
+
+ // RollingUpdate is the rolling update configuration. We always use `RollingUpdate` strategyt.
+ // +optional
+ RollingUpdate *appsv1.RollingUpdateDeployment `json:"rollingUpdate,omitempty"`
}
func (in *MetaSpec) GetConfig() string {
@@ -143,6 +148,10 @@ type FrontendSpec struct {
// TLS is the TLS configuration of the frontend.
// +optional
TLS *TLSSpec `json:"tls,omitempty"`
+
+ // RollingUpdate is the rolling update configuration. We always use `RollingUpdate` strategyt.
+ // +optional
+ RollingUpdate *appsv1.RollingUpdateDeployment `json:"rollingUpdate,omitempty"`
}
func (in *FrontendSpec) GetTLS() *TLSSpec {
@@ -192,6 +201,10 @@ type DatanodeSpec struct {
// Storage is the default file storage of the datanode. For example, WAL, cache, index etc.
// +optional
Storage *DatanodeStorageSpec `json:"storage,omitempty"`
+
+ // RollingUpdate is the rolling update configuration. We always use `RollingUpdate` strategy.
+ // +optional
+ RollingUpdate *appsv1.RollingUpdateStatefulSetStrategy `json:"rollingUpdate,omitempty"`
}
func (in *DatanodeSpec) GetConfig() string {
@@ -231,6 +244,10 @@ type FlownodeSpec struct {
// +kubebuilder:validation:Maximum=65535
// +optional
RPCPort int32 `json:"rpcPort,omitempty"`
+
+ // RollingUpdate is the rolling update configuration. We always use `RollingUpdate` strategy.
+ // +optional
+ RollingUpdate *appsv1.RollingUpdateStatefulSetStrategy `json:"rollingUpdate,omitempty"`
}
func (in *FlownodeSpec) GetConfig() string {
diff --git a/apis/v1alpha1/greptimedbstandalone_types.go b/apis/v1alpha1/greptimedbstandalone_types.go
index 81b1686..4b61035 100644
--- a/apis/v1alpha1/greptimedbstandalone_types.go
+++ b/apis/v1alpha1/greptimedbstandalone_types.go
@@ -15,6 +15,7 @@
package v1alpha1
import (
+ appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -87,6 +88,10 @@ type GreptimeDBStandaloneSpec struct {
// Logging defines the logging configuration for the component.
// +optional
Logging *LoggingSpec `json:"logging,omitempty"`
+
+ // RollingUpdate is the rolling update configuration. We always use `RollingUpdate` strategy.
+ // +optional
+ RollingUpdate *appsv1.RollingUpdateStatefulSetStrategy `json:"rollingUpdate,omitempty"`
}
// GreptimeDBStandaloneStatus defines the observed state of GreptimeDBStandalone
diff --git a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/merge/test00/expect.yaml b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/merge/test00/expect.yaml
index a2075c9..e575d99 100644
--- a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/merge/test00/expect.yaml
+++ b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/merge/test00/expect.yaml
@@ -59,6 +59,9 @@ spec:
logsDir: /data/greptimedb/logs
onlyLogToStdout: false
persistentWithData: false
+ rollingUpdate:
+ maxUnavailable: 1
+ maxSurge: 2
template:
main:
image: greptime/greptimedb:test
@@ -100,6 +103,9 @@ spec:
logsDir: /data/greptimedb/logs
onlyLogToStdout: false
persistentWithData: false
+ rollingUpdate:
+ maxSurge: 25%
+ maxUnavailable: 25%
template:
main:
image: greptime/greptimedb:latest
@@ -145,6 +151,9 @@ spec:
logsDir: /data/greptimedb/logs
onlyLogToStdout: false
persistentWithData: false
+ rollingUpdate:
+ maxUnavailable: 25%
+ partition: 1
template:
main:
image: greptime/greptimedb:latest
diff --git a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/merge/test00/input.yaml b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/merge/test00/input.yaml
index 2de7752..bd3d423 100644
--- a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/merge/test00/input.yaml
+++ b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/merge/test00/input.yaml
@@ -20,6 +20,9 @@ spec:
template:
main:
image: greptime/greptimedb:test
+ rollingUpdate:
+ maxUnavailable: 1
+ maxSurge: 2
meta:
etcdEndpoints:
- etcd.etcd-cluster.svc.cluster.local:2379
@@ -37,4 +40,7 @@ spec:
replicas: 3
logging:
level: debug
+ rollingUpdate:
+ partition: 1
+ maxUnavailable: 25%
httpPort: 5000
diff --git a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test00/expect.yaml b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test00/expect.yaml
index c7b9d03..803d408 100644
--- a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test00/expect.yaml
+++ b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test00/expect.yaml
@@ -48,6 +48,9 @@ spec:
type: ClusterIP
logging: {}
template: {}
+ rollingUpdate:
+ maxSurge: 25%
+ maxUnavailable: 25%
meta:
etcdEndpoints:
- etcd.etcd-cluster.svc.cluster.local:2379
@@ -57,6 +60,9 @@ spec:
replicas: 1
logging: {}
template: {}
+ rollingUpdate:
+ maxSurge: 25%
+ maxUnavailable: 25%
datanode:
httpPort: 4000
rpcPort: 4001
@@ -70,3 +76,6 @@ spec:
storageSize: 10Gi
logging: {}
template: {}
+ rollingUpdate:
+ maxUnavailable: 1
+ partition: 0
diff --git a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test01/expect.yaml b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test01/expect.yaml
index 8c64033..87b1340 100644
--- a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test01/expect.yaml
+++ b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test01/expect.yaml
@@ -60,6 +60,9 @@ spec:
args:
- --metasrv-addrs
- meta.default:3002
+ rollingUpdate:
+ maxUnavailable: 25%
+ maxSurge: 25%
meta:
enableRegionFailover: false
etcdEndpoints:
@@ -74,6 +77,9 @@ spec:
args:
- --store-addr
- etcd.default:2379
+ rollingUpdate:
+ maxUnavailable: 25%
+ maxSurge: 25%
datanode:
httpPort: 4000
rpcPort: 4001
@@ -89,3 +95,6 @@ spec:
template:
main:
image: greptime/greptimedb:latest
+ rollingUpdate:
+ maxUnavailable: 1
+ partition: 0
diff --git a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test02/expect.yaml b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test02/expect.yaml
index c9a5c1b..be3f1ca 100644
--- a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test02/expect.yaml
+++ b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test02/expect.yaml
@@ -59,6 +59,9 @@ spec:
type: ClusterIP
logging: {}
template: {}
+ rollingUpdate:
+ maxUnavailable: 25%
+ maxSurge: 25%
meta:
etcdEndpoints:
- etcd.etcd-cluster.svc.cluster.local:2379
@@ -69,6 +72,9 @@ spec:
rpcPort: 3002
replicas: 1
template: {}
+ rollingUpdate:
+ maxUnavailable: 25%
+ maxSurge: 25%
datanode:
httpPort: 4000
rpcPort: 4001
@@ -82,3 +88,6 @@ spec:
storageRetainPolicy: Retain
storageSize: 10Gi
template: {}
+ rollingUpdate:
+ maxUnavailable: 1
+ partition: 0
diff --git a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test03/expect.yaml b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test03/expect.yaml
index a901178..1660311 100644
--- a/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test03/expect.yaml
+++ b/apis/v1alpha1/testdata/defaulting/greptimedbcluster/setdefaults/test03/expect.yaml
@@ -59,6 +59,9 @@ spec:
type: ClusterIP
logging: {}
template: {}
+ rollingUpdate:
+ maxSurge: 25%
+ maxUnavailable: 25%
meta:
etcdEndpoints:
- etcd.etcd-cluster.svc.cluster.local:2379
@@ -69,6 +72,9 @@ spec:
replicas: 1
logging: {}
template: {}
+ rollingUpdate:
+ maxSurge: 25%
+ maxUnavailable: 25%
datanode:
httpPort: 4000
rpcPort: 4001
@@ -82,6 +88,9 @@ spec:
storageSize: 10Gi
logging: {}
template: {}
+ rollingUpdate:
+ maxUnavailable: 1
+ partition: 0
monitoring:
enabled: true
logsCollection: {}
@@ -127,6 +136,9 @@ spec:
service:
type: ClusterIP
version: latest
+ rollingUpdate:
+ maxUnavailable: 1
+ partition: 0
vector:
image: timberio/vector:nightly-alpine
resources:
diff --git a/apis/v1alpha1/testdata/defaulting/greptimedbstandalone/test00/expect.yaml b/apis/v1alpha1/testdata/defaulting/greptimedbstandalone/test00/expect.yaml
index cab06ce..3416ae0 100644
--- a/apis/v1alpha1/testdata/defaulting/greptimedbstandalone/test00/expect.yaml
+++ b/apis/v1alpha1/testdata/defaulting/greptimedbstandalone/test00/expect.yaml
@@ -45,3 +45,6 @@ spec:
mountPath: /data/greptimedb
storageRetainPolicy: Retain
storageSize: 10Gi
+ rollingUpdate:
+ maxUnavailable: 1
+ partition: 0
diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go
index 60fea66..a374937 100644
--- a/apis/v1alpha1/zz_generated.deepcopy.go
+++ b/apis/v1alpha1/zz_generated.deepcopy.go
@@ -19,6 +19,7 @@
package v1alpha1
import (
+ appsv1 "k8s.io/api/apps/v1"
"k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@@ -99,6 +100,11 @@ func (in *DatanodeSpec) DeepCopyInto(out *DatanodeSpec) {
*out = new(DatanodeStorageSpec)
(*in).DeepCopyInto(*out)
}
+ if in.RollingUpdate != nil {
+ in, out := &in.RollingUpdate, &out.RollingUpdate
+ *out = new(appsv1.RollingUpdateStatefulSetStrategy)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatanodeSpec.
@@ -170,6 +176,11 @@ func (in *FileStorage) DeepCopy() *FileStorage {
func (in *FlownodeSpec) DeepCopyInto(out *FlownodeSpec) {
*out = *in
in.ComponentSpec.DeepCopyInto(&out.ComponentSpec)
+ if in.RollingUpdate != nil {
+ in, out := &in.RollingUpdate, &out.RollingUpdate
+ *out = new(appsv1.RollingUpdateStatefulSetStrategy)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlownodeSpec.
@@ -211,6 +222,11 @@ func (in *FrontendSpec) DeepCopyInto(out *FrontendSpec) {
*out = new(TLSSpec)
**out = **in
}
+ if in.RollingUpdate != nil {
+ in, out := &in.RollingUpdate, &out.RollingUpdate
+ *out = new(appsv1.RollingUpdateDeployment)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FrontendSpec.
@@ -521,6 +537,11 @@ func (in *GreptimeDBStandaloneSpec) DeepCopyInto(out *GreptimeDBStandaloneSpec)
*out = new(LoggingSpec)
(*in).DeepCopyInto(*out)
}
+ if in.RollingUpdate != nil {
+ in, out := &in.RollingUpdate, &out.RollingUpdate
+ *out = new(appsv1.RollingUpdateStatefulSetStrategy)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GreptimeDBStandaloneSpec.
@@ -744,6 +765,11 @@ func (in *MetaSpec) DeepCopyInto(out *MetaSpec) {
*out = new(bool)
**out = **in
}
+ if in.RollingUpdate != nil {
+ in, out := &in.RollingUpdate, &out.RollingUpdate
+ *out = new(appsv1.RollingUpdateDeployment)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetaSpec.
diff --git a/config/crd/resources/greptime.io_greptimedbclusters.yaml b/config/crd/resources/greptime.io_greptimedbclusters.yaml
index c2ad24b..4c0bc28 100644
--- a/config/crd/resources/greptime.io_greptimedbclusters.yaml
+++ b/config/crd/resources/greptime.io_greptimedbclusters.yaml
@@ -3066,6 +3066,17 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -6105,6 +6116,17 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -9137,6 +9159,19 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxSurge:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -12237,6 +12272,19 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxSurge:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -18361,6 +18409,17 @@ spec:
required:
- enabled
type: object
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
diff --git a/config/crd/resources/greptime.io_greptimedbstandalones.yaml b/config/crd/resources/greptime.io_greptimedbstandalones.yaml
index 6468eaf..39fdc73 100644
--- a/config/crd/resources/greptime.io_greptimedbstandalones.yaml
+++ b/config/crd/resources/greptime.io_greptimedbstandalones.yaml
@@ -3173,6 +3173,17 @@ spec:
required:
- enabled
type: object
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
diff --git a/controllers/greptimedbcluster/deployers/datanode.go b/controllers/greptimedbcluster/deployers/datanode.go
index 9684ad0..4a023d9 100644
--- a/controllers/greptimedbcluster/deployers/datanode.go
+++ b/controllers/greptimedbcluster/deployers/datanode.go
@@ -388,6 +388,10 @@ func (b *datanodeBuilder) BuildStatefulSet() deployer.Builder {
},
Template: b.generatePodTemplateSpec(),
VolumeClaimTemplates: b.generatePVCs(),
+ UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
+ Type: appsv1.RollingUpdateStatefulSetStrategyType,
+ RollingUpdate: b.Cluster.Spec.Datanode.RollingUpdate,
+ },
},
}
diff --git a/controllers/greptimedbcluster/deployers/flownode.go b/controllers/greptimedbcluster/deployers/flownode.go
index b192998..cd890ab 100644
--- a/controllers/greptimedbcluster/deployers/flownode.go
+++ b/controllers/greptimedbcluster/deployers/flownode.go
@@ -193,6 +193,10 @@ func (b *flownodeBuilder) BuildStatefulSet() deployer.Builder {
},
},
Template: b.generatePodTemplateSpec(),
+ UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
+ Type: appsv1.RollingUpdateStatefulSetStrategyType,
+ RollingUpdate: b.Cluster.Spec.Flownode.RollingUpdate,
+ },
},
}
diff --git a/controllers/greptimedbcluster/deployers/frontend.go b/controllers/greptimedbcluster/deployers/frontend.go
index f3a8d21..e1a6d87 100644
--- a/controllers/greptimedbcluster/deployers/frontend.go
+++ b/controllers/greptimedbcluster/deployers/frontend.go
@@ -170,6 +170,10 @@ func (b *frontendBuilder) BuildDeployment() deployer.Builder {
},
},
Template: *b.generatePodTemplateSpec(),
+ Strategy: appsv1.DeploymentStrategy{
+ Type: appsv1.RollingUpdateDeploymentStrategyType,
+ RollingUpdate: b.Cluster.Spec.Frontend.RollingUpdate,
+ },
},
}
diff --git a/controllers/greptimedbcluster/deployers/meta.go b/controllers/greptimedbcluster/deployers/meta.go
index c8f1ead..fb88f7f 100644
--- a/controllers/greptimedbcluster/deployers/meta.go
+++ b/controllers/greptimedbcluster/deployers/meta.go
@@ -247,6 +247,10 @@ func (b *metaBuilder) BuildDeployment() deployer.Builder {
},
},
Template: *b.generatePodTemplateSpec(),
+ Strategy: appsv1.DeploymentStrategy{
+ Type: appsv1.RollingUpdateDeploymentStrategyType,
+ RollingUpdate: b.Cluster.Spec.Meta.RollingUpdate,
+ },
},
}
diff --git a/controllers/greptimedbstandalone/deployer.go b/controllers/greptimedbstandalone/deployer.go
index b8283f0..8857d60 100644
--- a/controllers/greptimedbstandalone/deployer.go
+++ b/controllers/greptimedbstandalone/deployer.go
@@ -253,6 +253,10 @@ func (b *standaloneBuilder) BuildStatefulSet() deployer.Builder {
},
Template: b.generatePodTemplateSpec(),
VolumeClaimTemplates: b.generatePVCs(),
+ UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
+ Type: appsv1.RollingUpdateStatefulSetStrategyType,
+ RollingUpdate: b.standalone.Spec.RollingUpdate,
+ },
},
}
diff --git a/docs/api-references/docs.md b/docs/api-references/docs.md
index 28ddc5c..8fdb0d8 100644
--- a/docs/api-references/docs.md
+++ b/docs/api-references/docs.md
@@ -114,6 +114,7 @@ _Appears in:_
| `rpcPort` _integer_ | RPCPort is the gRPC port of the datanode. | | Maximum: 65535
Minimum: 0
|
| `httpPort` _integer_ | HTTPPort is the HTTP port of the datanode. | | Maximum: 65535
Minimum: 0
|
| `storage` _[DatanodeStorageSpec](#datanodestoragespec)_ | Storage is the default file storage of the datanode. For example, WAL, cache, index etc. | | |
+| `rollingUpdate` _[RollingUpdateStatefulSetStrategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v/#rollingupdatestatefulsetstrategy-v1-apps)_ | RollingUpdate is the rolling update configuration. We always use `RollingUpdate` strategy. | | |
#### DatanodeStatus
@@ -193,6 +194,7 @@ _Appears in:_
| `template` _[PodTemplateSpec](#podtemplatespec)_ | Template defines the pod template for the component, if not specified, the pod template will use the default value. | | |
| `logging` _[LoggingSpec](#loggingspec)_ | Logging defines the logging configuration for the component. | | |
| `rpcPort` _integer_ | The gRPC port of the flownode. | | Maximum: 65535
Minimum: 0
|
+| `rollingUpdate` _[RollingUpdateStatefulSetStrategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v/#rollingupdatestatefulsetstrategy-v1-apps)_ | RollingUpdate is the rolling update configuration. We always use `RollingUpdate` strategy. | | |
#### FlownodeStatus
@@ -235,6 +237,7 @@ _Appears in:_
| `postgreSQLPort` _integer_ | PostgreSQLPort is the PostgreSQL port of the frontend. | | Maximum: 65535
Minimum: 0
|
| `service` _[ServiceSpec](#servicespec)_ | Service is the service configuration of the frontend. | | |
| `tls` _[TLSSpec](#tlsspec)_ | TLS is the TLS configuration of the frontend. | | |
+| `rollingUpdate` _[RollingUpdateDeployment](https://kubernetes.io/docs/reference/generated/kubernetes-api/v/#rollingupdatedeployment-v1-apps)_ | RollingUpdate is the rolling update configuration. We always use `RollingUpdate` strategyt. | | |
#### FrontendStatus
@@ -410,6 +413,7 @@ _Appears in:_
| `wal` _[WALProviderSpec](#walproviderspec)_ | WALProvider is the WAL provider for the greptimedb cluster. | | |
| `config` _string_ | The content of the configuration file of the component in TOML format. | | |
| `logging` _[LoggingSpec](#loggingspec)_ | Logging defines the logging configuration for the component. | | |
+| `rollingUpdate` _[RollingUpdateStatefulSetStrategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v/#rollingupdatestatefulsetstrategy-v1-apps)_ | RollingUpdate is the rolling update configuration. We always use `RollingUpdate` strategy. | | |
@@ -595,6 +599,7 @@ _Appears in:_
| `enableCheckEtcdService` _boolean_ | EnableCheckEtcdService indicates whether to check etcd cluster health when starting meta. | | |
| `enableRegionFailover` _boolean_ | EnableRegionFailover indicates whether to enable region failover. | | |
| `storeKeyPrefix` _string_ | StoreKeyPrefix is the prefix of the key in the etcd. We can use it to isolate the data of different clusters. | | |
+| `rollingUpdate` _[RollingUpdateDeployment](https://kubernetes.io/docs/reference/generated/kubernetes-api/v/#rollingupdatedeployment-v1-apps)_ | RollingUpdate is the rolling update configuration. We always use `RollingUpdate` strategyt. | | |
#### MetaStatus
diff --git a/manifests/bundle.yaml b/manifests/bundle.yaml
index c5ab69c..a1a8742 100644
--- a/manifests/bundle.yaml
+++ b/manifests/bundle.yaml
@@ -3072,6 +3072,17 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -6111,6 +6122,17 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -9143,6 +9165,19 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxSurge:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -12243,6 +12278,19 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxSurge:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -18367,6 +18415,17 @@ spec:
required:
- enabled
type: object
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -21875,6 +21934,17 @@ spec:
required:
- enabled
type: object
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
diff --git a/manifests/crds.yaml b/manifests/crds.yaml
index 7f3ae18..76a6573 100644
--- a/manifests/crds.yaml
+++ b/manifests/crds.yaml
@@ -3065,6 +3065,17 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -6104,6 +6115,17 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -9136,6 +9158,19 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxSurge:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -12236,6 +12271,19 @@ spec:
format: int32
minimum: 0
type: integer
+ rollingUpdate:
+ properties:
+ maxSurge:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -18360,6 +18408,17 @@ spec:
required:
- enabled
type: object
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535
@@ -21868,6 +21927,17 @@ spec:
required:
- enabled
type: object
+ rollingUpdate:
+ properties:
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ partition:
+ format: int32
+ type: integer
+ type: object
rpcPort:
format: int32
maximum: 65535