Skip to content

Commit 21bf1a7

Browse files
carlosmt86rossops
andauthored
Feat: Add HPA & PDB Helm Chart Support #13391 (#13512)
* feat(helm): add HPA and PDB support for Django and Celery Beat - Add PodDisruptionBudget for Django pods - Add HorizontalPodAutoscaler for Django pods - Add PodDisruptionBudget for Celery Beat pods - Add HorizontalPodAutoscaler for Celery Beat pods - All resources default to disabled (enabled: false) - Configurable via values.yaml Fixes #13391 * add changes requested * fix .Values.django.replicas * add changes requested * fix lint * move doc to v2.53 * fix Chart.yaml --------- Co-authored-by: Ross E Esposito <ross@defectdojo.com>
1 parent 50450e1 commit 21bf1a7

File tree

11 files changed

+303
-5
lines changed

11 files changed

+303
-5
lines changed

docs/content/en/open_source/upgrading/2.53.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22
title: 'Upgrading to DefectDojo Version 2.53.x'
33
toc_hide: true
44
weight: -20251103
5-
description: Helm chart changes for initializer annotations.
5+
description: Helm chart changes
6+
67
---
78

89
## Helm Chart Changes
910

10-
This release introduces an important change to the Helm chart configuration for the initializer job.
11+
This release introduces an important change to the Helm chart configuration for the initializer job and support for HPA and PDB.
12+
13+
### New values
14+
15+
Added Helm chart support for Celery and Django deployments for Horizontal Pod Autoscaler using `.autoscaling` fields under each section. And Pod Disruption Budget using `.podDisruptionBudget` for any of Celery Beat/Worker or Django deploy
1116

1217
### Breaking changes
1318

helm/defectdojo/Chart.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,7 @@ dependencies:
3535
annotations:
3636
artifacthub.io/prerelease: "true"
3737
artifacthub.io/changes: |
38+
- kind: added
39+
description: Added HPA and PDB for celery worker and Django
3840
- kind: fixed
3941
description: extraAnnotations spec doesn't affect initializer job

helm/defectdojo/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,7 @@ A Helm chart for Kubernetes to install DefectDojo
570570
| celery.worker.annotations | object | `{}` | Annotations for the Celery worker deployment. |
571571
| celery.worker.appSettings.poolType | string | `"solo"` | Performance improved celery worker config when needing to deal with a lot of findings (e.g deduplication ops) poolType: prefork autoscaleMin: 2 autoscaleMax: 8 concurrency: 8 prefetchMultiplier: 128 |
572572
| celery.worker.automountServiceAccountToken | bool | `false` | |
573+
| celery.worker.autoscaling | object | `{"behavior":{},"enabled":false,"maxReplicas":5,"minReplicas":2,"targetCPUUtilizationPercentage":80,"targetMemoryUtilizationPercentage":80}` | Autoscaling configuration for Celery worker deployment. |
573574
| celery.worker.containerSecurityContext | object | `{}` | Container security context for the Celery worker containers. |
574575
| celery.worker.extraEnv | list | `[]` | Additional environment variables injected to Celery worker containers. |
575576
| celery.worker.extraInitContainers | list | `[]` | A list of additional initContainers to run before celery worker containers. |
@@ -578,7 +579,8 @@ A Helm chart for Kubernetes to install DefectDojo
578579
| celery.worker.image | object | `{"digest":"","registry":"","repository":"","tag":""}` | If empty, uses values from images.django.image |
579580
| celery.worker.livenessProbe | object | `{}` | Enable liveness probe for Celery worker containers. ``` exec: command: - bash - -c - celery -A dojo inspect ping -t 5 initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 10 ``` |
580581
| celery.worker.nodeSelector | object | `{}` | |
581-
| celery.worker.podAnnotations | object | `{}` | Annotations for the Celery beat pods. |
582+
| celery.worker.podAnnotations | object | `{}` | Annotations for the Celery worker pods. |
583+
| celery.worker.podDisruptionBudget | object | `{"enabled":false,"minAvailable":"50%","unhealthyPodEvictionPolicy":"AlwaysAllow"}` | Configure pod disruption budgets for Celery worker ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget |
582584
| celery.worker.podSecurityContext | object | `{}` | Pod security context for the Celery worker pods. |
583585
| celery.worker.readinessProbe | object | `{}` | Enable readiness probe for Celery worker container. |
584586
| celery.worker.replicas | int | `1` | |
@@ -587,6 +589,7 @@ A Helm chart for Kubernetes to install DefectDojo
587589
| celery.worker.resources.requests.cpu | string | `"100m"` | |
588590
| celery.worker.resources.requests.memory | string | `"128Mi"` | |
589591
| celery.worker.startupProbe | object | `{}` | Enable startup probe for Celery worker container. |
592+
| celery.worker.terminationGracePeriodSeconds | int | `300` | |
590593
| celery.worker.tolerations | list | `[]` | |
591594
| cloudsql | object | `{"containerSecurityContext":{},"enable_iam_login":false,"enabled":false,"extraEnv":[],"extraVolumeMounts":[],"image":{"pullPolicy":"IfNotPresent","repository":"gcr.io/cloudsql-docker/gce-proxy","tag":"1.37.9"},"instance":"","resources":{},"use_private_ip":false,"verbose":true}` | Google CloudSQL support in GKE via gce-proxy |
592595
| cloudsql.containerSecurityContext | object | `{}` | Optional: security context for the CloudSQL proxy container. |
@@ -612,6 +615,7 @@ A Helm chart for Kubernetes to install DefectDojo
612615
| django.affinity | object | `{}` | |
613616
| django.annotations | object | `{}` | |
614617
| django.automountServiceAccountToken | bool | `false` | |
618+
| django.autoscaling | object | `{"behavior":{},"enabled":false,"maxReplicas":5,"minReplicas":2,"targetCPUUtilizationPercentage":80,"targetMemoryUtilizationPercentage":80}` | Autoscaling configuration for the Django deployment. |
615619
| django.extraEnv | list | `[]` | Additional environment variables injected to all Django containers and initContainers. |
616620
| django.extraInitContainers | list | `[]` | A list of additional initContainers to run before the uwsgi and nginx containers. |
617621
| django.extraVolumeMounts | list | `[]` | Array of additional volume mount points common to all containers and initContainers. |
@@ -639,11 +643,13 @@ A Helm chart for Kubernetes to install DefectDojo
639643
| django.nginx.tls.enabled | bool | `false` | |
640644
| django.nginx.tls.generateCertificate | bool | `false` | |
641645
| django.nodeSelector | object | `{}` | |
646+
| django.podDisruptionBudget | object | `{"enabled":false,"minAvailable":"50%","unhealthyPodEvictionPolicy":"AlwaysAllow"}` | Configure pod disruption budgets for django ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget |
642647
| django.podSecurityContext | object | `{"fsGroup":1001}` | Pod security context for the Django pods. |
643648
| django.replicas | int | `1` | |
644649
| django.service.annotations | object | `{}` | |
645650
| django.service.type | string | `""` | |
646651
| django.strategy | object | `{}` | |
652+
| django.terminationGracePeriodSeconds | int | `60` | |
647653
| django.tolerations | list | `[]` | |
648654
| django.uwsgi.appSettings.maxFd | int | `0` | Use this value to set the maximum number of file descriptors. If set to 0 will be detected by uwsgi e.g. 102400 |
649655
| django.uwsgi.appSettings.processes | int | `4` | |

helm/defectdojo/templates/celery-worker-deployment.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ spec:
170170
affinity:
171171
{{- toYaml . | nindent 8 }}
172172
{{- end }}
173+
{{- with .Values.celery.worker.terminationGracePeriodSeconds }}
174+
terminationGracePeriodSeconds:
175+
{{- toYaml . | nindent 8 }}
176+
{{- end }}
173177
{{- with .Values.celery.worker.tolerations }}
174178
tolerations:
175179
{{- toYaml . | nindent 8 }}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{{- if .Values.celery.worker.autoscaling.enabled -}}
2+
{{- $fullName := include "defectdojo.fullname" . -}}
3+
apiVersion: autoscaling/v2
4+
kind: HorizontalPodAutoscaler
5+
metadata:
6+
{{- with mergeOverwrite dict .Values.extraAnnotations .Values.celery.annotations .Values.celery.worker.annotations }}
7+
annotations:
8+
{{- range $key, $value := . }}
9+
{{ $key }}: {{ quote $value }}
10+
{{- end }}
11+
{{- end }}
12+
name: {{ $fullName }}-celery-worker
13+
namespace: {{ .Release.Namespace }}
14+
labels:
15+
defectdojo.org/component: celery
16+
defectdojo.org/subcomponent: worker
17+
app.kubernetes.io/name: {{ include "defectdojo.name" . }}
18+
app.kubernetes.io/instance: {{ .Release.Name }}
19+
app.kubernetes.io/managed-by: {{ .Release.Service }}
20+
helm.sh/chart: {{ include "defectdojo.chart" . }}
21+
{{- range $key, $value := .Values.extraLabels }}
22+
{{ $key }}: {{ quote $value }}
23+
{{- end }}
24+
spec:
25+
scaleTargetRef:
26+
apiVersion: apps/v1
27+
kind: "Deployment"
28+
name: {{ $fullName }}-celery-worker
29+
minReplicas: {{ .Values.celery.worker.autoscaling.minReplicas }}
30+
maxReplicas: {{ .Values.celery.worker.autoscaling.maxReplicas }}
31+
metrics:
32+
{{- with .Values.celery.worker.autoscaling.targetCPUUtilizationPercentage }}
33+
- type: Resource
34+
resource:
35+
name: cpu
36+
target:
37+
averageUtilization: {{ . }}
38+
type: Utilization
39+
{{- end }}
40+
{{- with .Values.celery.worker.autoscaling.targetMemoryUtilizationPercentage }}
41+
- type: Resource
42+
resource:
43+
name: memory
44+
target:
45+
averageUtilization: {{ . }}
46+
type: Utilization
47+
{{- end }}
48+
{{- with .Values.celery.worker.autoscaling.behavior }}
49+
behavior: {{ toYaml .Values.celery.worker.autoscaling.behavior | nindent 4 }}
50+
{{- end }}
51+
{{- end }}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{{- if and .Values.celery.worker.podDisruptionBudget.enabled (or (gt (int .Values.celery.worker.replicas) 1) .Values.celery.worker.autoscaling.enabled) }}
2+
{{- $fullName := include "defectdojo.fullname" . -}}
3+
apiVersion: policy/v1
4+
kind: PodDisruptionBudget
5+
metadata:
6+
{{- with mergeOverwrite dict .Values.extraAnnotations .Values.celery.annotations .Values.celery.worker.annotations }}
7+
annotations:
8+
{{- range $key, $value := . }}
9+
{{ $key }}: {{ quote $value }}
10+
{{- end }}
11+
{{- end }}
12+
labels:
13+
defectdojo.org/component: celery
14+
defectdojo.org/subcomponent: worker
15+
app.kubernetes.io/name: {{ include "defectdojo.name" . }}
16+
app.kubernetes.io/instance: {{ .Release.Name }}
17+
app.kubernetes.io/managed-by: {{ .Release.Service }}
18+
helm.sh/chart: {{ include "defectdojo.chart" . }}
19+
{{- range $key, $value := .Values.extraLabels }}
20+
{{ $key }}: {{ quote $value }}
21+
{{- end }}
22+
name: {{ $fullName }}-celery-worker
23+
namespace: {{ .Release.Namespace }}
24+
spec:
25+
selector:
26+
matchLabels:
27+
app.kubernetes.io/name: {{ include "defectdojo.name" . }}
28+
defectdojo.org/component: celery
29+
defectdojo.org/subcomponent: worker
30+
{{ toYaml (omit .Values.celery.worker.podDisruptionBudget "enabled" ) | indent 2 }}
31+
{{- end }}

helm/defectdojo/templates/django-deployment.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ spec:
372372
affinity:
373373
{{- toYaml . | nindent 8 }}
374374
{{- end }}
375+
{{- with .Values.django.terminationGracePeriodSeconds }}
376+
terminationGracePeriodSeconds:
377+
{{- toYaml . | nindent 8 }}
378+
{{- end }}
375379
{{- with .Values.django.tolerations }}
376380
tolerations:
377381
{{- toYaml . | nindent 8 }}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{{- if .Values.django.autoscaling.enabled -}}
2+
{{- $fullName := include "defectdojo.fullname" . -}}
3+
apiVersion: autoscaling/v2
4+
kind: HorizontalPodAutoscaler
5+
metadata:
6+
{{- with mergeOverwrite dict .Values.extraAnnotations .Values.django.annotations }}
7+
annotations:
8+
{{- range $key, $value := . }}
9+
{{ $key }}: {{ quote $value }}
10+
{{- end }}
11+
{{- end }}
12+
name: {{ $fullName }}-django
13+
namespace: {{ .Release.Namespace }}
14+
labels:
15+
defectdojo.org/component: django
16+
app.kubernetes.io/name: {{ include "defectdojo.name" . }}
17+
app.kubernetes.io/instance: {{ .Release.Name }}
18+
app.kubernetes.io/managed-by: {{ .Release.Service }}
19+
helm.sh/chart: {{ include "defectdojo.chart" . }}
20+
{{- range $key, $value := .Values.extraLabels }}
21+
{{ $key }}: {{ quote $value }}
22+
{{- end }}
23+
spec:
24+
scaleTargetRef:
25+
apiVersion: apps/v1
26+
kind: "Deployment"
27+
name: {{ $fullName }}-django
28+
minReplicas: {{ .Values.django.autoscaling.minReplicas }}
29+
maxReplicas: {{ .Values.django.autoscaling.maxReplicas }}
30+
metrics:
31+
{{- with .Values.django.autoscaling.targetCPUUtilizationPercentage }}
32+
- type: Resource
33+
resource:
34+
name: cpu
35+
target:
36+
averageUtilization: {{ . }}
37+
type: Utilization
38+
{{- end }}
39+
{{- with .Values.django.autoscaling.targetMemoryUtilizationPercentage }}
40+
- type: Resource
41+
resource:
42+
name: memory
43+
target:
44+
averageUtilization: {{ . }}
45+
type: Utilization
46+
{{- end }}
47+
{{- with .Values.django.autoscaling.behavior }}
48+
behavior: {{ toYaml .Values.django.autoscaling.behavior | nindent 4 }}
49+
{{- end }}
50+
{{- end }}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{{- if and .Values.django.podDisruptionBudget.enabled (or (gt (int .Values.django.replicas) 1) .Values.django.autoscaling.enabled) }}
2+
{{- $fullName := include "defectdojo.fullname" . -}}
3+
apiVersion: policy/v1
4+
kind: PodDisruptionBudget
5+
metadata:
6+
{{- with mergeOverwrite dict .Values.extraAnnotations .Values.django.annotations }}
7+
annotations:
8+
{{- range $key, $value := . }}
9+
{{ $key }}: {{ quote $value }}
10+
{{- end }}
11+
{{- end }}
12+
labels:
13+
defectdojo.org/component: django
14+
app.kubernetes.io/name: {{ include "defectdojo.name" . }}
15+
app.kubernetes.io/instance: {{ .Release.Name }}
16+
app.kubernetes.io/managed-by: {{ .Release.Service }}
17+
helm.sh/chart: {{ include "defectdojo.chart" . }}
18+
{{- range $key, $value := .Values.extraLabels }}
19+
{{ $key }}: {{ quote $value }}
20+
{{- end }}
21+
name: {{ $fullName }}-django
22+
namespace: {{ .Release.Namespace }}
23+
spec:
24+
selector:
25+
matchLabels:
26+
app.kubernetes.io/name: {{ include "defectdojo.name" . }}
27+
defectdojo.org/component: django
28+
{{ toYaml (omit .Values.django.podDisruptionBudget "enabled" ) | indent 2 }}
29+
{{- end }}

helm/defectdojo/values.schema.json

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,30 @@
181181
"automountServiceAccountToken": {
182182
"type": "boolean"
183183
},
184+
"autoscaling": {
185+
"description": "Autoscaling configuration for Celery worker deployment.",
186+
"type": "object",
187+
"properties": {
188+
"behavior": {
189+
"type": "object"
190+
},
191+
"enabled": {
192+
"type": "boolean"
193+
},
194+
"maxReplicas": {
195+
"type": "integer"
196+
},
197+
"minReplicas": {
198+
"type": "integer"
199+
},
200+
"targetCPUUtilizationPercentage": {
201+
"type": "integer"
202+
},
203+
"targetMemoryUtilizationPercentage": {
204+
"type": "integer"
205+
}
206+
}
207+
},
184208
"containerSecurityContext": {
185209
"description": "Container security context for the Celery worker containers.",
186210
"type": "object"
@@ -227,9 +251,24 @@
227251
"type": "object"
228252
},
229253
"podAnnotations": {
230-
"description": "Annotations for the Celery beat pods.",
254+
"description": "Annotations for the Celery worker pods.",
231255
"type": "object"
232256
},
257+
"podDisruptionBudget": {
258+
"description": "Configure pod disruption budgets for Celery worker ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget",
259+
"type": "object",
260+
"properties": {
261+
"enabled": {
262+
"type": "boolean"
263+
},
264+
"minAvailable": {
265+
"type": "string"
266+
},
267+
"unhealthyPodEvictionPolicy": {
268+
"type": "string"
269+
}
270+
}
271+
},
233272
"podSecurityContext": {
234273
"description": "Pod security context for the Celery worker pods.",
235274
"type": "object"
@@ -272,6 +311,10 @@
272311
"description": "Enable startup probe for Celery worker container.",
273312
"type": "object"
274313
},
314+
"terminationGracePeriodSeconds": {
315+
"description": "Termination grace period seconds for Celery worker pods.",
316+
"type": "integer"
317+
},
275318
"tolerations": {
276319
"type": "array"
277320
}
@@ -431,6 +474,30 @@
431474
"automountServiceAccountToken": {
432475
"type": "boolean"
433476
},
477+
"autoscaling": {
478+
"description": "Autoscaling configuration for the Django deployment.",
479+
"type": "object",
480+
"properties": {
481+
"behavior": {
482+
"type": "object"
483+
},
484+
"enabled": {
485+
"type": "boolean"
486+
},
487+
"maxReplicas": {
488+
"type": "integer"
489+
},
490+
"minReplicas": {
491+
"type": "integer"
492+
},
493+
"targetCPUUtilizationPercentage": {
494+
"type": "integer"
495+
},
496+
"targetMemoryUtilizationPercentage": {
497+
"type": "integer"
498+
}
499+
}
500+
},
434501
"extraEnv": {
435502
"description": "Additional environment variables injected to all Django containers and initContainers.",
436503
"type": "array"
@@ -596,6 +663,21 @@
596663
"nodeSelector": {
597664
"type": "object"
598665
},
666+
"podDisruptionBudget": {
667+
"description": "Configure pod disruption budgets for django ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget",
668+
"type": "object",
669+
"properties": {
670+
"enabled": {
671+
"type": "boolean"
672+
},
673+
"minAvailable": {
674+
"type": "string"
675+
},
676+
"unhealthyPodEvictionPolicy": {
677+
"type": "string"
678+
}
679+
}
680+
},
599681
"podSecurityContext": {
600682
"description": "Pod security context for the Django pods.",
601683
"type": "object",
@@ -622,6 +704,10 @@
622704
"strategy": {
623705
"type": "object"
624706
},
707+
"terminationGracePeriodSeconds": {
708+
"description": "Termination grace period seconds for django pods.",
709+
"type": "integer"
710+
},
625711
"tolerations": {
626712
"type": "array"
627713
},

0 commit comments

Comments
 (0)