Compare commits

...

1 Commits

Author SHA1 Message Date
Armel Soro c1b06c96dd
feat: Support autoscaling via HPA (#268)
* feat: expose autoscaling configuration using the HPA resource

Signed-off-by: Armel Soro <asoro@redhat.com>

* Set the Deployment replicas only if autoscaling is not enabled

When autoscaling is enabled, the HPA controller controls the number of replicas [1]

[1] https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/\#migrating-deployments-and-statefulsets-to-horizontal-autoscaling

Signed-off-by: Armel Soro <asoro@redhat.com>

* Add CI values file with autoscaling enabled

Signed-off-by: Armel Soro <asoro@redhat.com>

* Bump chart version

This is a backward-compatible change

Signed-off-by: Armel Soro <asoro@redhat.com>

* Update values schema

Signed-off-by: Armel Soro <asoro@redhat.com>

* Update README

Signed-off-by: Armel Soro <asoro@redhat.com>

---------

Signed-off-by: Armel Soro <asoro@redhat.com>
2025-07-09 21:16:13 +01:00
8 changed files with 129 additions and 3 deletions

View File

@ -38,4 +38,4 @@ sources:
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 2.5.3
version: 2.6.0

View File

@ -2,7 +2,7 @@
# Backstage Helm Chart
[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/backstage)](https://artifacthub.io/packages/search?repo=backstage)
![Version: 2.5.3](https://img.shields.io/badge/Version-2.5.3-informational?style=flat-square)
![Version: 2.6.0](https://img.shields.io/badge/Version-2.6.0-informational?style=flat-square)
![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
A Helm chart for deploying a Backstage application
@ -117,6 +117,7 @@ Kubernetes: `>= 1.19.0-0`
| backstage.annotations | Additional custom annotations for the `Deployment` resource | object | `{}` |
| backstage.appConfig | Generates ConfigMap and configures it in the Backstage pods | object | `{}` |
| backstage.args | Backstage container command arguments | list | `[]` |
| backstage.autoscaling | Autoscaling configuration. <br /> Ref: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/ | object | `{"enabled":false,"maxReplicas":100,"minReplicas":1,"targetCPUUtilizationPercentage":80}` |
| backstage.command | Backstage container command | list | `["node","packages/backend"]` |
| backstage.containerPorts | Container ports on the Deployment | object | `{"backend":7007}` |
| backstage.containerSecurityContext | Security settings for a Container. <br /> Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container | object | `{}` |

View File

@ -0,0 +1,7 @@
backstage:
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 75
targetMemoryUtilizationPercentage: 90

View File

@ -20,7 +20,9 @@ metadata:
{{- include "common.tplvalues.render" ( dict "value" .Values.backstage.annotations "context" $) | nindent 4 }}
{{- end }}
spec:
{{- if not .Values.backstage.autoscaling.enabled }}
replicas: {{ .Values.backstage.replicas }}
{{- end }}
revisionHistoryLimit: {{ .Values.backstage.revisionHistoryLimit }}
selector:
matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }}

View File

@ -0,0 +1,43 @@
{{- if .Values.backstage.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "common.names.fullname" . }}
namespace: {{ .Release.Namespace | quote }}
labels: {{ include "common.labels.standard" . | nindent 4 }}
app.kubernetes.io/component: backstage
{{- if .Values.commonLabels }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }}
{{- end }}
annotations:
{{- if .Values.commonAnnotations }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
{{- end }}
{{- if .Values.backstage.annotations }}
{{- include "common.tplvalues.render" ( dict "value" .Values.backstage.annotations "context" $) | nindent 4 }}
{{- end }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "common.names.fullname" . }}
minReplicas: {{ .Values.backstage.autoscaling.minReplicas }}
maxReplicas: {{ .Values.backstage.autoscaling.maxReplicas }}
metrics:
{{- if .Values.backstage.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.backstage.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.backstage.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.backstage.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

View File

@ -792,6 +792,38 @@
"title": "Backstage container command arguments",
"type": "array"
},
"autoscaling": {
"additionalProperties": false,
"properties": {
"enabled": {
"default": false,
"description": "Enable autoscaling",
"title": "Backstage Autoscaling",
"type": "boolean"
},
"maxReplicas": {
"default": 100,
"title": "Maximum number of Backstage pod replicas that the autoscaler is allowed to scale up to",
"type": "integer"
},
"minReplicas": {
"default": 1,
"title": "Minimum number of Backstage pod replicas that the autoscaler is allowed to scale down to",
"type": "integer"
},
"targetCPUUtilizationPercentage": {
"default": 80,
"title": "Percentage of CPU that each Backstage pod should be using on average before the autoscaler decides to scale",
"type": "integer"
},
"targetMemoryUtilizationPercentage": {
"title": "Percentage of memory that each Backstage pod should be using on average before the autoscaler decides to scale",
"type": "integer"
}
},
"title": "Autoscaling parameters",
"type": "object"
},
"command": {
"default": [
"node",
@ -3293,7 +3325,7 @@
"description": "Represents a Glusterfs mount that lasts the lifetime of a pod. Glusterfs volumes do not support ownership management or SELinux relabeling.",
"properties": {
"endpoints": {
"description": "endpoints is the endpoint name that details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod",
"description": "endpoints is the endpoint name that details Glusterfs topology.",
"type": "string"
},
"path": {

View File

@ -275,6 +275,38 @@
}
}
},
"autoscaling": {
"title": "Autoscaling parameters",
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"description": "Enable autoscaling",
"title": "Backstage Autoscaling",
"type": "boolean",
"default": false
},
"minReplicas": {
"title": "Minimum number of Backstage pod replicas that the autoscaler is allowed to scale down to",
"type": "integer",
"default": 1
},
"maxReplicas": {
"title": "Maximum number of Backstage pod replicas that the autoscaler is allowed to scale up to",
"type": "integer",
"default": 100
},
"targetCPUUtilizationPercentage": {
"title": "Percentage of CPU that each Backstage pod should be using on average before the autoscaler decides to scale",
"type": "integer",
"default": 80
},
"targetMemoryUtilizationPercentage": {
"title": "Percentage of memory that each Backstage pod should be using on average before the autoscaler decides to scale",
"type": "integer"
}
}
},
"pdb": {
"title": "PDB parameters",
"type": "object",

View File

@ -140,6 +140,15 @@ backstage:
minAvailable: ""
maxUnavailable: ""
# -- Autoscaling configuration.
# <br /> Ref: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
# -- Container ports on the Deployment
containerPorts:
backend: 7007