Commit b0024f73 authored by Shinya Maeda's avatar Shinya Maeda
Browse files

Merge branch 'add-hpa-custom-scaling-support' into 'master'

feat: add support for scaling on custom metrics

See merge request gitlab-org/cluster-integration/auto-deploy-image!226
parents 9c1d950c 8e26f6ea
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
apiVersion: v1
description: GitLab's Auto-deploy Helm Chart
name: auto-deploy-app
version: 2.14.0
version: 2.16.0
icon: https://gitlab.com/gitlab-com/gitlab-artwork/raw/master/logo/logo-square.png
+2 −1
Original line number Diff line number Diff line
@@ -34,7 +34,8 @@
| hpa.enabled                   | If true, enables horizontal pod autoscaler. A resource request is also required to be set, such as `resources.requests.cpu: 200m`.| `false` |
| hpa.minReplicas               |             | `1`                                |
| hpa.maxReplicas               |             | `5`                                |
| hpa.targetCPUUtilizationPercentage | Percentage threshold when HPA begins scaling out pods | `80` |
| hpa.targetCPUUtilizationPercentage | `autoscaling/v1` - Percentage threshold for when HPA begins scaling out pods. Ignored if `hpa.metrics` is present. | `nil` |
| hpa.metrics                   | `autoscaling/v2beta2`  [metrics](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/) definitions for when HPA begins scaling out pods.  | `nil` |
| gitlab.app                    | GitLab project slug. | `nil` |
| gitlab.env                    | GitLab environment slug. | `nil` |
| gitlab.envName                | GitLab environment name. | `nil` |
+11 −2
Original line number Diff line number Diff line
{{- if and .Values.hpa.enabled .Values.resources.requests -}}
{{- if .Values.hpa.metrics }}
apiVersion: autoscaling/v2beta2
{{- else }}
apiVersion: autoscaling/v1
{{- end }}
kind: HorizontalPodAutoscaler
metadata:
  name: {{ template "fullname" . }}
@@ -7,10 +11,15 @@ metadata:
{{ include "sharedlabels" . | indent 4 }}
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: {{ template "appname" . }}
    apiVersion: apps/v1
  minReplicas: {{ .Values.hpa.minReplicas }}
  maxReplicas: {{ .Values.hpa.maxReplicas }}
{{- if .Values.hpa.metrics }}
  metrics:
{{ toYaml .Values.hpa.metrics | indent 2 }}
{{- else }}
  targetCPUUtilizationPercentage: {{ .Values.hpa.targetCPUUtilizationPercentage }}
{{- end -}}
{{- end }}
{{- end}}
+78 −0
Original line number Diff line number Diff line
package main

import (
	"os"
	"regexp"
	"testing"

	"github.com/gruntwork-io/terratest/modules/helm"
	"github.com/stretchr/testify/require"
	autoscalingV1 "k8s.io/api/autoscaling/v1"
	autoscalingV2Beta2 "k8s.io/api/autoscaling/v2beta2"
)

func TestHPA_AutoscalingV1(t *testing.T) {
@@ -60,3 +62,79 @@ func TestHPA_AutoscalingV1(t *testing.T) {
		})
	}
}

func TestHPA_AutoscalingV2beta2(t *testing.T) {
	templates := []string{"templates/hpa.yaml"}
	releaseName := "hpa-test"

	tcs := []struct {
		name   string
		values string

		expectedName        string
		expectedMinReplicas int32
		expectedMaxReplicas int32
		expectedAverageUtilization   int32

		expectedErrorRegexp *regexp.Regexp
	}{
		{
			name:                "defaults",
			expectedErrorRegexp: regexp.MustCompile("Error: could not find template templates/hpa.yaml in chart"),
		},
		{
			name:                "with hpa enabled, and both metrics and requests defined",
			values: `
hpa:
  enabled: true
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 80
resources:
  requests:
    cpu: 500
`,
			expectedName:        "hpa-test-auto-deploy",
			expectedMinReplicas: 1,
			expectedMaxReplicas: 5,
			expectedAverageUtilization:   80,
		},
	}

	for _, tc := range tcs {
		t.Run(tc.name, func(t *testing.T) {
			f, err := os.CreateTemp("", "")
			defer os.Remove(f.Name())
			require.NoError(t, err)
			f.WriteString(tc.values)

			opts := &helm.Options{ValuesFiles: []string{ f.Name() }}
			output, err := helm.RenderTemplateE(t, opts, helmChartPath, releaseName, templates)

			if tc.expectedErrorRegexp != nil {
				if err == nil {
					t.Error("Expected error but didn't happen")
				} else {
					require.Regexp(t, tc.expectedErrorRegexp, err.Error())
				}
				return
			}
			if err != nil {
				t.Error(err)
				return
			}


			hpa := new(autoscalingV2Beta2.HorizontalPodAutoscaler)
			helm.UnmarshalK8SYaml(t, output, hpa)
			require.Equal(t, tc.expectedName, hpa.ObjectMeta.Name)
			require.Equal(t, tc.expectedMinReplicas, *hpa.Spec.MinReplicas)
			require.Equal(t, tc.expectedMaxReplicas, hpa.Spec.MaxReplicas)
			require.Equal(t, tc.expectedAverageUtilization, *hpa.Spec.Metrics[0].Resource.Target.AverageUtilization)
		})
	}
}
+14 −0
Original line number Diff line number Diff line
@@ -35,7 +35,21 @@ hpa:
  enabled: false
  minReplicas: 1
  maxReplicas: 5
  # Only one of targetCPUUtilizationPercentage and metrics can be chosen.
  # This is because targetCPUUtilizationPercentage is from autoscaling/v1,
  # whereas metrics is from autoscaling/v2beta2. If both are provided, only
  # metrics will be used.
  # See https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/
  # for examples of each.
  targetCPUUtilizationPercentage: 80
  # metrics:
  # - type: Resource
  #   resource:
  #     name: cpu
  #     target:
  #       type: Utilization
  #       averageUtilization: 80

gitlab:
  app:
  env: