diff --git a/apis/apps/v1/deprecated.go b/apis/apps/v1/deprecated.go index e4be8f591a7..116d59510d3 100644 --- a/apis/apps/v1/deprecated.go +++ b/apis/apps/v1/deprecated.go @@ -23,7 +23,6 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" viper "github.com/apecloud/kubeblocks/pkg/viperx" ) @@ -217,7 +216,6 @@ func (t *InstanceTemplate) GetReplicas() int32 { return defaultInstanceTemplateReplicas } -// GetOrdinals TODO(free6om): Remove after resolving the circular dependencies between apps and workloads. -func (t *InstanceTemplate) GetOrdinals() workloads.Ordinals { - return workloads.Ordinals{} +func (t *InstanceTemplate) GetOrdinals() Ordinals { + return t.Ordinals } diff --git a/apis/apps/v1/types.go b/apis/apps/v1/types.go index 0cc99cfc120..902b0ecac59 100644 --- a/apis/apps/v1/types.go +++ b/apis/apps/v1/types.go @@ -591,7 +591,23 @@ type TLSSecretRef struct { Key string `json:"key"` } -// InstanceTemplate allows customization of individual replica configurations in a Component. +// Range represents a range with a start and an end value. +// It is used to define a continuous segment. +type Range struct { + Start int32 `json:"start"` + End int32 `json:"end"` +} + +// Ordinals represents a combination of continuous segments and individual values. +type Ordinals struct { + Ranges []Range `json:"ranges,omitempty"` + Discrete []int32 `json:"discrete,omitempty"` +} + +// InstanceTemplate allows customization of individual replica configurations within a Component, +// without altering the base component template defined in ClusterComponentSpec. +// It enables the application of distinct settings to specific instances (replicas), +// providing flexibility while maintaining a common configuration baseline. type InstanceTemplate struct { // Name specifies the unique name of the instance Pod created using this InstanceTemplate. // This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal @@ -613,6 +629,15 @@ type InstanceTemplate struct { // +optional Replicas *int32 `json:"replicas,omitempty"` + // Specifies the desired Ordinals of this InstanceTemplate. + // The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + // + // For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + // then the instance names generated under this InstanceTemplate would be + // $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + // $(cluster.name)-$(component.name)-$(template.name)-7 + Ordinals Ordinals `json:"ordinals,omitempty"` + // Specifies a map of key-value pairs to be merged into the Pod's existing annotations. // Existing keys will have their values overwritten, while new keys will be added to the annotations. // diff --git a/apis/apps/v1/zz_generated.deepcopy.go b/apis/apps/v1/zz_generated.deepcopy.go index 1e9b6d2c9df..4524d020a5e 100644 --- a/apis/apps/v1/zz_generated.deepcopy.go +++ b/apis/apps/v1/zz_generated.deepcopy.go @@ -2108,6 +2108,7 @@ func (in *InstanceTemplate) DeepCopyInto(out *InstanceTemplate) { *out = new(int32) **out = **in } + in.Ordinals.DeepCopyInto(&out.Ordinals) if in.Annotations != nil { in, out := &in.Annotations, &out.Annotations *out = make(map[string]string, len(*in)) @@ -2292,6 +2293,31 @@ func (in *NamedVar) DeepCopy() *NamedVar { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Ordinals) DeepCopyInto(out *Ordinals) { + *out = *in + if in.Ranges != nil { + in, out := &in.Ranges, &out.Ranges + *out = make([]Range, len(*in)) + copy(*out, *in) + } + if in.Discrete != nil { + in, out := &in.Discrete, &out.Discrete + *out = make([]int32, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ordinals. +func (in *Ordinals) DeepCopy() *Ordinals { + if in == nil { + return nil + } + out := new(Ordinals) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PasswordConfig) DeepCopyInto(out *PasswordConfig) { *out = *in @@ -2369,6 +2395,21 @@ func (in *ProvisionSecretRef) DeepCopy() *ProvisionSecretRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Range) DeepCopyInto(out *Range) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Range. +func (in *Range) DeepCopy() *Range { + if in == nil { + return nil + } + out := new(Range) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReplicaRole) DeepCopyInto(out *ReplicaRole) { *out = *in diff --git a/apis/workloads/v1/instanceset_types.go b/apis/workloads/v1/instanceset_types.go index 79895a8d7d9..d5bc3b92b39 100644 --- a/apis/workloads/v1/instanceset_types.go +++ b/apis/workloads/v1/instanceset_types.go @@ -24,6 +24,8 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" + + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) // +genclient @@ -306,150 +308,17 @@ type InstanceSetStatus struct { TemplatesStatus []InstanceTemplateStatus `json:"templatesStatus,omitempty"` } -// Range represents a range with a start and an end value. -// It is used to define a continuous segment. -type Range struct { - Start int32 `json:"start"` - End int32 `json:"end"` -} +// +kubebuilder:object:generate=false +type Range = kbappsv1.Range -// Ordinals represents a combination of continuous segments and individual values. -type Ordinals struct { - Ranges []Range `json:"ranges,omitempty"` - Discrete []int32 `json:"discrete,omitempty"` -} +// +kubebuilder:object:generate=false +type Ordinals = kbappsv1.Ordinals -// InstanceTemplate allows customization of individual replica configurations within a Component, -// without altering the base component template defined in ClusterComponentSpec. -// It enables the application of distinct settings to specific instances (replicas), -// providing flexibility while maintaining a common configuration baseline. -type InstanceTemplate struct { - // Name specifies the unique name of the instance Pod created using this InstanceTemplate. - // This name is constructed by concatenating the component's name, the template's name, and the instance's ordinal - // using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. - // The specified name overrides any default naming conventions or patterns. - // - // +kubebuilder:validation:MaxLength=54 - // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` - // +kubebuilder:validation:Required - Name string `json:"name"` +// +kubebuilder:object:generate=false +type InstanceTemplate = kbappsv1.InstanceTemplate - // Specifies the number of instances (Pods) to create from this InstanceTemplate. - // This field allows setting how many replicated instances of the component, - // with the specific overrides in the InstanceTemplate, are created. - // The default value is 1. A value of 0 disables instance creation. - // - // +kubebuilder:default=1 - // +kubebuilder:validation:Minimum=0 - // +optional - Replicas *int32 `json:"replicas,omitempty"` - - // Specifies the desired Ordinals of this InstanceTemplate. - // The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. - // - // For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, - // then the instance names generated under this InstanceTemplate would be - // $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and - // $(cluster.name)-$(component.name)-$(template.name)-7 - Ordinals Ordinals `json:"ordinals,omitempty"` - - // Specifies a map of key-value pairs to be merged into the Pod's existing annotations. - // Existing keys will have their values overwritten, while new keys will be added to the annotations. - // - // +optional - Annotations map[string]string `json:"annotations,omitempty"` - - // Specifies a map of key-value pairs that will be merged into the Pod's existing labels. - // Values for existing keys will be overwritten, and new keys will be added. - // - // +optional - Labels map[string]string `json:"labels,omitempty"` - - // Specifies an override for the first container's image in the pod. - // - // +optional - Image *string `json:"image,omitempty"` - - // Specifies the scheduling policy for the Component. - // - // +optional - SchedulingPolicy *SchedulingPolicy `json:"schedulingPolicy,omitempty"` - - // Specifies an override for the resource requirements of the first container in the Pod. - // This field allows for customizing resource allocation (CPU, memory, etc.) for the container. - // - // +optional - Resources *corev1.ResourceRequirements `json:"resources,omitempty"` - - // Defines Env to override. - // Add new or override existing envs. - // +optional - Env []corev1.EnvVar `json:"env,omitempty"` - - // Defines Volumes to override. - // Add new or override existing volumes. - // +optional - Volumes []corev1.Volume `json:"volumes,omitempty"` - - // Defines VolumeMounts to override. - // Add new or override existing volume mounts of the first container in the pod. - // +optional - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` - - // Defines VolumeClaimTemplates to override. - // Add new or override existing volume claim templates. - // +optional - VolumeClaimTemplates []corev1.PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty"` -} - -// SchedulingPolicy the scheduling policy. -// Deprecated: Unify with apps/v1alpha1.SchedulingPolicy -type SchedulingPolicy struct { - // If specified, the Pod will be dispatched by specified scheduler. - // If not specified, the Pod will be dispatched by default scheduler. - // - // +optional - SchedulerName string `json:"schedulerName,omitempty"` - - // NodeSelector is a selector which must be true for the Pod to fit on a node. - // Selector which must match a node's labels for the Pod to be scheduled on that node. - // More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - // - // +optional - // +mapType=atomic - NodeSelector map[string]string `json:"nodeSelector,omitempty"` - - // NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, - // the scheduler simply schedules this Pod onto that node, assuming that it fits resource - // requirements. - // - // +optional - NodeName string `json:"nodeName,omitempty"` - - // Specifies a group of affinity scheduling rules of the Cluster, including NodeAffinity, PodAffinity, and PodAntiAffinity. - // - // +optional - Affinity *corev1.Affinity `json:"affinity,omitempty"` - - // Allows Pods to be scheduled onto nodes with matching taints. - // Each toleration in the array allows the Pod to tolerate node taints based on - // specified `key`, `value`, `effect`, and `operator`. - // - // - The `key`, `value`, and `effect` identify the taint that the toleration matches. - // - The `operator` determines how the toleration matches the taint. - // - // Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. - // - // +optional - Tolerations []corev1.Toleration `json:"tolerations,omitempty"` - - // TopologySpreadConstraints describes how a group of Pods ought to spread across topology - // domains. Scheduler will schedule Pods in a way which abides by the constraints. - // All topologySpreadConstraints are ANDed. - // - // +optional - TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` -} +// +kubebuilder:object:generate=false +type SchedulingPolicy = kbappsv1.SchedulingPolicy type PodUpdatePolicyType string @@ -688,18 +557,3 @@ const ( ) const defaultInstanceTemplateReplicas = 1 - -func (t *InstanceTemplate) GetName() string { - return t.Name -} - -func (t *InstanceTemplate) GetReplicas() int32 { - if t.Replicas != nil { - return *t.Replicas - } - return defaultInstanceTemplateReplicas -} - -func (t *InstanceTemplate) GetOrdinals() Ordinals { - return t.Ordinals -} diff --git a/apis/workloads/v1/zz_generated.deepcopy.go b/apis/workloads/v1/zz_generated.deepcopy.go index 5c605826880..4c34a745cce 100644 --- a/apis/workloads/v1/zz_generated.deepcopy.go +++ b/apis/workloads/v1/zz_generated.deepcopy.go @@ -24,6 +24,7 @@ along with this program. If not, see . package v1 import ( + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" @@ -168,7 +169,7 @@ func (in *InstanceSetSpec) DeepCopyInto(out *InstanceSetSpec) { in.Template.DeepCopyInto(&out.Template) if in.Instances != nil { in, out := &in.Instances, &out.Instances - *out = make([]InstanceTemplate, len(*in)) + *out = make([]appsv1.InstanceTemplate, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -271,84 +272,6 @@ func (in *InstanceSetStatus) DeepCopy() *InstanceSetStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InstanceTemplate) DeepCopyInto(out *InstanceTemplate) { - *out = *in - if in.Replicas != nil { - in, out := &in.Replicas, &out.Replicas - *out = new(int32) - **out = **in - } - in.Ordinals.DeepCopyInto(&out.Ordinals) - if in.Annotations != nil { - in, out := &in.Annotations, &out.Annotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Image != nil { - in, out := &in.Image, &out.Image - *out = new(string) - **out = **in - } - if in.SchedulingPolicy != nil { - in, out := &in.SchedulingPolicy, &out.SchedulingPolicy - *out = new(SchedulingPolicy) - (*in).DeepCopyInto(*out) - } - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = new(corev1.ResourceRequirements) - (*in).DeepCopyInto(*out) - } - if in.Env != nil { - in, out := &in.Env, &out.Env - *out = make([]corev1.EnvVar, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes - *out = make([]corev1.Volume, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.VolumeMounts != nil { - in, out := &in.VolumeMounts, &out.VolumeMounts - *out = make([]corev1.VolumeMount, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.VolumeClaimTemplates != nil { - in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates - *out = make([]corev1.PersistentVolumeClaim, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceTemplate. -func (in *InstanceTemplate) DeepCopy() *InstanceTemplate { - if in == nil { - return nil - } - out := new(InstanceTemplate) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *InstanceTemplateStatus) DeepCopyInto(out *InstanceTemplateStatus) { *out = *in @@ -424,46 +347,6 @@ func (in *MembershipReconfiguration) DeepCopy() *MembershipReconfiguration { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Ordinals) DeepCopyInto(out *Ordinals) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]Range, len(*in)) - copy(*out, *in) - } - if in.Discrete != nil { - in, out := &in.Discrete, &out.Discrete - *out = make([]int32, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ordinals. -func (in *Ordinals) DeepCopy() *Ordinals { - if in == nil { - return nil - } - out := new(Ordinals) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Range) DeepCopyInto(out *Range) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Range. -func (in *Range) DeepCopy() *Range { - if in == nil { - return nil - } - out := new(Range) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReplicaRole) DeepCopyInto(out *ReplicaRole) { *out = *in @@ -478,44 +361,3 @@ func (in *ReplicaRole) DeepCopy() *ReplicaRole { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SchedulingPolicy) DeepCopyInto(out *SchedulingPolicy) { - *out = *in - if in.NodeSelector != nil { - in, out := &in.NodeSelector, &out.NodeSelector - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Affinity != nil { - in, out := &in.Affinity, &out.Affinity - *out = new(corev1.Affinity) - (*in).DeepCopyInto(*out) - } - if in.Tolerations != nil { - in, out := &in.Tolerations, &out.Tolerations - *out = make([]corev1.Toleration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.TopologySpreadConstraints != nil { - in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints - *out = make([]corev1.TopologySpreadConstraint, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SchedulingPolicy. -func (in *SchedulingPolicy) DeepCopy() *SchedulingPolicy { - if in == nil { - return nil - } - out := new(SchedulingPolicy) - in.DeepCopyInto(out) - return out -} diff --git a/config/crd/bases/apps.kubeblocks.io_clusters.yaml b/config/crd/bases/apps.kubeblocks.io_clusters.yaml index 2d4cc34c940..f89f108f011 100644 --- a/config/crd/bases/apps.kubeblocks.io_clusters.yaml +++ b/config/crd/bases/apps.kubeblocks.io_clusters.yaml @@ -426,8 +426,11 @@ spec: The sum of replicas across all InstanceTemplates should not exceed the total number of replicas specified for the Component. Any remaining replicas will be generated using the default template and will follow the default naming rules. items: - description: InstanceTemplate allows customization of individual - replica configurations in a Component. + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. properties: annotations: additionalProperties: @@ -573,6 +576,40 @@ spec: maxLength: 54 pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object replicas: default: 1 description: |- @@ -9066,8 +9103,11 @@ spec: The sum of replicas across all InstanceTemplates should not exceed the total number of replicas specified for the Component. Any remaining replicas will be generated using the default template and will follow the default naming rules. items: - description: InstanceTemplate allows customization of - individual replica configurations in a Component. + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. properties: annotations: additionalProperties: @@ -9216,6 +9256,40 @@ spec: maxLength: 54 pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object replicas: default: 1 description: |- diff --git a/config/crd/bases/apps.kubeblocks.io_components.yaml b/config/crd/bases/apps.kubeblocks.io_components.yaml index 9da4fd1e563..bc9052c0abc 100644 --- a/config/crd/bases/apps.kubeblocks.io_components.yaml +++ b/config/crd/bases/apps.kubeblocks.io_components.yaml @@ -309,8 +309,11 @@ spec: The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the Component. Any remaining replicas will be generated using the default template and will follow the default naming rules. items: - description: InstanceTemplate allows customization of individual - replica configurations in a Component. + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. properties: annotations: additionalProperties: @@ -455,6 +458,40 @@ spec: maxLength: 54 pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object replicas: default: 1 description: |- diff --git a/config/crd/bases/operations.kubeblocks.io_opsrequests.yaml b/config/crd/bases/operations.kubeblocks.io_opsrequests.yaml index 4dd1102ce19..8791b6f6567 100644 --- a/config/crd/bases/operations.kubeblocks.io_opsrequests.yaml +++ b/config/crd/bases/operations.kubeblocks.io_opsrequests.yaml @@ -643,8 +643,11 @@ spec: Defines the configuration for new instances added during scaling, including resource requirements, labels, annotations, etc. New instances are created based on the provided instance templates. items: - description: InstanceTemplate allows customization of - individual replica configurations in a Component. + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. properties: annotations: additionalProperties: @@ -793,6 +796,40 @@ spec: maxLength: 54 pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object replicas: default: 1 description: |- @@ -5167,8 +5204,11 @@ spec: description: Records the InstanceTemplate list of the Component prior to any changes. items: - description: InstanceTemplate allows customization of - individual replica configurations in a Component. + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. properties: annotations: additionalProperties: @@ -5317,6 +5357,40 @@ spec: maxLength: 54 pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object replicas: default: 1 description: |- diff --git a/config/crd/bases/workloads.kubeblocks.io_instancesets.yaml b/config/crd/bases/workloads.kubeblocks.io_instancesets.yaml index a8e587f9cda..2ba5d965990 100644 --- a/config/crd/bases/workloads.kubeblocks.io_instancesets.yaml +++ b/config/crd/bases/workloads.kubeblocks.io_instancesets.yaml @@ -462,7 +462,7 @@ spec: type: array image: description: Specifies an override for the first container's - image in the pod. + image in the Pod. type: string labels: additionalProperties: @@ -474,7 +474,7 @@ spec: name: description: |- Name specifies the unique name of the instance Pod created using this InstanceTemplate. - This name is constructed by concatenating the component's name, the template's name, and the instance's ordinal + This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. The specified name overrides any default naming conventions or patterns. maxLength: 54 @@ -518,7 +518,7 @@ spec: default: 1 description: |- Specifies the number of instances (Pods) to create from this InstanceTemplate. - This field allows setting how many replicated instances of the component, + This field allows setting how many replicated instances of the Component, with the specific overrides in the InstanceTemplate, are created. The default value is 1. A value of 0 disables instance creation. format: int32 @@ -1744,145 +1744,41 @@ spec: Defines VolumeClaimTemplates to override. Add new or override existing volume claim templates. items: - description: PersistentVolumeClaim is a user's request for - and claim to a persistent volume properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: + name: description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. type: string - metadata: - description: |- - Standard object's metadata. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object spec: description: |- - spec defines the desired characteristics of a volume requested by a pod author. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. properties: accessModes: description: |- - accessModes contains the desired access modes the volume should have. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. items: type: string type: array - dataSource: - description: |- - dataSource field can be used to specify either: - * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) - If the provisioner or an external controller can support the specified data source, - it will create a new volume based on the contents of the specified data source. - When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, - and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. - If the namespace is specified, then dataSourceRef will not be copied to dataSource. - properties: - apiGroup: - description: |- - APIGroup is the group for the resource being referenced. - If APIGroup is not specified, the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: |- - dataSourceRef specifies the object from which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty API group (non - core object) or a PersistentVolumeClaim object. - When this field is specified, volume binding will only succeed if the type of - the specified object matches some installed volume populator or dynamic - provisioner. - This field will replace the functionality of the dataSource field and as such - if both fields are non-empty, they must have the same value. For backwards - compatibility, when namespace isn't specified in dataSourceRef, - both fields (dataSource and dataSourceRef) will be set to the same - value automatically if one of them is empty and the other is non-empty. - When namespace is specified in dataSourceRef, - dataSource isn't set to the same value and must be empty. - There are three important differences between dataSource and dataSourceRef: - * While dataSource only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim objects. - * While dataSource ignores disallowed values (dropping them), dataSourceRef - preserves all values, and generates an error if a disallowed value is - specified. - * While dataSource only allows local objects, dataSourceRef allows objects - in any namespaces. - (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. - (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. - properties: - apiGroup: - description: |- - APIGroup is the group for the resource being referenced. - If APIGroup is not specified, the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - namespace: - description: |- - Namespace is the namespace of resource being referenced - Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. - (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. - type: string - required: - - kind - - name - type: object + x-kubernetes-preserve-unknown-fields: true resources: description: |- - resources represents the minimum resources the volume should have. - If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements - that are lower than previous value but must still be higher than capacity recorded in the - status field of the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. properties: limits: additionalProperties: @@ -1909,274 +1805,25 @@ spec: More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object - selector: - description: selector is a label query over volumes - to consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true storageClassName: description: |- - storageClassName is the name of the StorageClass required by the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 - type: string - volumeAttributesClassName: - description: |- - volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. - If specified, the CSI driver will create or update the volume with the attributes defined - in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, - it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass - will be applied to the claim but it's not allowed to reset this field to empty string once it is set. - If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass - will be set by the persistentvolume controller if it exists. - If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be - set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource - exists. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass - (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. type: string volumeMode: - description: |- - volumeMode defines what type of volume is required by the claim. - Value of Filesystem is implied when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference to - the PersistentVolume backing this claim. - type: string - type: object - status: - description: |- - status represents the current information/status of a persistent volume claim. - Read-only. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims - properties: - accessModes: - description: |- - accessModes contains the actual access modes the volume backing the PVC has. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 - items: - type: string - type: array - allocatedResourceStatuses: - additionalProperties: - description: |- - When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource - that it does not recognizes, then it should ignore that update and let other controllers - handle it. - type: string - description: "allocatedResourceStatuses stores status - of resource being resized for the given PVC.\nKey - names follow standard Kubernetes label syntax. Valid - values are either:\n\t* Un-prefixed keys:\n\t\t- - storage - the capacity of the volume.\n\t* Custom - resources must use implementation-defined prefixed - names such as \"example.com/my-custom-resource\"\nApart - from above values - keys that are unprefixed or - have kubernetes.io prefix are considered\nreserved - and hence may not be used.\n\n\nClaimResourceStatus - can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState - set when resize controller starts resizing the volume - in control-plane.\n\t- ControllerResizeFailed:\n\t\tState - set when resize has failed in resize controller - with a terminal error.\n\t- NodeResizePending:\n\t\tState - set when resize controller has finished resizing - the volume but further resizing of\n\t\tvolume is - needed on the node.\n\t- NodeResizeInProgress:\n\t\tState - set when kubelet starts resizing the volume.\n\t- - NodeResizeFailed:\n\t\tState set when resizing has - failed in kubelet with a terminal error. Transient - errors don't set\n\t\tNodeResizeFailed.\nFor example: - if expanding a PVC for more capacity - this field - can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] - = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] - = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] - = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] - = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] - = \"NodeResizeFailed\"\nWhen this field is not set, - it means that no resize operation is in progress - for the given PVC.\n\n\nA controller that receives - PVC update with previously unknown resourceName - or ClaimResourceStatus\nshould ignore the update - for the purpose it was designed. For example - a - controller that\nonly is responsible for resizing - capacity of the volume, should ignore PVC updates - that change other valid\nresources associated with - PVC.\n\n\nThis is an alpha field and requires enabling - RecoverVolumeExpansionFailure feature." - type: object - x-kubernetes-map-type: granular - allocatedResources: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: "allocatedResources tracks the resources - allocated to a PVC including its capacity.\nKey - names follow standard Kubernetes label syntax. Valid - values are either:\n\t* Un-prefixed keys:\n\t\t- - storage - the capacity of the volume.\n\t* Custom - resources must use implementation-defined prefixed - names such as \"example.com/my-custom-resource\"\nApart - from above values - keys that are unprefixed or - have kubernetes.io prefix are considered\nreserved - and hence may not be used.\n\n\nCapacity reported - here may be larger than the actual capacity when - a volume expansion operation\nis requested.\nFor - storage quota, the larger value from allocatedResources - and PVC.spec.resources is used.\nIf allocatedResources - is not set, PVC.spec.resources alone is used for - quota calculation.\nIf a volume expansion capacity - request is lowered, allocatedResources is only\nlowered - if there are no expansion operations in progress - and if the actual volume capacity\nis equal or lower - than the requested capacity.\n\n\nA controller that - receives PVC update with previously unknown resourceName\nshould - ignore the update for the purpose it was designed. - For example - a controller that\nonly is responsible - for resizing capacity of the volume, should ignore - PVC updates that change other valid\nresources associated - with PVC.\n\n\nThis is an alpha field and requires - enabling RecoverVolumeExpansionFailure feature." - type: object - capacity: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: capacity represents the actual resources - of the underlying volume. - type: object - conditions: - description: |- - conditions is the current Condition of persistent volume claim. If underlying persistent volume is being - resized then the Condition will be set to 'ResizeStarted'. - items: - description: PersistentVolumeClaimCondition contains - details about state of pvc - properties: - lastProbeTime: - description: lastProbeTime is the time we probed - the condition. - format: date-time - type: string - lastTransitionTime: - description: lastTransitionTime is the time - the condition transitioned from one status - to another. - format: date-time - type: string - message: - description: message is the human-readable message - indicating details about last transition. - type: string - reason: - description: |- - reason is a unique, this should be a short, machine understandable string that gives the reason - for condition's last transition. If it reports "ResizeStarted" that means the underlying - persistent volume is being resized. - type: string - status: - type: string - type: - description: PersistentVolumeClaimConditionType - is a valid value of PersistentVolumeClaimCondition.Type - type: string - required: - - status - - type - type: object - type: array - currentVolumeAttributesClassName: - description: |- - currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. - When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim - This is an alpha field and requires enabling VolumeAttributesClass feature. - type: string - modifyVolumeStatus: - description: |- - ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. - When this is unset, there is no ModifyVolume operation being attempted. - This is an alpha field and requires enabling VolumeAttributesClass feature. - properties: - status: - description: "status is the status of the ControllerModifyVolume - operation. It can be in any of following states:\n - - Pending\n Pending indicates that the PersistentVolumeClaim - cannot be modified due to unmet requirements, - such as\n the specified VolumeAttributesClass - not existing.\n - InProgress\n InProgress - indicates that the volume is being modified.\n - - Infeasible\n Infeasible indicates that the - request has been rejected as invalid by the - CSI driver. To\n\t resolve the error, a valid - VolumeAttributesClass needs to be specified.\nNote: - New statuses can be added in the future. Consumers - should check for unknown statuses and fail appropriately." - type: string - targetVolumeAttributesClassName: - description: targetVolumeAttributesClassName is - the name of the VolumeAttributesClass the PVC - currently being reconciled - type: string - required: - - status - type: object - phase: - description: phase represents the current phase of - PersistentVolumeClaim. + description: Defines what type of volume is required + by the claim, either Block or Filesystem. type: string type: object + required: + - name type: object type: array volumeMounts: description: |- Defines VolumeMounts to override. - Add new or override existing volume mounts of the first container in the pod. + Add new or override existing volume mounts of the first container in the Pod. items: description: VolumeMount describes a mounting of a Volume within a container. diff --git a/controllers/apps/transformer_component_workload.go b/controllers/apps/transformer_component_workload.go index d4172c52ea3..c8796186692 100644 --- a/controllers/apps/transformer_component_workload.go +++ b/controllers/apps/transformer_component_workload.go @@ -542,7 +542,8 @@ func (r *componentWorkloadOps) expandVolume() error { for i := range r.runningITS.Spec.Instances { runningInsSpec := r.runningITS.Spec.DeepCopy() runningInsTPL := runningInsSpec.Instances[i] - intctrlutil.MergeList(&runningInsTPL.VolumeClaimTemplates, &runningInsSpec.VolumeClaimTemplates, + vcts := intctrlutil.ConvertAppsV1PersistentVolumeClaimsToCoreV1(runningInsTPL.VolumeClaimTemplates) + intctrlutil.MergeList(&vcts, &runningInsSpec.VolumeClaimTemplates, func(item corev1.PersistentVolumeClaim) func(corev1.PersistentVolumeClaim) bool { return func(claim corev1.PersistentVolumeClaim) bool { return claim.Name == item.Name diff --git a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml index 2d4cc34c940..f89f108f011 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml @@ -426,8 +426,11 @@ spec: The sum of replicas across all InstanceTemplates should not exceed the total number of replicas specified for the Component. Any remaining replicas will be generated using the default template and will follow the default naming rules. items: - description: InstanceTemplate allows customization of individual - replica configurations in a Component. + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. properties: annotations: additionalProperties: @@ -573,6 +576,40 @@ spec: maxLength: 54 pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object replicas: default: 1 description: |- @@ -9066,8 +9103,11 @@ spec: The sum of replicas across all InstanceTemplates should not exceed the total number of replicas specified for the Component. Any remaining replicas will be generated using the default template and will follow the default naming rules. items: - description: InstanceTemplate allows customization of - individual replica configurations in a Component. + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. properties: annotations: additionalProperties: @@ -9216,6 +9256,40 @@ spec: maxLength: 54 pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object replicas: default: 1 description: |- diff --git a/deploy/helm/crds/apps.kubeblocks.io_components.yaml b/deploy/helm/crds/apps.kubeblocks.io_components.yaml index 9da4fd1e563..bc9052c0abc 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_components.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_components.yaml @@ -309,8 +309,11 @@ spec: The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the Component. Any remaining replicas will be generated using the default template and will follow the default naming rules. items: - description: InstanceTemplate allows customization of individual - replica configurations in a Component. + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. properties: annotations: additionalProperties: @@ -455,6 +458,40 @@ spec: maxLength: 54 pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object replicas: default: 1 description: |- diff --git a/deploy/helm/crds/operations.kubeblocks.io_opsrequests.yaml b/deploy/helm/crds/operations.kubeblocks.io_opsrequests.yaml index 4dd1102ce19..8791b6f6567 100755 --- a/deploy/helm/crds/operations.kubeblocks.io_opsrequests.yaml +++ b/deploy/helm/crds/operations.kubeblocks.io_opsrequests.yaml @@ -643,8 +643,11 @@ spec: Defines the configuration for new instances added during scaling, including resource requirements, labels, annotations, etc. New instances are created based on the provided instance templates. items: - description: InstanceTemplate allows customization of - individual replica configurations in a Component. + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. properties: annotations: additionalProperties: @@ -793,6 +796,40 @@ spec: maxLength: 54 pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object replicas: default: 1 description: |- @@ -5167,8 +5204,11 @@ spec: description: Records the InstanceTemplate list of the Component prior to any changes. items: - description: InstanceTemplate allows customization of - individual replica configurations in a Component. + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. properties: annotations: additionalProperties: @@ -5317,6 +5357,40 @@ spec: maxLength: 54 pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object replicas: default: 1 description: |- diff --git a/deploy/helm/crds/workloads.kubeblocks.io_instancesets.yaml b/deploy/helm/crds/workloads.kubeblocks.io_instancesets.yaml index a8e587f9cda..2ba5d965990 100644 --- a/deploy/helm/crds/workloads.kubeblocks.io_instancesets.yaml +++ b/deploy/helm/crds/workloads.kubeblocks.io_instancesets.yaml @@ -462,7 +462,7 @@ spec: type: array image: description: Specifies an override for the first container's - image in the pod. + image in the Pod. type: string labels: additionalProperties: @@ -474,7 +474,7 @@ spec: name: description: |- Name specifies the unique name of the instance Pod created using this InstanceTemplate. - This name is constructed by concatenating the component's name, the template's name, and the instance's ordinal + This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. The specified name overrides any default naming conventions or patterns. maxLength: 54 @@ -518,7 +518,7 @@ spec: default: 1 description: |- Specifies the number of instances (Pods) to create from this InstanceTemplate. - This field allows setting how many replicated instances of the component, + This field allows setting how many replicated instances of the Component, with the specific overrides in the InstanceTemplate, are created. The default value is 1. A value of 0 disables instance creation. format: int32 @@ -1744,145 +1744,41 @@ spec: Defines VolumeClaimTemplates to override. Add new or override existing volume claim templates. items: - description: PersistentVolumeClaim is a user's request for - and claim to a persistent volume properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: + name: description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. type: string - metadata: - description: |- - Standard object's metadata. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object spec: description: |- - spec defines the desired characteristics of a volume requested by a pod author. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. properties: accessModes: description: |- - accessModes contains the desired access modes the volume should have. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. items: type: string type: array - dataSource: - description: |- - dataSource field can be used to specify either: - * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) - If the provisioner or an external controller can support the specified data source, - it will create a new volume based on the contents of the specified data source. - When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, - and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. - If the namespace is specified, then dataSourceRef will not be copied to dataSource. - properties: - apiGroup: - description: |- - APIGroup is the group for the resource being referenced. - If APIGroup is not specified, the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: |- - dataSourceRef specifies the object from which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty API group (non - core object) or a PersistentVolumeClaim object. - When this field is specified, volume binding will only succeed if the type of - the specified object matches some installed volume populator or dynamic - provisioner. - This field will replace the functionality of the dataSource field and as such - if both fields are non-empty, they must have the same value. For backwards - compatibility, when namespace isn't specified in dataSourceRef, - both fields (dataSource and dataSourceRef) will be set to the same - value automatically if one of them is empty and the other is non-empty. - When namespace is specified in dataSourceRef, - dataSource isn't set to the same value and must be empty. - There are three important differences between dataSource and dataSourceRef: - * While dataSource only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim objects. - * While dataSource ignores disallowed values (dropping them), dataSourceRef - preserves all values, and generates an error if a disallowed value is - specified. - * While dataSource only allows local objects, dataSourceRef allows objects - in any namespaces. - (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. - (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. - properties: - apiGroup: - description: |- - APIGroup is the group for the resource being referenced. - If APIGroup is not specified, the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - namespace: - description: |- - Namespace is the namespace of resource being referenced - Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. - (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. - type: string - required: - - kind - - name - type: object + x-kubernetes-preserve-unknown-fields: true resources: description: |- - resources represents the minimum resources the volume should have. - If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements - that are lower than previous value but must still be higher than capacity recorded in the - status field of the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. properties: limits: additionalProperties: @@ -1909,274 +1805,25 @@ spec: More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object - selector: - description: selector is a label query over volumes - to consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true storageClassName: description: |- - storageClassName is the name of the StorageClass required by the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 - type: string - volumeAttributesClassName: - description: |- - volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. - If specified, the CSI driver will create or update the volume with the attributes defined - in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, - it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass - will be applied to the claim but it's not allowed to reset this field to empty string once it is set. - If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass - will be set by the persistentvolume controller if it exists. - If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be - set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource - exists. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass - (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. type: string volumeMode: - description: |- - volumeMode defines what type of volume is required by the claim. - Value of Filesystem is implied when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference to - the PersistentVolume backing this claim. - type: string - type: object - status: - description: |- - status represents the current information/status of a persistent volume claim. - Read-only. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims - properties: - accessModes: - description: |- - accessModes contains the actual access modes the volume backing the PVC has. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 - items: - type: string - type: array - allocatedResourceStatuses: - additionalProperties: - description: |- - When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource - that it does not recognizes, then it should ignore that update and let other controllers - handle it. - type: string - description: "allocatedResourceStatuses stores status - of resource being resized for the given PVC.\nKey - names follow standard Kubernetes label syntax. Valid - values are either:\n\t* Un-prefixed keys:\n\t\t- - storage - the capacity of the volume.\n\t* Custom - resources must use implementation-defined prefixed - names such as \"example.com/my-custom-resource\"\nApart - from above values - keys that are unprefixed or - have kubernetes.io prefix are considered\nreserved - and hence may not be used.\n\n\nClaimResourceStatus - can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState - set when resize controller starts resizing the volume - in control-plane.\n\t- ControllerResizeFailed:\n\t\tState - set when resize has failed in resize controller - with a terminal error.\n\t- NodeResizePending:\n\t\tState - set when resize controller has finished resizing - the volume but further resizing of\n\t\tvolume is - needed on the node.\n\t- NodeResizeInProgress:\n\t\tState - set when kubelet starts resizing the volume.\n\t- - NodeResizeFailed:\n\t\tState set when resizing has - failed in kubelet with a terminal error. Transient - errors don't set\n\t\tNodeResizeFailed.\nFor example: - if expanding a PVC for more capacity - this field - can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] - = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] - = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] - = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] - = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] - = \"NodeResizeFailed\"\nWhen this field is not set, - it means that no resize operation is in progress - for the given PVC.\n\n\nA controller that receives - PVC update with previously unknown resourceName - or ClaimResourceStatus\nshould ignore the update - for the purpose it was designed. For example - a - controller that\nonly is responsible for resizing - capacity of the volume, should ignore PVC updates - that change other valid\nresources associated with - PVC.\n\n\nThis is an alpha field and requires enabling - RecoverVolumeExpansionFailure feature." - type: object - x-kubernetes-map-type: granular - allocatedResources: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: "allocatedResources tracks the resources - allocated to a PVC including its capacity.\nKey - names follow standard Kubernetes label syntax. Valid - values are either:\n\t* Un-prefixed keys:\n\t\t- - storage - the capacity of the volume.\n\t* Custom - resources must use implementation-defined prefixed - names such as \"example.com/my-custom-resource\"\nApart - from above values - keys that are unprefixed or - have kubernetes.io prefix are considered\nreserved - and hence may not be used.\n\n\nCapacity reported - here may be larger than the actual capacity when - a volume expansion operation\nis requested.\nFor - storage quota, the larger value from allocatedResources - and PVC.spec.resources is used.\nIf allocatedResources - is not set, PVC.spec.resources alone is used for - quota calculation.\nIf a volume expansion capacity - request is lowered, allocatedResources is only\nlowered - if there are no expansion operations in progress - and if the actual volume capacity\nis equal or lower - than the requested capacity.\n\n\nA controller that - receives PVC update with previously unknown resourceName\nshould - ignore the update for the purpose it was designed. - For example - a controller that\nonly is responsible - for resizing capacity of the volume, should ignore - PVC updates that change other valid\nresources associated - with PVC.\n\n\nThis is an alpha field and requires - enabling RecoverVolumeExpansionFailure feature." - type: object - capacity: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: capacity represents the actual resources - of the underlying volume. - type: object - conditions: - description: |- - conditions is the current Condition of persistent volume claim. If underlying persistent volume is being - resized then the Condition will be set to 'ResizeStarted'. - items: - description: PersistentVolumeClaimCondition contains - details about state of pvc - properties: - lastProbeTime: - description: lastProbeTime is the time we probed - the condition. - format: date-time - type: string - lastTransitionTime: - description: lastTransitionTime is the time - the condition transitioned from one status - to another. - format: date-time - type: string - message: - description: message is the human-readable message - indicating details about last transition. - type: string - reason: - description: |- - reason is a unique, this should be a short, machine understandable string that gives the reason - for condition's last transition. If it reports "ResizeStarted" that means the underlying - persistent volume is being resized. - type: string - status: - type: string - type: - description: PersistentVolumeClaimConditionType - is a valid value of PersistentVolumeClaimCondition.Type - type: string - required: - - status - - type - type: object - type: array - currentVolumeAttributesClassName: - description: |- - currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. - When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim - This is an alpha field and requires enabling VolumeAttributesClass feature. - type: string - modifyVolumeStatus: - description: |- - ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. - When this is unset, there is no ModifyVolume operation being attempted. - This is an alpha field and requires enabling VolumeAttributesClass feature. - properties: - status: - description: "status is the status of the ControllerModifyVolume - operation. It can be in any of following states:\n - - Pending\n Pending indicates that the PersistentVolumeClaim - cannot be modified due to unmet requirements, - such as\n the specified VolumeAttributesClass - not existing.\n - InProgress\n InProgress - indicates that the volume is being modified.\n - - Infeasible\n Infeasible indicates that the - request has been rejected as invalid by the - CSI driver. To\n\t resolve the error, a valid - VolumeAttributesClass needs to be specified.\nNote: - New statuses can be added in the future. Consumers - should check for unknown statuses and fail appropriately." - type: string - targetVolumeAttributesClassName: - description: targetVolumeAttributesClassName is - the name of the VolumeAttributesClass the PVC - currently being reconciled - type: string - required: - - status - type: object - phase: - description: phase represents the current phase of - PersistentVolumeClaim. + description: Defines what type of volume is required + by the claim, either Block or Filesystem. type: string type: object + required: + - name type: object type: array volumeMounts: description: |- Defines VolumeMounts to override. - Add new or override existing volume mounts of the first container in the pod. + Add new or override existing volume mounts of the first container in the Pod. items: description: VolumeMount describes a mounting of a Volume within a container. diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index eebf2a02817..4a14bc8e6a4 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -7747,10 +7747,9 @@ ContainerVars

InstanceTemplate

-(Appears on:ClusterComponentSpec, ComponentSpec) +(Appears on:ClusterComponentSpec, ComponentSpec, InstanceSetSpec)

-

InstanceTemplate allows customization of individual replica configurations in a Component.

@@ -7791,6 +7790,24 @@ The default value is 1. A value of 0 disables instance creation.

+ + + +
+ordinals
+ + +Ordinals + + +
+

Specifies the desired Ordinals of this InstanceTemplate. +The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate.

+

For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, +then the instance names generated under this InstanceTemplate would be +$(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and +$(cluster.name)-$(component.name)-$(template.name)-7

+
annotations
map[string]string @@ -8324,6 +8341,45 @@ VarOption
+

Ordinals +

+

+(Appears on:InstanceTemplate, InstanceSetSpec) +

+
+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ranges
+ + +[]Range + + +
+
+discrete
+ +[]int32 + +
+

PasswordConfig

@@ -8698,6 +8754,43 @@ string +

Range +

+

+(Appears on:Ordinals) +

+
+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+start
+ +int32 + +
+
+end
+ +int32 + +
+

ReplicaRole

@@ -28738,7 +28831,7 @@ Defaults to 1 if unspecified.

defaultTemplateOrdinals
- + Ordinals @@ -28796,7 +28889,7 @@ Kubernetes core/v1.PodTemplateSpec instances
- + []InstanceTemplate @@ -29255,7 +29348,7 @@ Defaults to 1 if unspecified.

defaultTemplateOrdinals
- + Ordinals @@ -29313,7 +29406,7 @@ Kubernetes core/v1.PodTemplateSpec instances
- + []InstanceTemplate @@ -29748,201 +29841,6 @@ key is the pod name, value is the revision.

-

InstanceTemplate -

-

-(Appears on:InstanceSetSpec) -

-
-

InstanceTemplate allows customization of individual replica configurations within a Component, -without altering the base component template defined in ClusterComponentSpec. -It enables the application of distinct settings to specific instances (replicas), -providing flexibility while maintaining a common configuration baseline.

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldDescription
-name
- -string - -
-

Name specifies the unique name of the instance Pod created using this InstanceTemplate. -This name is constructed by concatenating the component’s name, the template’s name, and the instance’s ordinal -using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. -The specified name overrides any default naming conventions or patterns.

-
-replicas
- -int32 - -
-(Optional) -

Specifies the number of instances (Pods) to create from this InstanceTemplate. -This field allows setting how many replicated instances of the component, -with the specific overrides in the InstanceTemplate, are created. -The default value is 1. A value of 0 disables instance creation.

-
-ordinals
- - -Ordinals - - -
-

Specifies the desired Ordinals of this InstanceTemplate. -The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate.

-

For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, -then the instance names generated under this InstanceTemplate would be -$(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and -$(cluster.name)-$(component.name)-$(template.name)-7

-
-annotations
- -map[string]string - -
-(Optional) -

Specifies a map of key-value pairs to be merged into the Pod’s existing annotations. -Existing keys will have their values overwritten, while new keys will be added to the annotations.

-
-labels
- -map[string]string - -
-(Optional) -

Specifies a map of key-value pairs that will be merged into the Pod’s existing labels. -Values for existing keys will be overwritten, and new keys will be added.

-
-image
- -string - -
-(Optional) -

Specifies an override for the first container’s image in the pod.

-
-schedulingPolicy
- - -SchedulingPolicy - - -
-(Optional) -

Specifies the scheduling policy for the Component.

-
-resources
- - -Kubernetes core/v1.ResourceRequirements - - -
-(Optional) -

Specifies an override for the resource requirements of the first container in the Pod. -This field allows for customizing resource allocation (CPU, memory, etc.) for the container.

-
-env
- - -[]Kubernetes core/v1.EnvVar - - -
-(Optional) -

Defines Env to override. -Add new or override existing envs.

-
-volumes
- - -[]Kubernetes core/v1.Volume - - -
-(Optional) -

Defines Volumes to override. -Add new or override existing volumes.

-
-volumeMounts
- - -[]Kubernetes core/v1.VolumeMount - - -
-(Optional) -

Defines VolumeMounts to override. -Add new or override existing volume mounts of the first container in the pod.

-
-volumeClaimTemplates
- - -[]Kubernetes core/v1.PersistentVolumeClaim - - -
-(Optional) -

Defines VolumeClaimTemplates to override. -Add new or override existing volume claim templates.

-

InstanceTemplateStatus

@@ -30196,46 +30094,6 @@ If the Image is not configured, the Image from the previous non-nil action will -

Ordinals -

-

-(Appears on:InstanceSetSpec, InstanceTemplate) -

-
-

Ordinals represents a combination of continuous segments and individual values.

-
- - - - - - - - - - - - - - - - - -
FieldDescription
-ranges
- - -[]Range - - -
-
-discrete
- -[]int32 - -
-

PodUpdatePolicyType (string alias)

@@ -30260,45 +30118,6 @@ Any attempt to modify other fields will be rejected.

-

Range -

-

-(Appears on:Ordinals) -

-
-

Range represents a range with a start and an end value. -It is used to define a continuous segment.

-
- - - - - - - - - - - - - - - - - -
FieldDescription
-start
- -int32 - -
-
-end
- -int32 - -
-

ReplicaRole

@@ -30382,117 +30201,6 @@ bool -

SchedulingPolicy -

-

-(Appears on:InstanceTemplate) -

-
-

SchedulingPolicy the scheduling policy. -Deprecated: Unify with apps/v1alpha1.SchedulingPolicy

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldDescription
-schedulerName
- -string - -
-(Optional) -

If specified, the Pod will be dispatched by specified scheduler. -If not specified, the Pod will be dispatched by default scheduler.

-
-nodeSelector
- -map[string]string - -
-(Optional) -

NodeSelector is a selector which must be true for the Pod to fit on a node. -Selector which must match a node’s labels for the Pod to be scheduled on that node. -More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

-
-nodeName
- -string - -
-(Optional) -

NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, -the scheduler simply schedules this Pod onto that node, assuming that it fits resource -requirements.

-
-affinity
- - -Kubernetes core/v1.Affinity - - -
-(Optional) -

Specifies a group of affinity scheduling rules of the Cluster, including NodeAffinity, PodAffinity, and PodAntiAffinity.

-
-tolerations
- - -[]Kubernetes core/v1.Toleration - - -
-(Optional) -

Allows Pods to be scheduled onto nodes with matching taints. -Each toleration in the array allows the Pod to tolerate node taints based on -specified key, value, effect, and operator.

-
    -
  • The key, value, and effect identify the taint that the toleration matches.
  • -
  • The operator determines how the toleration matches the taint.
  • -
-

Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes.

-
-topologySpreadConstraints
- - -[]Kubernetes core/v1.TopologySpreadConstraint - - -
-(Optional) -

TopologySpreadConstraints describes how a group of Pods ought to spread across topology -domains. Scheduler will schedule Pods in a way which abides by the constraints. -All topologySpreadConstraints are ANDed.

-

workloads.kubeblocks.io/v1alpha1

diff --git a/pkg/controller/component/its_convertor.go b/pkg/controller/component/its_convertor.go index af8af9b5d16..24697157335 100644 --- a/pkg/controller/component/its_convertor.go +++ b/pkg/controller/component/its_convertor.go @@ -24,13 +24,11 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" - viper "github.com/apecloud/kubeblocks/pkg/viperx" ) // BuildWorkloadFrom builds a new Component object based on SynthesizedComponent. @@ -209,37 +207,10 @@ func AppsInstanceToWorkloadInstance(instance *kbappsv1.InstanceTemplate) *worklo Env: instance.Env, Volumes: instance.Volumes, VolumeMounts: instance.VolumeMounts, - VolumeClaimTemplates: toPersistentVolumeClaims(instance.VolumeClaimTemplates), + VolumeClaimTemplates: instance.VolumeClaimTemplates, } } -func toPersistentVolumeClaims(vcts []kbappsv1.ClusterComponentVolumeClaimTemplate) []corev1.PersistentVolumeClaim { - storageClassName := func(spec kbappsv1.PersistentVolumeClaimSpec, defaultStorageClass string) *string { - if spec.StorageClassName != nil && *spec.StorageClassName != "" { - return spec.StorageClassName - } - if defaultStorageClass != "" { - return &defaultStorageClass - } - return nil - } - var pvcs []corev1.PersistentVolumeClaim - for _, v := range vcts { - pvcs = append(pvcs, corev1.PersistentVolumeClaim{ - ObjectMeta: metav1.ObjectMeta{ - Name: v.Name, - }, - Spec: corev1.PersistentVolumeClaimSpec{ - AccessModes: v.Spec.AccessModes, - Resources: v.Spec.Resources, - StorageClassName: storageClassName(v.Spec, viper.GetString(constant.CfgKeyDefaultStorageClass)), - VolumeMode: v.Spec.VolumeMode, - }, - }) - } - return pvcs -} - // parseITSConvertorArgs parses the args of ITS convertor. func parseITSConvertorArgs(args ...any) (*SynthesizedComponent, error) { synthesizeComp, ok := args[0].(*SynthesizedComponent) diff --git a/pkg/controller/instanceset/instance_util.go b/pkg/controller/instanceset/instance_util.go index 750da4ab900..d95d3c5a8db 100644 --- a/pkg/controller/instanceset/instance_util.go +++ b/pkg/controller/instanceset/instance_util.go @@ -956,7 +956,8 @@ func buildInstanceTemplateExt(template workloads.InstanceTemplate, templateExt * return vm.Name == item.Name } }) - intctrlutil.MergeList(&template.VolumeClaimTemplates, &templateExt.VolumeClaimTemplates, + vcts := intctrlutil.ConvertAppsV1PersistentVolumeClaimsToCoreV1(template.VolumeClaimTemplates) + intctrlutil.MergeList(&vcts, &templateExt.VolumeClaimTemplates, func(item corev1.PersistentVolumeClaim) func(corev1.PersistentVolumeClaim) bool { return func(claim corev1.PersistentVolumeClaim) bool { return claim.Name == item.Name diff --git a/pkg/controllerutil/cluster_utils.go b/pkg/controllerutil/cluster_utils.go index ff779d1daf2..21be3575a19 100644 --- a/pkg/controllerutil/cluster_utils.go +++ b/pkg/controllerutil/cluster_utils.go @@ -22,9 +22,13 @@ package controllerutil import ( "context" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + "github.com/apecloud/kubeblocks/pkg/constant" + viper "github.com/apecloud/kubeblocks/pkg/viperx" ) func GetComponentSpecByName(ctx context.Context, cli client.Reader, @@ -47,3 +51,30 @@ func GetComponentSpecByName(ctx context.Context, cli client.Reader, } return nil, nil } + +func ConvertAppsV1PersistentVolumeClaimsToCoreV1(vcts []appsv1.ClusterComponentVolumeClaimTemplate) []corev1.PersistentVolumeClaim { + storageClassName := func(spec appsv1.PersistentVolumeClaimSpec, defaultStorageClass string) *string { + if spec.StorageClassName != nil && *spec.StorageClassName != "" { + return spec.StorageClassName + } + if defaultStorageClass != "" { + return &defaultStorageClass + } + return nil + } + var pvcs []corev1.PersistentVolumeClaim + for _, v := range vcts { + pvcs = append(pvcs, corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: v.Name, + }, + Spec: corev1.PersistentVolumeClaimSpec{ + AccessModes: v.Spec.AccessModes, + Resources: v.Spec.Resources, + StorageClassName: storageClassName(v.Spec, viper.GetString(constant.CfgKeyDefaultStorageClass)), + VolumeMode: v.Spec.VolumeMode, + }, + }) + } + return pvcs +}