From 9943957fb7274b8c0ae30aa6f91265512dff9087 Mon Sep 17 00:00:00 2001 From: Anatolii Lapytskyi Date: Mon, 9 Feb 2026 18:03:37 +0100 Subject: [PATCH] feat(helm): add PDB and per-component affinity support (#327) Add PodDisruptionBudget templates for api, control plane, and worker (disabled by default). Support per-component affinity overrides with backward-compatible global affinity fallback. --- helm/hindsight/templates/api-deployment.yaml | 2 +- .../templates/controlplane-deployment.yaml | 2 +- helm/hindsight/templates/pdb.yaml | 56 +++++++++++++++++++ .../templates/worker-statefulset.yaml | 2 +- helm/hindsight/values.yaml | 29 +++++++++- 5 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 helm/hindsight/templates/pdb.yaml diff --git a/helm/hindsight/templates/api-deployment.yaml b/helm/hindsight/templates/api-deployment.yaml index fc81ebd4..eefc3945 100644 --- a/helm/hindsight/templates/api-deployment.yaml +++ b/helm/hindsight/templates/api-deployment.yaml @@ -87,7 +87,7 @@ spec: nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.affinity }} + {{- with (.Values.api.affinity | default .Values.affinity) }} affinity: {{- toYaml . | nindent 8 }} {{- end }} diff --git a/helm/hindsight/templates/controlplane-deployment.yaml b/helm/hindsight/templates/controlplane-deployment.yaml index 3f6b958b..e4859e74 100644 --- a/helm/hindsight/templates/controlplane-deployment.yaml +++ b/helm/hindsight/templates/controlplane-deployment.yaml @@ -71,7 +71,7 @@ spec: nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.affinity }} + {{- with (.Values.controlPlane.affinity | default .Values.affinity) }} affinity: {{- toYaml . | nindent 8 }} {{- end }} diff --git a/helm/hindsight/templates/pdb.yaml b/helm/hindsight/templates/pdb.yaml new file mode 100644 index 00000000..7bdda5f7 --- /dev/null +++ b/helm/hindsight/templates/pdb.yaml @@ -0,0 +1,56 @@ +{{- if and .Values.api.enabled .Values.api.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "hindsight.fullname" . }}-api + labels: + {{- include "hindsight.api.labels" . | nindent 4 }} +spec: + {{- if .Values.api.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.api.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.api.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.api.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "hindsight.api.selectorLabels" . | nindent 6 }} +{{- end }} +--- +{{- if and .Values.controlPlane.enabled .Values.controlPlane.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "hindsight.fullname" . }}-control-plane + labels: + {{- include "hindsight.controlPlane.labels" . | nindent 4 }} +spec: + {{- if .Values.controlPlane.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.controlPlane.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.controlPlane.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.controlPlane.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "hindsight.controlPlane.selectorLabels" . | nindent 6 }} +{{- end }} +--- +{{- if and .Values.worker.enabled .Values.worker.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "hindsight.fullname" . }}-worker + labels: + {{- include "hindsight.worker.labels" . | nindent 4 }} +spec: + {{- if .Values.worker.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.worker.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.worker.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.worker.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "hindsight.worker.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/hindsight/templates/worker-statefulset.yaml b/helm/hindsight/templates/worker-statefulset.yaml index bf4a175a..85cff9f6 100644 --- a/helm/hindsight/templates/worker-statefulset.yaml +++ b/helm/hindsight/templates/worker-statefulset.yaml @@ -99,7 +99,7 @@ spec: nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.affinity }} + {{- with (.Values.worker.affinity | default .Values.affinity) }} affinity: {{- toYaml . | nindent 8 }} {{- end }} diff --git a/helm/hindsight/values.yaml b/helm/hindsight/values.yaml index e39e622e..cb1ba93f 100644 --- a/helm/hindsight/values.yaml +++ b/helm/hindsight/values.yaml @@ -58,6 +58,15 @@ api: timeoutSeconds: 3 failureThreshold: 3 + # Pod disruption budget + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 + + # Pod affinity/anti-affinity (overrides global affinity for this component) + # affinity: {} + # Environment variables env: #HINDSIGHT_API_LLM_PROVIDER: "groq" @@ -122,6 +131,15 @@ worker: # HTTP port for metrics/health (matches service.targetPort) HINDSIGHT_API_WORKER_HTTP_PORT: "8889" + # Pod disruption budget + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 + + # Pod affinity/anti-affinity (overrides global affinity for this component) + # affinity: {} + # Secret environment variables (inherited from api.secrets if not specified) secrets: {} @@ -165,6 +183,15 @@ controlPlane: timeoutSeconds: 3 failureThreshold: 3 + # Pod disruption budget + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 + + # Pod affinity/anti-affinity (overrides global affinity for this component) + # affinity: {} + # Environment variables env: NODE_ENV: "production" @@ -263,7 +290,7 @@ nodeSelector: {} # Tolerations tolerations: [] -# Affinity +# Affinity (applied to all components unless overridden per-component) affinity: {} # Autoscaling