Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support RollingUpdate #8577

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
11 changes: 2 additions & 9 deletions apis/apps/v1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,17 +426,10 @@ type ClusterComponentSpec struct {
// +optional
ParallelPodManagementConcurrency *intstr.IntOrString `json:"parallelPodManagementConcurrency,omitempty"`

// PodUpdatePolicy indicates how pods should be updated
// Provides fine-grained control over the spec update process of all instances.
//
// - `StrictInPlace` indicates that only allows in-place upgrades.
// Any attempt to modify other fields will be rejected.
// - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod.
// If that fails, it will fall back to the ReCreate, where pod will be recreated.
// Default value is "PreferInPlace"
//
// +kubebuilder:validation:Enum={StrictInPlace,PreferInPlace}
// +optional
PodUpdatePolicy *PodUpdatePolicyType `json:"podUpdatePolicy,omitempty"`
UpdateStrategy *UpdateStrategy `json:"updateStrategy,omitempty"`

// Allows for the customization of configuration values for each instance within a Component.
// An instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps).
Expand Down
16 changes: 5 additions & 11 deletions apis/apps/v1/component_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,24 +189,18 @@ type ComponentSpec struct {
// +optional
ServiceAccountName string `json:"serviceAccountName,omitempty"`

// Provides fine-grained control over the spec update process of all instances.
//
// +optional
UpdateStrategy *UpdateStrategy `json:"updateStrategy,omitempty"`

// Controls the concurrency of pods during initial scale up, when replacing pods on nodes,
// or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`.
// The default Concurrency is 100%.
//
// +optional
ParallelPodManagementConcurrency *intstr.IntOrString `json:"parallelPodManagementConcurrency,omitempty"`

// PodUpdatePolicy indicates how pods should be updated
//
// - `StrictInPlace` indicates that only allows in-place upgrades.
// Any attempt to modify other fields will be rejected.
// - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod.
// If that fails, it will fall back to the ReCreate, where pod will be recreated.
// Default value is "PreferInPlace"
//
// +optional
PodUpdatePolicy *PodUpdatePolicyType `json:"podUpdatePolicy,omitempty"`

// Specifies the scheduling policy for the Component.
//
// +optional
Expand Down
51 changes: 9 additions & 42 deletions apis/apps/v1/componentdefinition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,23 +444,24 @@ type ComponentDefinitionSpec struct {
// +optional
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`

// Specifies the concurrency strategy for updating multiple instances of the Component.
// Available strategies:
// Specifies the concurrency level for updating instances during a rolling update.
// Available levels:
//
// - `Serial`: Updates replicas one at a time, ensuring minimal downtime by waiting for each replica to become ready
// - `Serial`: Updates instances one at a time, ensuring minimal downtime by waiting for each instance to become ready
// before updating the next.
// - `Parallel`: Updates all replicas simultaneously, optimizing for speed but potentially reducing availability
// - `Parallel`: Updates all instances simultaneously, optimizing for speed but potentially reducing availability
// during the update.
// - `BestEffortParallel`: Updates replicas concurrently with a limit on simultaneous updates to ensure a minimum
// - `BestEffortParallel`: Updates instances concurrently with a limit on simultaneous updates to ensure a minimum
// number of operational replicas for maintaining quorum.
// For example, in a 5-replica component, updating a maximum of 2 replicas simultaneously keeps
// For example, in a 5-instances setup, updating a maximum of 2 instances simultaneously keeps
// at least 3 operational for quorum.
//
// This field is immutable and defaults to 'Serial'.
// Defaults to 'Serial'.
//
// +kubebuilder:validation:Enum={Serial,Parallel,BestEffortParallel}
// +kubebuilder:default=Serial
// +optional
UpdateStrategy *UpdateStrategy `json:"updateStrategy,omitempty"`
UpdateConcurrency *UpdateConcurrency `json:"updateConcurrency,omitempty"`

// InstanceSet controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down.
//
Expand Down Expand Up @@ -1459,40 +1460,6 @@ type ReplicaRole struct {
Votable bool `json:"votable,omitempty"`
}

// UpdateStrategy defines the update strategy for cluster components. This strategy determines how updates are applied
// across the cluster.
// The available strategies are `Serial`, `BestEffortParallel`, and `Parallel`.
//
// +enum
// +kubebuilder:validation:Enum={Serial,BestEffortParallel,Parallel}
type UpdateStrategy string

const (
// SerialStrategy indicates that updates are applied one at a time in a sequential manner.
// The operator waits for each replica to be updated and ready before proceeding to the next one.
// This ensures that only one replica is unavailable at a time during the update process.
SerialStrategy UpdateStrategy = "Serial"

// ParallelStrategy indicates that updates are applied simultaneously to all Pods of a Component.
// The replicas are updated in parallel, with the operator updating all replicas concurrently.
// This strategy provides the fastest update time but may lead to a period of reduced availability or
// capacity during the update process.
ParallelStrategy UpdateStrategy = "Parallel"

// BestEffortParallelStrategy indicates that the replicas are updated in parallel, with the operator making
// a best-effort attempt to update as many replicas as possible concurrently
// while maintaining the component's availability.
// Unlike the `Parallel` strategy, the `BestEffortParallel` strategy aims to ensure that a minimum number
// of replicas remain available during the update process to maintain the component's quorum and functionality.
//
// For example, consider a component with 5 replicas. To maintain the component's availability and quorum,
// the operator may allow a maximum of 2 replicas to be simultaneously updated. This ensures that at least
// 3 replicas (a quorum) remain available and functional during the update process.
//
// The `BestEffortParallel` strategy strikes a balance between update speed and component availability.
BestEffortParallelStrategy UpdateStrategy = "BestEffortParallel"
)

// ComponentLifecycleActions defines a collection of Actions for customizing the behavior of a Component.
type ComponentLifecycleActions struct {
// Specifies the hook to be executed after a component's creation.
Expand Down
4 changes: 2 additions & 2 deletions apis/apps/v1/shardingdefinition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ type ShardingDefinitionSpec struct {
//
// +kubebuilder:default=Serial
// +optional
ProvisionStrategy *UpdateStrategy `json:"provisionStrategy,omitempty"`
ProvisionStrategy *UpdateConcurrency `json:"provisionStrategy,omitempty"`

// Specifies the strategy for updating shards of the sharding. Only `Serial` and `Parallel` are supported.
//
// This field is immutable.
//
// +kubebuilder:default=Serial
// +optional
UpdateStrategy *UpdateStrategy `json:"updateStrategy,omitempty"`
UpdateStrategy *UpdateConcurrency `json:"updateStrategy,omitempty"`

// Defines a set of hooks and procedures that customize the behavior of a sharding throughout its lifecycle.
//
Expand Down
133 changes: 126 additions & 7 deletions apis/apps/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package v1

import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)

const (
Expand Down Expand Up @@ -463,16 +464,16 @@ type ClusterComponentConfigSource struct {
// - Local file
}

type PodUpdatePolicyType string
type InstanceUpdatePolicyType string

const (
// StrictInPlacePodUpdatePolicyType indicates that only allows in-place upgrades.
// Any attempt to modify other fields will be rejected.
StrictInPlacePodUpdatePolicyType PodUpdatePolicyType = "StrictInPlace"
// StrictInPlaceInstanceUpdatePolicyType indicates that only allows in-place update.
// Any attempt to modify other fields that not support in-place update will be rejected.
StrictInPlaceInstanceUpdatePolicyType InstanceUpdatePolicyType = "StrictInPlace"

// PreferInPlacePodUpdatePolicyType indicates that we will first attempt an in-place upgrade of the Pod.
// If that fails, it will fall back to the ReCreate, where pod will be recreated.
PreferInPlacePodUpdatePolicyType PodUpdatePolicyType = "PreferInPlace"
// PreferInPlaceInstanceUpdatePolicyType indicates that we will first attempt an in-place update of the instance.
// If that fails, it will fall back to the ReCreate, where instance will be recreated.
PreferInPlaceInstanceUpdatePolicyType InstanceUpdatePolicyType = "PreferInPlace"
)

type SchedulingPolicy struct {
Expand Down Expand Up @@ -690,3 +691,121 @@ type Ordinals struct {
Ranges []Range `json:"ranges,omitempty"`
Discrete []int32 `json:"discrete,omitempty"`
}

// UpdateStrategy defines fine-grained control over the spec update process of all instances.
type UpdateStrategy struct {
// Indicates the type of the UpdateStrategy.
// Default is RollingUpdate.
//
// +optional
Type UpdateStrategyType `json:"type,omitempty"`

// Indicates how instances should be updated.
//
// - `StrictInPlace` indicates that only allows in-place update.
// Any attempt to modify other fields that not support in-place update will be rejected.
// - `PreferInPlace` indicates that we will first attempt an in-place update of the instance.
// If that fails, it will fall back to the ReCreate, where instance will be recreated.
// Default value is "PreferInPlace".
//
// +kubebuilder:validation:Enum={StrictInPlace,PreferInPlace}
// +optional
InstanceUpdatePolicy *InstanceUpdatePolicyType `json:"instanceUpdatePolicy,omitempty"`

// Specifies how the rolling update should be applied.
//
// +optional
RollingUpdate *RollingUpdate `json:"rollingUpdate,omitempty"`
}

// UpdateStrategyType is a string enumeration type that enumerates
// all possible update strategies for the KubeBlocks controllers.
//
// +enum
// +kubebuilder:validation:Enum={RollingUpdate,OnDelete}
type UpdateStrategyType string

const (
// RollingUpdateStrategyType indicates that update will be
// applied to all Instances with respect to the InstanceSet
// ordering constraints.
RollingUpdateStrategyType UpdateStrategyType = "RollingUpdate"
// OnDeleteStrategyType indicates that ordered rolling restarts are disabled. Instances are recreated
// when they are manually deleted.
OnDeleteStrategyType UpdateStrategyType = "OnDelete"
)

// RollingUpdate specifies how the rolling update should be applied.
type RollingUpdate struct {
// Indicates the number of instances that should be updated during a rolling update.
// The remaining instances will remain untouched. This is helpful in defining how many instances
// should participate in the update process.
// Value can be an absolute number (ex: 5) or a percentage of desired instances (ex: 10%).
// Absolute number is calculated from percentage by rounding up.
// The default value is ComponentSpec.Replicas (i.e., update all instances).
//
// +optional
Replicas *intstr.IntOrString `json:"replicas,omitempty"`

// Specifies the concurrency level for updating instances during a rolling update.
// Available levels:
//
// - `Serial`: Updates instances one at a time, ensuring minimal downtime by waiting for each instance to become ready
// before updating the next.
// - `Parallel`: Updates all instances simultaneously, optimizing for speed but potentially reducing availability
// during the update.
// - `BestEffortParallel`: Updates instances concurrently with a limit on simultaneous updates to ensure a minimum
// number of operational replicas for maintaining quorum.
// For example, in a 5-instances setup, updating a maximum of 2 instances simultaneously keeps
// at least 3 operational for quorum.
//
// Defaults to 'Serial'.
//
// +kubebuilder:validation:Enum={Serial,Parallel,BestEffortParallel}
// +kubebuilder:default=Serial
// +optional
UpdateConcurrency *UpdateConcurrency `json:"updateConcurrency,omitempty"`

// The maximum number of instances that can be unavailable during the update.
// Value can be an absolute number (ex: 5) or a percentage of desired instances (ex: 10%).
// Absolute number is calculated from percentage by rounding up. This can not be 0.
// Defaults to 1. The field applies to all instances. That means if there is any unavailable pod,
// it will be counted towards MaxUnavailable.
//
// +optional
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`
}

// UpdateConcurrency defines the update concurrency level for cluster components. This concurrency level determines how updates are applied
// across the cluster.
// The available concurrency levels are `Serial`, `BestEffortParallel`, and `Parallel`.
//
// +enum
// +kubebuilder:validation:Enum={Serial,BestEffortParallel,Parallel}
type UpdateConcurrency string

const (
// SerialConcurrency indicates that updates are applied one at a time in a sequential manner.
// The operator waits for each replica to be updated and ready before proceeding to the next one.
// This ensures that only one replica is unavailable at a time during the update process.
SerialConcurrency UpdateConcurrency = "Serial"

// ParallelConcurrency indicates that updates are applied simultaneously to all Pods of a Component.
// The replicas are updated in parallel, with the operator updating all replicas concurrently.
// This strategy provides the fastest update time but may lead to a period of reduced availability or
// capacity during the update process.
ParallelConcurrency UpdateConcurrency = "Parallel"

// BestEffortParallelConcurrency indicates that the replicas are updated in parallel, with the operator making
// a best-effort attempt to update as many replicas as possible concurrently
// while maintaining the component's availability.
// Unlike the `Parallel` strategy, the `BestEffortParallel` strategy aims to ensure that a minimum number
// of replicas remain available during the update process to maintain the component's quorum and functionality.
//
// For example, consider a component with 5 replicas. To maintain the component's availability and quorum,
// the operator may allow a maximum of 2 replicas to be simultaneously updated. This ensures that at least
// 3 replicas (a quorum) remain available and functional during the update process.
//
// The `BestEffortParallel` strategy strikes a balance between update speed and component availability.
BestEffortParallelConcurrency UpdateConcurrency = "BestEffortParallel"
)
Loading
Loading