Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changelog/4026.added.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
feat(HPA): Adds autoscaling config
5 changes: 5 additions & 0 deletions deploy/helm/sumologic/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ spec:
name: {{ template "sumologic.metadata.name.otelcolinstrumentation.statefulset" . }}
minReplicas: {{ $otelcolInstrumentation.autoscaling.minReplicas }}
maxReplicas: {{ $otelcolInstrumentation.autoscaling.maxReplicas }}
{{- if $otelcolInstrumentation.autoscaling.behavior }}
behavior:
{{- toYaml $otelcolInstrumentation.autoscaling.behavior | nindent 4 }}
{{- end }}
metrics:
{{- if $otelcolInstrumentation.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ spec:
name: {{ template "sumologic.metadata.name.tracesgateway.deployment" . }}
minReplicas: {{ $tracesGateway.autoscaling.minReplicas }}
maxReplicas: {{ $tracesGateway.autoscaling.maxReplicas }}
{{- if $tracesGateway.autoscaling.behavior }}
behavior:
{{- toYaml $tracesGateway.autoscaling.behavior | nindent 4 }}
{{- end }}
metrics:
{{- if $tracesGateway.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
Expand Down
4 changes: 4 additions & 0 deletions deploy/helm/sumologic/templates/logs/common/hpa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ spec:
name: {{ template "sumologic.metadata.name.logs.statefulset" . }}
minReplicas: {{ .Values.metadata.logs.autoscaling.minReplicas }}
maxReplicas: {{ .Values.metadata.logs.autoscaling.maxReplicas }}
{{- if .Values.metadata.logs.autoscaling.behavior }}
behavior:
{{- toYaml .Values.metadata.logs.autoscaling.behavior | nindent 4 }}
{{- end }}
metrics:
{{- if .Values.metadata.logs.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ spec:
{{- if .Values.sumologic.metrics.collector.otelcol.autoscaling.targetMemoryUtilizationPercentage }}
targetMemoryUtilization: {{ .Values.sumologic.metrics.collector.otelcol.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- if .Values.sumologic.metrics.collector.otelcol.autoscaling.behavior }}
behavior:
{{ toYaml .Values.sumologic.metrics.collector.otelcol.autoscaling.behavior | nindent 6 }}
{{- end }}
{{- end }}
env:
- name: METADATA_METRICS_SVC
Expand Down
4 changes: 4 additions & 0 deletions deploy/helm/sumologic/templates/metrics/common/hpa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ spec:
name: {{ template "sumologic.metadata.name.metrics.statefulset" . }}
minReplicas: {{ .Values.metadata.metrics.autoscaling.minReplicas }}
maxReplicas: {{ .Values.metadata.metrics.autoscaling.maxReplicas }}
{{- if .Values.metadata.metrics.autoscaling.behavior }}
behavior:
{{- toYaml .Values.metadata.metrics.autoscaling.behavior | nindent 4 }}
{{- end }}
metrics:
{{- if .Values.metadata.metrics.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
Expand Down
5 changes: 5 additions & 0 deletions deploy/helm/sumologic/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ sumologic:
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 70
behavior: {}

nodeSelector: {}

Expand Down Expand Up @@ -1388,6 +1389,7 @@ otelcolInstrumentation:
maxReplicas: 10
targetCPUUtilizationPercentage: 100
# targetMemoryUtilizationPercentage: 50
behavior: {}

statefulset:
nodeSelector: {}
Expand Down Expand Up @@ -1706,6 +1708,7 @@ metadata:
maxReplicas: 10
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 50
behavior: {}

## Option to specify PodDisrutionBudgets
## You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget
Expand Down Expand Up @@ -1824,6 +1827,7 @@ metadata:
maxReplicas: 10
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 50
behavior: {}

## Option to specify PodDisrutionBudgets
## You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget
Expand All @@ -1845,6 +1849,7 @@ tracesGateway:
maxReplicas: 10
targetCPUUtilizationPercentage: 100
# targetMemoryUtilizationPercentage: 50
behavior: {}

deployment:
replicas: 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,24 @@ debug:
collector:
print: true
stopLogsIngestion: true

sumologic:
metrics:
collector:
otelcol:
enabled: true
autoscaling:
enabled: true
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 60
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ spec:
minReplicas: 1
targetCPUUtilization: 70
targetMemoryUtilization: 70
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 60

env:
- name: METADATA_METRICS_SVC
valueFrom:
Expand Down
25 changes: 25 additions & 0 deletions tests/integration/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,31 @@ func GetMultipleMultilineLogsFeature() features.Feature {
Feature()
}

func GetHPAFeature(releaseName string) features.Feature {
expectedHPA := []string{
fmt.Sprintf("%s-sumologic-metrics-collector", releaseName),
fmt.Sprintf("%s-sumologic-otelcol-instrumentation", releaseName),
fmt.Sprintf("%s-sumologic-otelcol-logs", releaseName),
fmt.Sprintf("%s-sumologic-otelcol-metrics", releaseName),
fmt.Sprintf("%s-sumologic-traces-gateway", releaseName),
}
expectedMetrics := map[string]map[string]int{}
for _, hpa := range expectedHPA {
expectedMetrics[hpa] = map[string]int{
"cpu": 75,
"memory": 75,
}
}
return features.New("HPA").
Assess("HPA configured", stepfuncs.WaitUntilHPAConfigured(
expectedHPA,
expectedMetrics,
waitDuration,
tickDuration,
)).
Feature()
}

func GetEventsFeature() features.Feature {
return features.New("events").
Assess("events present", stepfuncs.WaitUntilExpectedLogsPresent(
Expand Down
29 changes: 29 additions & 0 deletions tests/integration/helm_ot_hpa_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//go:build allversions
// +build allversions

package integration

import (
"testing"

strings_internal "github.com/SumoLogic/sumologic-kubernetes-collection/tests/integration/internal/strings"
)

func Test_Helm_OT_HPA(t *testing.T) {
installChecks := []featureCheck{
CheckSumologicSecret(15),
CheckOtelcolMetadataLogsInstall,
CheckOtelcolMetadataMetricsInstall,
CheckOtelcolEventsInstall,
CheckOtelcolMetricsCollectorInstall,
CheckOtelcolLogsCollectorInstall,
CheckTracesInstall,
}

featInstall := GetInstallFeature(installChecks)

releaseName := strings_internal.ReleaseNameFromT(t)
featHPA := GetHPAFeature(releaseName)

testenv.Test(t, featInstall, featHPA)
}
80 changes: 80 additions & 0 deletions tests/integration/internal/stepfuncs/assess_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"os"
"regexp"
"sort"
"strings"
Expand All @@ -12,6 +13,7 @@ import (

appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
log "k8s.io/klog/v2"
"sigs.k8s.io/e2e-framework/klient/k8s"
"sigs.k8s.io/e2e-framework/klient/k8s/resources"
Expand Down Expand Up @@ -351,6 +353,84 @@ func WaitUntilExpectedMetricLabelsPresent(
}
}

// WaitUntilHPAConfigured returns a features.Func that can be used in `Assess` calls.
// It will wait until all the provided HPA are configured and active.
func WaitUntilHPAConfigured(
expectedHPAMetadata []string,
expectedMetrics map[string]map[string]int,
waitDuration time.Duration,
tickDuration time.Duration,
) features.Func {
return WaitUntilHPAPresent(
expectedHPAMetadata,
expectedMetrics,
waitDuration,
tickDuration,
)
}

// WaitUntilHPAPresent returns a features.Func that can be used in `Assess` calls.
// It will wait until all the provided HPA are configured and active. It will not verify the
// functionality of the HPA.
func WaitUntilHPAPresent(expectedHPAMetadata []string,
expectedMetrics map[string]map[string]int,
waitDuration time.Duration,
tickDuration time.Duration,
) features.Func {
return func(ctx context.Context, t *testing.T, envConf *envconf.Config) context.Context {
namespace := ctxopts.Namespace(ctx)
if namespace == "" {
log.Fatalf("Namespace not found in test context")
}

cfg := envconf.New().WithKubeconfigFile(os.Getenv("KUBECONFIG"))
c, err := kubernetes.NewForConfig(cfg.Client().RESTConfig())
require.NoError(t, err)

assert.Eventually(t, func() bool {
totalCount := len(expectedHPAMetadata)
currCount := 0
for _, expectedHPA := range expectedHPAMetadata {
hpa, err := c.AutoscalingV2().HorizontalPodAutoscalers(namespace).
Get(ctx, expectedHPA, metav1.GetOptions{})
if err != nil {
log.Errorf("failed to list HPAs: %v", err)
return false
}

if hpa == nil || hpa.Spec.Metrics == nil || len(hpa.Spec.Metrics) == 0 || hpa.Spec.Behavior == nil {
log.Infof("HPA %s is not configured. HPA: %v", expectedHPA, hpa)
return false
}

if len(hpa.Spec.Metrics) >= 2 && hpa.Spec.Behavior.ScaleUp != nil && hpa.Spec.Behavior.ScaleDown != nil {

resourceName1 := hpa.Spec.Metrics[0].Resource.Name
val1 := hpa.Spec.Metrics[0].Resource.Target.AverageUtilization
expectedVal1 := expectedMetrics[expectedHPA][string(resourceName1)]

resourceName2 := hpa.Spec.Metrics[1].Resource.Name
val2 := hpa.Spec.Metrics[1].Resource.Target.AverageUtilization
expectedVal2 := expectedMetrics[expectedHPA][string(resourceName2)]

if int(*val1) != expectedVal1 || int(*val2) != expectedVal2 {
log.Infof("HPA %s is configured and active but expectedValue: [%d, %d] "+
"did not match current value [%d, %d].",
expectedHPA, expectedVal1, expectedVal2, int(*val1), int(*val2))
return false
}
log.Infof("HPA %s is configured and active.", expectedHPA)
currCount++
}
}
log.Infof("Total HPA count: %d, Current HPA count: %d, expectedHPA: %v",
totalCount, currCount, expectedHPAMetadata)
return currCount == totalCount
}, waitDuration, tickDuration)
return ctx
}
}

// WaitUntilExpectedMetricsPresent returns a features.Func that can be used in `Assess` calls.
// It will wait until the provided number of logs with the provided labels are returned by sumologic-mock's HTTP API on
// the provided Service and port, until it succeeds or waitDuration passes.
Expand Down
Loading
Loading