Skip to content

Commit 010baa5

Browse files
cluster: support HPA for all cluster CRs storage
1 parent c988d06 commit 010baa5

File tree

12 files changed

+2030
-6
lines changed

12 files changed

+2030
-6
lines changed

api/operator/v1/vlcluster_types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,11 @@ type VLStorage struct {
526526
// ClaimTemplates allows adding additional VolumeClaimTemplates for StatefulSet
527527
ClaimTemplates []corev1.PersistentVolumeClaim `json:"claimTemplates,omitempty"`
528528

529+
// Configures horizontal pod autoscaling.
530+
// Note, downscaling is not supported.
531+
// +optional
532+
HPA *vmv1beta1.EmbeddedHPA `json:"hpa,omitempty"`
533+
529534
// StorageDataPath - path to storage data
530535
// +optional
531536
StorageDataPath string `json:"storageDataPath,omitempty"`
@@ -697,6 +702,9 @@ func (cr *VLCluster) Validate() error {
697702
if vls.ServiceSpec != nil && vls.ServiceSpec.Name == name {
698703
return fmt.Errorf(".serviceSpec.Name cannot be equal to prefixed name=%q", name)
699704
}
705+
if vls.HPA != nil && vls.HPA.Behaviour != nil && vls.HPA.Behaviour.ScaleDown != nil {
706+
return fmt.Errorf("vlstorage scaledown HPA behavior is not supported")
707+
}
700708
}
701709
if cr.Spec.RequestsLoadBalancer.Enabled {
702710
rlb := cr.Spec.RequestsLoadBalancer.Spec

api/operator/v1/vtcluster_types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,11 @@ type VTStorage struct {
441441
// ClaimTemplates allows adding additional VolumeClaimTemplates for StatefulSet
442442
ClaimTemplates []corev1.PersistentVolumeClaim `json:"claimTemplates,omitempty"`
443443

444+
// Configures horizontal pod autoscaling.
445+
// Note, downscaling is not supported.
446+
// +optional
447+
HPA *vmv1beta1.EmbeddedHPA `json:"hpa,omitempty"`
448+
444449
// StorageDataPath - path to storage data
445450
// +optional
446451
StorageDataPath string `json:"storageDataPath,omitempty"`
@@ -612,6 +617,9 @@ func (cr *VTCluster) Validate() error {
612617
if vts.ServiceSpec != nil && vts.ServiceSpec.Name == name {
613618
return fmt.Errorf(".serviceSpec.Name cannot be equal to prefixed name=%q", name)
614619
}
620+
if vts.HPA != nil && vts.HPA.Behaviour != nil && vts.HPA.Behaviour.ScaleDown != nil {
621+
return fmt.Errorf("vtstorage scaledown HPA behavior is not supported")
622+
}
615623
}
616624
if cr.Spec.RequestsLoadBalancer.Enabled {
617625
rlb := cr.Spec.RequestsLoadBalancer.Spec

api/operator/v1/zz_generated.deepcopy.go

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

api/operator/v1beta1/vmcluster_types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,11 @@ type VMStorage struct {
445445
// +optional
446446
PersistentVolumeClaimRetentionPolicy *appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy `json:"persistentVolumeClaimRetentionPolicy,omitempty"`
447447

448+
// Configures horizontal pod autoscaling.
449+
// Note, downscaling is not supported.
450+
// +optional
451+
HPA *EmbeddedHPA `json:"hpa,omitempty"`
452+
448453
// VMInsertPort for VMInsert connections
449454
// +optional
450455
VMInsertPort string `json:"vmInsertPort,omitempty"`
@@ -670,6 +675,9 @@ func (cr *VMCluster) Validate() error {
670675
return fmt.Errorf("vmstorage: %w", err)
671676
}
672677
}
678+
if vms.HPA != nil && vms.HPA.Behaviour != nil && vms.HPA.Behaviour.ScaleDown != nil {
679+
return fmt.Errorf("vmstorage scaledown HPA behavior is not supported")
680+
}
673681
}
674682
if cr.Spec.RequestsLoadBalancer.Enabled {
675683
rlb := cr.Spec.RequestsLoadBalancer.Spec

api/operator/v1beta1/zz_generated.deepcopy.go

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

config/crd/overlay/crd.yaml

Lines changed: 1893 additions & 0 deletions
Large diffs are not rendered by default.

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ aliases:
1515

1616
* FEATURE: [vmagent](https://docs.victoriametrics.com/operator/resources/vmagent/): support `namespace` parameter in `attach_metadata` section for all scrape configurations. See [#1654](https://github.com/VictoriaMetrics/operator/issues/1654).
1717
* FEATURE: [vlagent](https://docs.victoriametrics.com/operator/resources/vlagent): support logs collection. See [#1501](https://github.com/VictoriaMetrics/operator/issues/1501).
18+
* FEATURE: [vmoperator](https://docs.victoriametrics.com/operator/): added HPA support for all cluster CR storage. See [#1678](https://github.com/VictoriaMetrics/operator/issues/1678).
1819

1920
## [v0.66.1](https://github.com/VictoriaMetrics/operator/releases/tag/v0.66.1)
2021

docs/api.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ Appears in: [VLClusterSpec](#vlclusterspec)
561561
| hostAliases<a href="#vlstorage-hostaliases" id="vlstorage-hostaliases">#</a><br/>_[HostAlias](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#hostalias-v1-core) array_ | _(Optional)_<br/>HostAliases provides mapping for ip and hostname,<br />that would be propagated to pod,<br />cannot be used with HostNetwork. |
562562
| hostNetwork<a href="#vlstorage-hostnetwork" id="vlstorage-hostnetwork">#</a><br/>_boolean_ | _(Optional)_<br/>HostNetwork controls whether the pod may use the node network namespace |
563563
| host_aliases<a href="#vlstorage-host_aliases" id="vlstorage-host_aliases">#</a><br/>_[HostAlias](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#hostalias-v1-core) array_ | _(Optional)_<br/>HostAliasesUnderScore provides mapping for ip and hostname,<br />that would be propagated to pod,<br />cannot be used with HostNetwork.<br />Has Priority over hostAliases field |
564+
| hpa<a href="#vlstorage-hpa" id="vlstorage-hpa">#</a><br/>_[EmbeddedHPA](#embeddedhpa)_ | _(Optional)_<br/>Configures horizontal pod autoscaling.<br />Note, downscaling is not supported. |
564565
| image<a href="#vlstorage-image" id="vlstorage-image">#</a><br/>_[Image](#image)_ | _(Optional)_<br/>Image - docker image settings<br />if no specified operator uses default version from operator config |
565566
| imagePullSecrets<a href="#vlstorage-imagepullsecrets" id="vlstorage-imagepullsecrets">#</a><br/>_[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#localobjectreference-v1-core) array_ | _(Optional)_<br/>ImagePullSecrets An optional list of references to secrets in the same namespace<br />to use for pulling images from registries<br />see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod |
566567
| initContainers<a href="#vlstorage-initcontainers" id="vlstorage-initcontainers">#</a><br/>_[Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#container-v1-core) array_ | _(Optional)_<br/>InitContainers allows adding initContainers to the pod definition.<br />Any errors during the execution of an initContainer will lead to a restart of the Pod.<br />More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ |
@@ -1094,6 +1095,7 @@ Appears in: [VTClusterSpec](#vtclusterspec)
10941095
| hostAliases<a href="#vtstorage-hostaliases" id="vtstorage-hostaliases">#</a><br/>_[HostAlias](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#hostalias-v1-core) array_ | _(Optional)_<br/>HostAliases provides mapping for ip and hostname,<br />that would be propagated to pod,<br />cannot be used with HostNetwork. |
10951096
| hostNetwork<a href="#vtstorage-hostnetwork" id="vtstorage-hostnetwork">#</a><br/>_boolean_ | _(Optional)_<br/>HostNetwork controls whether the pod may use the node network namespace |
10961097
| host_aliases<a href="#vtstorage-host_aliases" id="vtstorage-host_aliases">#</a><br/>_[HostAlias](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#hostalias-v1-core) array_ | _(Optional)_<br/>HostAliasesUnderScore provides mapping for ip and hostname,<br />that would be propagated to pod,<br />cannot be used with HostNetwork.<br />Has Priority over hostAliases field |
1098+
| hpa<a href="#vtstorage-hpa" id="vtstorage-hpa">#</a><br/>_[EmbeddedHPA](#embeddedhpa)_ | _(Optional)_<br/>Configures horizontal pod autoscaling.<br />Note, downscaling is not supported. |
10971099
| image<a href="#vtstorage-image" id="vtstorage-image">#</a><br/>_[Image](#image)_ | _(Optional)_<br/>Image - docker image settings<br />if no specified operator uses default version from operator config |
10981100
| imagePullSecrets<a href="#vtstorage-imagepullsecrets" id="vtstorage-imagepullsecrets">#</a><br/>_[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#localobjectreference-v1-core) array_ | _(Optional)_<br/>ImagePullSecrets An optional list of references to secrets in the same namespace<br />to use for pulling images from registries<br />see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod |
10991101
| initContainers<a href="#vtstorage-initcontainers" id="vtstorage-initcontainers">#</a><br/>_[Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#container-v1-core) array_ | _(Optional)_<br/>InitContainers allows adding initContainers to the pod definition.<br />Any errors during the execution of an initContainer will lead to a restart of the Pod.<br />More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ |
@@ -1718,7 +1720,7 @@ Appears in: [Receiver](#receiver)
17181720
EmbeddedHPA embeds HorizontalPodAutoScaler spec v2.
17191721
https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/horizontal-pod-autoscaler-v2/
17201722

1721-
Appears in: [VLInsert](#vlinsert), [VLSelect](#vlselect), [VMAuthSpec](#vmauthspec), [VMInsert](#vminsert), [VMSelect](#vmselect), [VTInsert](#vtinsert), [VTSelect](#vtselect)
1723+
Appears in: [VLInsert](#vlinsert), [VLSelect](#vlselect), [VLStorage](#vlstorage), [VMAuthSpec](#vmauthspec), [VMInsert](#vminsert), [VMSelect](#vmselect), [VMStorage](#vmstorage), [VTInsert](#vtinsert), [VTSelect](#vtselect), [VTStorage](#vtstorage)
17221724

17231725
| Field | Description |
17241726
| --- | --- |
@@ -4826,6 +4828,7 @@ Appears in: [VMClusterSpec](#vmclusterspec)
48264828
| hostAliases<a href="#vmstorage-hostaliases" id="vmstorage-hostaliases">#</a><br/>_[HostAlias](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#hostalias-v1-core) array_ | _(Optional)_<br/>HostAliases provides mapping for ip and hostname,<br />that would be propagated to pod,<br />cannot be used with HostNetwork. |
48274829
| hostNetwork<a href="#vmstorage-hostnetwork" id="vmstorage-hostnetwork">#</a><br/>_boolean_ | _(Optional)_<br/>HostNetwork controls whether the pod may use the node network namespace |
48284830
| host_aliases<a href="#vmstorage-host_aliases" id="vmstorage-host_aliases">#</a><br/>_[HostAlias](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#hostalias-v1-core) array_ | _(Optional)_<br/>HostAliasesUnderScore provides mapping for ip and hostname,<br />that would be propagated to pod,<br />cannot be used with HostNetwork.<br />Has Priority over hostAliases field |
4831+
| hpa<a href="#vmstorage-hpa" id="vmstorage-hpa">#</a><br/>_[EmbeddedHPA](#embeddedhpa)_ | _(Optional)_<br/>Configures horizontal pod autoscaling.<br />Note, downscaling is not supported. |
48294832
| image<a href="#vmstorage-image" id="vmstorage-image">#</a><br/>_[Image](#image)_ | _(Optional)_<br/>Image - docker image settings<br />if no specified operator uses default version from operator config |
48304833
| imagePullSecrets<a href="#vmstorage-imagepullsecrets" id="vmstorage-imagepullsecrets">#</a><br/>_[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#localobjectreference-v1-core) array_ | _(Optional)_<br/>ImagePullSecrets An optional list of references to secrets in the same namespace<br />to use for pulling images from registries<br />see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod |
48314834
| initContainers<a href="#vmstorage-initcontainers" id="vmstorage-initcontainers">#</a><br/>_[Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#container-v1-core) array_ | _(Optional)_<br/>InitContainers allows adding initContainers to the pod definition.<br />Any errors during the execution of an initContainer will lead to a restart of the Pod.<br />More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ |

internal/controller/operator/factory/vlcluster/vlstorage.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"sort"
88

99
appsv1 "k8s.io/api/apps/v1"
10+
autoscalingv2 "k8s.io/api/autoscaling/v2"
1011
corev1 "k8s.io/api/core/v1"
1112
policyv1 "k8s.io/api/policy/v1"
1213
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -39,6 +40,9 @@ func createOrUpdateVLStorage(ctx context.Context, rclient client.Client, cr, pre
3940
return err
4041
}
4142
}
43+
if err := createOrUpdateVLSelectHPA(ctx, rclient, cr, prevCR); err != nil {
44+
return err
45+
}
4246
if err := createOrUpdateVLStorageSTS(ctx, rclient, cr, prevCR); err != nil {
4347
return err
4448
}
@@ -93,6 +97,30 @@ func createOrUpdateVLStorageService(ctx context.Context, rclient client.Client,
9397
return newHeadless, nil
9498
}
9599

100+
func createOrUpdateVLStorageHPA(ctx context.Context, rclient client.Client, cr, prevCR *vmv1.VLCluster) error {
101+
hpa := cr.Spec.VLStorage.HPA
102+
if hpa == nil {
103+
return nil
104+
}
105+
if hpa.Behaviour != nil && hpa.Behaviour.ScaleDown != nil {
106+
return fmt.Errorf("scaleDown is not supported for vlstorage HPA")
107+
}
108+
b := build.NewChildBuilder(cr, vmv1beta1.ClusterComponentStorage)
109+
targetRef := autoscalingv2.CrossVersionObjectReference{
110+
Name: b.PrefixedName(),
111+
Kind: "StatefulSet",
112+
APIVersion: "apps/v1",
113+
}
114+
defaultHPA := build.HPA(b, targetRef, hpa)
115+
var prevHPA *autoscalingv2.HorizontalPodAutoscaler
116+
if prevCR != nil && prevCR.Spec.VLStorage.HPA != nil {
117+
b = build.NewChildBuilder(prevCR, vmv1beta1.ClusterComponentStorage)
118+
prevHPA = build.HPA(b, targetRef, prevCR.Spec.VLStorage.HPA)
119+
}
120+
121+
return reconcile.HPA(ctx, rclient, defaultHPA, prevHPA)
122+
}
123+
96124
func createOrUpdateVLStorageSTS(ctx context.Context, rclient client.Client, cr, prevCR *vmv1.VLCluster) error {
97125
var prevSts *appsv1.StatefulSet
98126

internal/controller/operator/factory/vmcluster/vmcluster.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ func CreateOrUpdate(ctx context.Context, cr *vmv1beta1.VMCluster, rclient client
7474
if err != nil {
7575
return err
7676
}
77+
if err := createOrUpdateVMStorageHPA(ctx, rclient, cr, prevCR); err != nil {
78+
return err
79+
}
7780
if !ptr.Deref(cr.Spec.VMStorage.DisableSelfServiceScrape, cfg.DisableSelfServiceScrapeCreation) {
7881
err := reconcile.VMServiceScrapeForCRD(ctx, rclient, build.VMServiceScrapeForServiceWithSpec(storageSvc, cr.Spec.VMStorage, "vmbackupmanager"))
7982
if err != nil {
@@ -1119,12 +1122,12 @@ func createOrUpdateVMInsertHPA(ctx context.Context, rclient client.Client, cr, p
11191122
if cr.Spec.VMInsert.HPA == nil {
11201123
return nil
11211124
}
1125+
b := build.NewChildBuilder(cr, vmv1beta1.ClusterComponentInsert)
11221126
targetRef := autoscalingv2.CrossVersionObjectReference{
1123-
Name: cr.PrefixedName(vmv1beta1.ClusterComponentInsert),
1127+
Name: b.PrefixedName(),
11241128
Kind: "Deployment",
11251129
APIVersion: "apps/v1",
11261130
}
1127-
b := build.NewChildBuilder(cr, vmv1beta1.ClusterComponentInsert)
11281131
newHPA := build.HPA(b, targetRef, cr.Spec.VMInsert.HPA)
11291132
var prevHPA *autoscalingv2.HorizontalPodAutoscaler
11301133
if prevCR != nil && prevCR.Spec.VMInsert.HPA != nil {
@@ -1138,13 +1141,12 @@ func createOrUpdateVMSelectHPA(ctx context.Context, rclient client.Client, cr, p
11381141
if cr.Spec.VMSelect.HPA == nil {
11391142
return nil
11401143
}
1141-
commonName := cr.PrefixedName(vmv1beta1.ClusterComponentSelect)
1144+
b := build.NewChildBuilder(cr, vmv1beta1.ClusterComponentSelect)
11421145
targetRef := autoscalingv2.CrossVersionObjectReference{
1143-
Name: commonName,
1146+
Name: b.PrefixedName(),
11441147
Kind: "StatefulSet",
11451148
APIVersion: "apps/v1",
11461149
}
1147-
b := build.NewChildBuilder(cr, vmv1beta1.ClusterComponentSelect)
11481150
defaultHPA := build.HPA(b, targetRef, cr.Spec.VMSelect.HPA)
11491151
var prevHPA *autoscalingv2.HorizontalPodAutoscaler
11501152
if prevCR != nil && prevCR.Spec.VMSelect.HPA != nil {
@@ -1155,6 +1157,30 @@ func createOrUpdateVMSelectHPA(ctx context.Context, rclient client.Client, cr, p
11551157
return reconcile.HPA(ctx, rclient, defaultHPA, prevHPA)
11561158
}
11571159

1160+
func createOrUpdateVMStorageHPA(ctx context.Context, rclient client.Client, cr, prevCR *vmv1beta1.VMCluster) error {
1161+
hpa := cr.Spec.VMStorage.HPA
1162+
if hpa == nil {
1163+
return nil
1164+
}
1165+
if hpa.Behaviour != nil && hpa.Behaviour.ScaleDown != nil {
1166+
return fmt.Errorf("scaleDown is not supported for vmstorage HPA")
1167+
}
1168+
b := build.NewChildBuilder(cr, vmv1beta1.ClusterComponentStorage)
1169+
targetRef := autoscalingv2.CrossVersionObjectReference{
1170+
Name: b.PrefixedName(),
1171+
Kind: "StatefulSet",
1172+
APIVersion: "apps/v1",
1173+
}
1174+
defaultHPA := build.HPA(b, targetRef, hpa)
1175+
var prevHPA *autoscalingv2.HorizontalPodAutoscaler
1176+
if prevCR != nil && prevCR.Spec.VMStorage.HPA != nil {
1177+
b = build.NewChildBuilder(prevCR, vmv1beta1.ClusterComponentStorage)
1178+
prevHPA = build.HPA(b, targetRef, prevCR.Spec.VMStorage.HPA)
1179+
}
1180+
1181+
return reconcile.HPA(ctx, rclient, defaultHPA, prevHPA)
1182+
}
1183+
11581184
func deleteOrphaned(ctx context.Context, rclient client.Client, cr *vmv1beta1.VMCluster) error {
11591185
newStorage := cr.Spec.VMStorage
11601186
newSelect := cr.Spec.VMSelect
@@ -1174,6 +1200,9 @@ func deleteOrphaned(ctx context.Context, rclient client.Client, cr *vmv1beta1.VM
11741200
if newStorage.PodDisruptionBudget != nil {
11751201
cc.KeepPDB(commonName)
11761202
}
1203+
if newStorage.HPA != nil {
1204+
cc.KeepHPA(commonName)
1205+
}
11771206
if !ptr.Deref(newStorage.DisableSelfServiceScrape, disableSelfScrape) {
11781207
cc.KeepScrape(commonName)
11791208
}

0 commit comments

Comments
 (0)