diff --git a/charts/cf-vcluster/Chart.yaml b/charts/cf-vcluster/Chart.yaml index 40543ff..60def46 100644 --- a/charts/cf-vcluster/Chart.yaml +++ b/charts/cf-vcluster/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: cf-vcluster description: Umbrella chart over vCluster adjusted for Codefresh use cases - mainly in Crossplane compositions type: application -version: 0.28.0-3 +version: 0.28.0-4 appVersion: "0.28.0" dependencies: - name: vcluster diff --git a/charts/cf-vcluster/README.md b/charts/cf-vcluster/README.md index 54c919e..812bc4a 100644 --- a/charts/cf-vcluster/README.md +++ b/charts/cf-vcluster/README.md @@ -1,6 +1,6 @@ # cf-vcluster -![Version: 0.28.0-3](https://img.shields.io/badge/Version-0.28.0--3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.28.0](https://img.shields.io/badge/AppVersion-0.28.0-informational?style=flat-square) +![Version: 0.28.0-4](https://img.shields.io/badge/Version-0.28.0--4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.28.0](https://img.shields.io/badge/AppVersion-0.28.0-informational?style=flat-square) Umbrella chart over vCluster adjusted for Codefresh use cases - mainly in Crossplane compositions @@ -20,13 +20,18 @@ Umbrella chart over vCluster adjusted for Codefresh use cases - mainly in Crossp | Key | Type | Default | Description | |-----|------|---------|-------------| +| automaticScaleDown.enabled | bool | `false` | | +| automaticScaleDown.httpScaler | object | `{"host":"keda-add-ons-http-external-scaler.keda","port":9090}` | Scaler address on vCluster host | +| automaticScaleDown.initialCooldownPeriod | int | `120` | | +| automaticScaleDown.interceptor | object | `{"host":"keda-add-ons-http-interceptor-proxy.keda","port":8443}` | Interceptor address on vCluster host | +| automaticScaleDown.periodSeconds | int | `43200` | How many seconds of no requests to vcluster until it is scaled down to zero. Defaults to 12 hours (43200s) | | global.ingress.internal.annotations."nginx.ingress.kubernetes.io/backend-protocol" | string | `"HTTPS"` | | | global.ingress.internal.annotations."nginx.ingress.kubernetes.io/ssl-passthrough" | string | `"true"` | | | global.ingress.internal.annotations."nginx.ingress.kubernetes.io/ssl-redirect" | string | `"true"` | | | global.ingress.internal.backendServiceOverride | object | `{}` | Possibility to override backend service name for ingress. If not set default vcluster backend service will be used | | global.ingress.internal.enabled | bool | `false` | | | global.ingress.internal.host.domain | string | `"corp.local"` | | -| global.ingress.internal.host.name | string | `"{{ .Release.Name }}"` | | +| global.ingress.internal.host.name | string | `"{{ .Release.Namespace }}-vcluster"` | | | global.ingress.internal.ingressClassName | string | `"nginx-internal"` | | | global.ingress.public.annotations."nginx.ingress.kubernetes.io/backend-protocol" | string | `"HTTPS"` | | | global.ingress.public.annotations."nginx.ingress.kubernetes.io/ssl-passthrough" | string | `"true"` | | @@ -34,7 +39,7 @@ Umbrella chart over vCluster adjusted for Codefresh use cases - mainly in Crossp | global.ingress.public.backendServiceOverride | object | `{}` | Possibility to override backend service name for ingress. If not set default vcluster backend service will be used | | global.ingress.public.enabled | bool | `false` | | | global.ingress.public.host.domain | string | `"example.com"` | | -| global.ingress.public.host.name | string | `"{{ .Release.Name }}"` | | +| global.ingress.public.host.name | string | `"{{ .Release.Namespace }}-vcluster"` | | | global.ingress.public.ingressClassName | string | `"nginx-public"` | | | vcluster.controlPlane.distro.k8s.apiServer.extraArgs[0] | string | `"--oidc-issuer-url=https://dexidp.shared-services.cf-infra.com"` | | | vcluster.controlPlane.distro.k8s.apiServer.extraArgs[1] | string | `"--oidc-client-id=vcluster-login"` | | diff --git a/charts/cf-vcluster/templates/ingresses.tpl b/charts/cf-vcluster/templates/ingresses.tpl index 5a76ce6..b205217 100644 --- a/charts/cf-vcluster/templates/ingresses.tpl +++ b/charts/cf-vcluster/templates/ingresses.tpl @@ -18,11 +18,11 @@ spec: - path: / pathType: {{ $.Values.vcluster.controlPlane.ingress.pathType }} backend: - {{- if $ingress.backendServiceOverride}} + {{- if $.Values.automaticScaleDown.enabled}} service: - name: {{ $ingress.backendServiceOverride.name }} + name: {{ $.Release.Name }}-keda-http-interceptor port: - number: {{ $ingress.backendServiceOverride.port }} + number: {{ $.Values.automaticScaleDown.interceptor.port }} {{- else }} service: name: {{ $.Release.Name }} diff --git a/charts/cf-vcluster/templates/keda-auto-scalewon/HTTPScaledObject.yaml b/charts/cf-vcluster/templates/keda-auto-scalewon/HTTPScaledObject.yaml new file mode 100644 index 0000000..93582a7 --- /dev/null +++ b/charts/cf-vcluster/templates/keda-auto-scalewon/HTTPScaledObject.yaml @@ -0,0 +1,59 @@ +{{- if .Values.automaticScaleDown.enabled }} +{{ $vclusterContext := (index .Subcharts "vcluster")}} +apiVersion: http.keda.sh/v1alpha1 +kind: HTTPScaledObject +metadata: + name: {{ .Release.Name }} + annotations: + # Workaround for idleReplicaCount - https://github.com/kedacore/http-add-on/pull/594 + httpscaledobject.keda.sh/skip-scaledobject-creation: "true" +spec: + hosts: + {{- if .Values.global.ingress.internal.enabled }} + - {{ tpl (printf "%s.%s" .Values.global.ingress.internal.host.name .Values.global.ingress.internal.host.domain) . }} + {{- else if .Values.global.ingress.public.enabled }} + - {{ tpl (printf "%s.%s" .Values.global.ingress.public.host.name .Values.global.ingress.public.host.domain) . }} + {{- else }} + - {{ fail "Cannot enable autoScaledown if no ingress is enabled" }} + {{- end }} + scaleTargetRef: + name: {{ .Release.Name }} + kind: {{ include "vcluster.kind" $vclusterContext }} + apiVersion: apps/v1 + service: {{ .Release.Name }} + port: 443 + replicas: + min: {{ $vclusterContext.Values.controlPlane.statefulSet.highAvailability.replicas }} + max: {{ $vclusterContext.Values.controlPlane.statefulSet.highAvailability.replicas }} + scaledownPeriod: {{ .Values.automaticScaleDown.periodSeconds }} + scalingMetric: + requestRate: + granularity: 1s + targetValue: 1 + window: 1m +--- +# Workaround for idleReplicaCount - https://github.com/kedacore/http-add-on/pull/594 +apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: {{ .Release.Name }} +spec: + advanced: + restoreToOriginalReplicaCount: true + scalingModifiers: {} + initialCooldownPeriod: {{ .Values.automaticScaleDown.initialCooldownPeriod }} + cooldownPeriod: {{ .Values.automaticScaleDown.periodSeconds }} + maxReplicaCount: {{ $vclusterContext.Values.controlPlane.statefulSet.highAvailability.replicas }} + minReplicaCount: {{ $vclusterContext.Values.controlPlane.statefulSet.highAvailability.replicas }} + idleReplicaCount: 0 + pollingInterval: 15 + scaleTargetRef: + apiVersion: apps/v1 + kind: {{ include "vcluster.kind" $vclusterContext }} + name: {{ .Release.Name }} + triggers: + - metadata: + httpScaledObject: {{ .Release.Name }} + scalerAddress: {{ printf "%s:%d" .Values.automaticScaleDown.httpScaler.host (int64 .Values.automaticScaleDown.httpScaler.port) }} + type: external-push +{{- end }} diff --git a/charts/cf-vcluster/templates/keda-auto-scalewon/service.yaml b/charts/cf-vcluster/templates/keda-auto-scalewon/service.yaml new file mode 100644 index 0000000..5f40562 --- /dev/null +++ b/charts/cf-vcluster/templates/keda-auto-scalewon/service.yaml @@ -0,0 +1,9 @@ +{{- if .Values.automaticScaleDown.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-keda-http-interceptor +spec: + type: ExternalName + externalName: {{ .Values.automaticScaleDown.interceptor.host}} +{{- end }} diff --git a/charts/cf-vcluster/values.test.rnd-sandbox.yaml b/charts/cf-vcluster/values.test.rnd-sandbox.yaml index aad66cb..d954a9b 100644 --- a/charts/cf-vcluster/values.test.rnd-sandbox.yaml +++ b/charts/cf-vcluster/values.test.rnd-sandbox.yaml @@ -5,4 +5,8 @@ global: enabled: true className: nginx-internal host: - domain: rnd-sandbox.cf-infra.com + domain: vclusters.rnd-sandbox.cf-infra.com + +automaticScaleDown: + enabled: true + periodSeconds: 60 diff --git a/charts/cf-vcluster/values.yaml b/charts/cf-vcluster/values.yaml index 61f9559..bf89de8 100644 --- a/charts/cf-vcluster/values.yaml +++ b/charts/cf-vcluster/values.yaml @@ -13,7 +13,7 @@ global: # name: "interceptor-service" # port: 80 host: - name: "{{ .Release.Name }}" + name: "{{ .Release.Namespace }}-vcluster" domain: corp.local public: enabled: false @@ -28,7 +28,7 @@ global: nginx.ingress.kubernetes.io/ssl-passthrough: "true" nginx.ingress.kubernetes.io/ssl-redirect: "true" host: - name: "{{ .Release.Name }}" + name: "{{ .Release.Namespace }}-vcluster" domain: example.com vcluster: @@ -138,3 +138,19 @@ vcluster: rbac: clusterRole: enabled: true + +# Automatic scaledown with Keda +automaticScaleDown: + enabled: false + # How many seconds to wait until scaler is active from creation (prevent release failure) + initialCooldownPeriod: 120 + # -- How many seconds of no requests to vcluster until it is scaled down to zero. Defaults to 12 hours (43200s) + periodSeconds: 43200 + # -- Interceptor address on vCluster host + interceptor: + host: "keda-add-ons-http-interceptor-proxy.keda" + port: 8443 + # -- Scaler address on vCluster host + httpScaler: + host: keda-add-ons-http-external-scaler.keda + port: 9090