Skip to content

Commit a15dfd2

Browse files
committed
feat: Add auto-scaling
1 parent 0b07bcd commit a15dfd2

File tree

9 files changed

+3604
-124
lines changed

9 files changed

+3604
-124
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Please note this table only reports end-to-end tests suite coverage, others vers
9797
- [x] Cluster monitoring.
9898
- [x] Complete end2end test suite.
9999
- [x] Archival.
100-
- [ ] Auto scaling.
100+
- [x] Auto scaling.
101101
- [ ] Multi cluster replication.
102102
103103
## Contributing

api/v1beta1/temporalcluster_types.go

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ import (
2828
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
2929
"go.temporal.io/server/common/primitives"
3030
"golang.org/x/exp/slices"
31+
autoscalingv2 "k8s.io/api/autoscaling/v2"
3132
corev1 "k8s.io/api/core/v1"
3233
networkingv1 "k8s.io/api/networking/v1"
3334
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3435
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
36+
"k8s.io/utils/ptr"
3537
)
3638

3739
// LogSpec contains the temporal logging configuration.
@@ -62,6 +64,32 @@ type LogSpec struct {
6264
Development bool `json:"development"`
6365
}
6466

67+
// AutoscalingSpec defines the configuration for Horizontal Pod Autoscaling.
68+
type AutoscalingSpec struct {
69+
// MinReplicas is the lower limit for the number of replicas to which the autoscaler
70+
// can scale down. It defaults to 1 pod.
71+
// +optional
72+
// +kubebuilder:validation:Minimum=1
73+
MinReplicas *int32 `json:"minReplicas,omitempty"`
74+
75+
// MaxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up.
76+
// +kubebuilder:validation:Minimum=1
77+
// +optional
78+
MaxReplicas *int32 `json:"maxReplicas,omitempty"`
79+
80+
// Metrics contains the specifications for which to use to calculate the
81+
// desired replica count (the maximum replica count across all metrics will
82+
// be used). If not set, defaults to 80% CPU and 70% memory utilization.
83+
// +optional
84+
Metrics []autoscalingv2.MetricSpec `json:"metrics,omitempty"`
85+
86+
// Behavior configures the scaling behavior of the target
87+
// in both Up and Down directions (scaleUp and scaleDown fields respectively).
88+
// If not set, the default HPAScalingRules for scale up and scale down are used.
89+
// +optional
90+
Behavior *autoscalingv2.HorizontalPodAutoscalerBehavior `json:"behavior,omitempty"`
91+
}
92+
6593
// ServiceSpec contains a temporal service specifications.
6694
type ServiceSpec struct {
6795
// Port defines a custom gRPC port for the service.
@@ -88,7 +116,7 @@ type ServiceSpec struct {
88116
// Number of desired replicas for the service. Default to 1.
89117
// +kubebuilder:validation:Minimum=1
90118
// +optional
91-
Replicas *int32 `json:"replicas"`
119+
Replicas *int32 `json:"replicas,omitempty"`
92120
// Compute Resources required by this service.
93121
// More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
94122
// +optional
@@ -100,6 +128,10 @@ type ServiceSpec struct {
100128
// InitContainers adds a list of init containers to the service's deployment.
101129
// +optional
102130
InitContainers []corev1.Container `json:"initContainers,omitempty"`
131+
// Autoscaling enables horizontal pod autoscaling for the service.
132+
// When enabled, the controller will bypass the replicas field and create an HPA resource instead.
133+
// +optional
134+
Autoscaling *AutoscalingSpec `json:"autoscaling,omitempty"`
103135
// ServiceAccountOverride
104136
}
105137

@@ -116,6 +148,30 @@ func (s *InternalFrontendServiceSpec) IsEnabled() bool {
116148
return s != nil && s.Enabled
117149
}
118150

151+
// IsAutoscalingEnabled returns true if autoscaling is enabled for the service.
152+
func (s *ServiceSpec) IsAutoscalingEnabled() bool {
153+
return s != nil && s.Autoscaling != nil
154+
}
155+
156+
// GetEffectiveReplicas returns the replica count to use for the deployment.
157+
// If autoscaling is enabled, returns the current replicas value which HPA may have
158+
// updated via the coordination logic. Otherwise, returns the configured replicas value.
159+
func (s *ServiceSpec) GetEffectiveReplicas() *int32 {
160+
// If autoscaling is configured, respect the current Replicas value which may be
161+
// updated by HPA coordination logic, but ensure it doesn't go below MinReplicas
162+
if s.IsAutoscalingEnabled() && s.Autoscaling.MinReplicas != nil {
163+
if s.Replicas != nil {
164+
replicas := max(*s.Autoscaling.MinReplicas, *s.Replicas)
165+
return &replicas
166+
}
167+
return s.Autoscaling.MinReplicas
168+
}
169+
if s.Replicas != nil {
170+
return s.Replicas
171+
}
172+
return ptr.To[int32](1)
173+
}
174+
119175
// ServicesSpec contains all temporal services specifications.
120176
type ServicesSpec struct {
121177
// Frontend service custom specifications.

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)