From 0029760743e6d19bdb4d4985436fc42a20969f2c Mon Sep 17 00:00:00 2001 From: "avi@robusta.dev" Date: Thu, 18 Jun 2026 10:15:03 +0300 Subject: [PATCH 1/2] ROB-397 - optional global imagePullSecret for Helm chart Add global.imagePullSecrets that applies to the runner, kubewatch and the runtime pods created by the runner (KRR, Popeye via the runner ServiceAccount). A per-component imagePullSecrets overrides the global one; an empty global leaves the rendered output unchanged (backwards compatible). Also adds imagePullSecrets support to the forwarder ServiceAccount, which previously had none, and documents the option in proxies.rst. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/setup-robusta/proxies.rst | 13 +++++++++++++ .../templates/forwarder-service-account.yaml | 5 +++++ helm/robusta/templates/forwarder.yaml | 5 +++-- helm/robusta/templates/runner-service-account.yaml | 5 +++-- helm/robusta/templates/runner.yaml | 5 +++-- helm/robusta/values.yaml | 5 +++++ 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/docs/setup-robusta/proxies.rst b/docs/setup-robusta/proxies.rst index 12b6764c7..547eea3c7 100644 --- a/docs/setup-robusta/proxies.rst +++ b/docs/setup-robusta/proxies.rst @@ -113,6 +113,19 @@ When deploying Robusta in a tightly restricted environment, the runner needs out If you mirror images to a private registry, override ``image.registry`` (and the per-component ``image:`` fields) in your Helm values and you can drop the public registries from the allowlist. +If your private registry requires authentication, set ``global.imagePullSecrets``. This applies the +pull secret to every component at once — the runner, kubewatch, HolmesGPT, and the pods the runner +launches at runtime (e.g. KRR, Popeye, via the runner ServiceAccount): + +.. code-block:: yaml + + global: + imagePullSecrets: + - name: my-registry-secret + +A per-component value (e.g. ``runner.imagePullSecrets``, ``kubewatch.imagePullSecrets``) overrides the +global one for that component. Leaving ``global.imagePullSecrets`` empty keeps the previous behavior. + Verifying the Allowlist ---------------------------------------- diff --git a/helm/robusta/templates/forwarder-service-account.yaml b/helm/robusta/templates/forwarder-service-account.yaml index 3cdfa1b7c..bf0d0bc8c 100644 --- a/helm/robusta/templates/forwarder-service-account.yaml +++ b/helm/robusta/templates/forwarder-service-account.yaml @@ -123,6 +123,11 @@ metadata: {{- toYaml . | nindent 4}} {{- end }} {{- end }} +{{- $pullSecrets := .Values.kubewatch.imagePullSecrets | default (.Values.global.imagePullSecrets | default list) }} +{{- if $pullSecrets }} +imagePullSecrets: +{{- toYaml $pullSecrets | nindent 2}} +{{- end }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/helm/robusta/templates/forwarder.yaml b/helm/robusta/templates/forwarder.yaml index 94e5df017..5139e8ce3 100644 --- a/helm/robusta/templates/forwarder.yaml +++ b/helm/robusta/templates/forwarder.yaml @@ -31,9 +31,10 @@ spec: serviceAccountName: {{ include "robusta.fullname" . }}-forwarder-service-account {{- end }} automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} - {{- if .Values.kubewatch.imagePullSecrets }} + {{- $pullSecrets := .Values.kubewatch.imagePullSecrets | default (.Values.global.imagePullSecrets | default list) }} + {{- if $pullSecrets }} imagePullSecrets: - {{- toYaml .Values.kubewatch.imagePullSecrets | nindent 6 }} + {{- toYaml $pullSecrets | nindent 6 }} {{- end }} {{- with .Values.kubewatch.securityContext.pod }} securityContext: diff --git a/helm/robusta/templates/runner-service-account.yaml b/helm/robusta/templates/runner-service-account.yaml index 434413377..817aef811 100644 --- a/helm/robusta/templates/runner-service-account.yaml +++ b/helm/robusta/templates/runner-service-account.yaml @@ -556,9 +556,10 @@ metadata: {{- toYaml . | nindent 4}} {{- end }} {{- end }} -{{- if .Values.runnerServiceAccount.imagePullSecrets }} +{{- $pullSecrets := .Values.runnerServiceAccount.imagePullSecrets | default (.Values.global.imagePullSecrets | default list) }} +{{- if $pullSecrets }} imagePullSecrets: -{{- toYaml .Values.runnerServiceAccount.imagePullSecrets | nindent 2}} +{{- toYaml $pullSecrets | nindent 2}} {{- end }} --- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/helm/robusta/templates/runner.yaml b/helm/robusta/templates/runner.yaml index ea6e659b7..45fed018c 100644 --- a/helm/robusta/templates/runner.yaml +++ b/helm/robusta/templates/runner.yaml @@ -34,9 +34,10 @@ spec: serviceAccountName: {{ include "robusta.fullname" . }}-runner-service-account {{- end }} automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} - {{- if .Values.runner.imagePullSecrets }} + {{- $pullSecrets := .Values.runner.imagePullSecrets | default (.Values.global.imagePullSecrets | default list) }} + {{- if $pullSecrets }} imagePullSecrets: - {{- toYaml .Values.runner.imagePullSecrets | nindent 6 }} + {{- toYaml $pullSecrets | nindent 6 }} {{- end }} {{- with .Values.runner.securityContext.pod }} securityContext: diff --git a/helm/robusta/values.yaml b/helm/robusta/values.yaml index bcd2bac2f..37ec8bc0e 100644 --- a/helm/robusta/values.yaml +++ b/helm/robusta/values.yaml @@ -33,6 +33,11 @@ clusterZone: "" global: clusterDomain: "cluster.local" + # Optional image pull secrets applied globally to the runner, kubewatch, holmes, + # and runtime pods created by the runner (e.g. KRR, Popeye, via the runner ServiceAccount). + # A per-component imagePullSecrets (e.g. runner.imagePullSecrets) overrides this global + # value for that component. Leave empty to keep existing behavior. + imagePullSecrets: [] automountServiceAccountToken: true From c7a37e8e46d19fb846e250a20cfbe338b34e07fd Mon Sep 17 00:00:00 2001 From: "avi@robusta.dev" Date: Thu, 18 Jun 2026 10:23:50 +0300 Subject: [PATCH 2/2] ROB-397 - optional global imagePullSecret for Helm chart Add global.imagePullSecrets that applies to the runner, kubewatch and the runtime pods created by the runner (KRR, Popeye via the runner ServiceAccount). A per-component imagePullSecrets overrides the global one; an empty global leaves the rendered output unchanged (backwards compatible). Documents the option in proxies.rst. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/setup-robusta/proxies.rst | 15 +++++++++++---- .../templates/forwarder-service-account.yaml | 5 ----- helm/robusta/templates/forwarder.yaml | 2 +- .../robusta/templates/runner-service-account.yaml | 2 +- helm/robusta/templates/runner.yaml | 2 +- helm/robusta/values.yaml | 12 ++++++++---- 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/docs/setup-robusta/proxies.rst b/docs/setup-robusta/proxies.rst index 547eea3c7..392086cf5 100644 --- a/docs/setup-robusta/proxies.rst +++ b/docs/setup-robusta/proxies.rst @@ -114,8 +114,9 @@ When deploying Robusta in a tightly restricted environment, the runner needs out If you mirror images to a private registry, override ``image.registry`` (and the per-component ``image:`` fields) in your Helm values and you can drop the public registries from the allowlist. If your private registry requires authentication, set ``global.imagePullSecrets``. This applies the -pull secret to every component at once — the runner, kubewatch, HolmesGPT, and the pods the runner -launches at runtime (e.g. KRR, Popeye, via the runner ServiceAccount): +pull secret to the runner, kubewatch, and the pods the runner launches at runtime (e.g. KRR, Popeye, +via the runner ServiceAccount). To also cover HolmesGPT, set ``holmes.imagePullSecrets`` — HolmesGPT +is a subchart, so set it explicitly alongside the global value: .. code-block:: yaml @@ -123,8 +124,14 @@ launches at runtime (e.g. KRR, Popeye, via the runner ServiceAccount): imagePullSecrets: - name: my-registry-secret -A per-component value (e.g. ``runner.imagePullSecrets``, ``kubewatch.imagePullSecrets``) overrides the -global one for that component. Leaving ``global.imagePullSecrets`` empty keeps the previous behavior. + # HolmesGPT is a subchart — set its pull secret as well + holmes: + imagePullSecrets: + - name: my-registry-secret + +A per-component value (e.g. ``runner.imagePullSecrets``, ``kubewatch.imagePullSecrets``, +``holmes.imagePullSecrets``) overrides the global one for that component. Leaving +``global.imagePullSecrets`` empty keeps the previous behavior. Verifying the Allowlist ---------------------------------------- diff --git a/helm/robusta/templates/forwarder-service-account.yaml b/helm/robusta/templates/forwarder-service-account.yaml index bf0d0bc8c..3cdfa1b7c 100644 --- a/helm/robusta/templates/forwarder-service-account.yaml +++ b/helm/robusta/templates/forwarder-service-account.yaml @@ -123,11 +123,6 @@ metadata: {{- toYaml . | nindent 4}} {{- end }} {{- end }} -{{- $pullSecrets := .Values.kubewatch.imagePullSecrets | default (.Values.global.imagePullSecrets | default list) }} -{{- if $pullSecrets }} -imagePullSecrets: -{{- toYaml $pullSecrets | nindent 2}} -{{- end }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/helm/robusta/templates/forwarder.yaml b/helm/robusta/templates/forwarder.yaml index 5139e8ce3..99c7d577e 100644 --- a/helm/robusta/templates/forwarder.yaml +++ b/helm/robusta/templates/forwarder.yaml @@ -31,7 +31,7 @@ spec: serviceAccountName: {{ include "robusta.fullname" . }}-forwarder-service-account {{- end }} automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} - {{- $pullSecrets := .Values.kubewatch.imagePullSecrets | default (.Values.global.imagePullSecrets | default list) }} + {{- $pullSecrets := .Values.kubewatch.imagePullSecrets | default .Values.global.imagePullSecrets }} {{- if $pullSecrets }} imagePullSecrets: {{- toYaml $pullSecrets | nindent 6 }} diff --git a/helm/robusta/templates/runner-service-account.yaml b/helm/robusta/templates/runner-service-account.yaml index 817aef811..5d808c874 100644 --- a/helm/robusta/templates/runner-service-account.yaml +++ b/helm/robusta/templates/runner-service-account.yaml @@ -556,7 +556,7 @@ metadata: {{- toYaml . | nindent 4}} {{- end }} {{- end }} -{{- $pullSecrets := .Values.runnerServiceAccount.imagePullSecrets | default (.Values.global.imagePullSecrets | default list) }} +{{- $pullSecrets := .Values.runnerServiceAccount.imagePullSecrets | default .Values.global.imagePullSecrets }} {{- if $pullSecrets }} imagePullSecrets: {{- toYaml $pullSecrets | nindent 2}} diff --git a/helm/robusta/templates/runner.yaml b/helm/robusta/templates/runner.yaml index 45fed018c..0d0966cf5 100644 --- a/helm/robusta/templates/runner.yaml +++ b/helm/robusta/templates/runner.yaml @@ -34,7 +34,7 @@ spec: serviceAccountName: {{ include "robusta.fullname" . }}-runner-service-account {{- end }} automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} - {{- $pullSecrets := .Values.runner.imagePullSecrets | default (.Values.global.imagePullSecrets | default list) }} + {{- $pullSecrets := .Values.runner.imagePullSecrets | default .Values.global.imagePullSecrets }} {{- if $pullSecrets }} imagePullSecrets: {{- toYaml $pullSecrets | nindent 6 }} diff --git a/helm/robusta/values.yaml b/helm/robusta/values.yaml index 37ec8bc0e..f4582bbe2 100644 --- a/helm/robusta/values.yaml +++ b/helm/robusta/values.yaml @@ -33,10 +33,11 @@ clusterZone: "" global: clusterDomain: "cluster.local" - # Optional image pull secrets applied globally to the runner, kubewatch, holmes, - # and runtime pods created by the runner (e.g. KRR, Popeye, via the runner ServiceAccount). - # A per-component imagePullSecrets (e.g. runner.imagePullSecrets) overrides this global - # value for that component. Leave empty to keep existing behavior. + # Optional image pull secrets applied to the runner, kubewatch, and the runtime pods + # created by the runner (e.g. KRR, Popeye, via the runner ServiceAccount). + # A component's own imagePullSecrets (e.g. runner.imagePullSecrets), when set, is used + # instead of this global; otherwise the component inherits this global. Leave empty to + # keep existing behavior. HolmesGPT is a separate subchart - set holmes.imagePullSecrets. imagePullSecrets: [] automountServiceAccountToken: true @@ -653,6 +654,7 @@ kubewatch: tolerations: [] annotations: {} nodeSelector: ~ + # set to override global.imagePullSecrets for kubewatch; leave empty to inherit the global imagePullSecrets: [] config: namespace: "" @@ -712,6 +714,7 @@ grafanaRenderer: # parameters for the robusta runner service account runnerServiceAccount: # image pull secrets added to the runner service account. Any pod using the service account will get those + # set to override global.imagePullSecrets; leave empty to inherit the global imagePullSecrets: [] # Additional annotations for the ServiceAccount. annotations: {} @@ -742,6 +745,7 @@ runner: annotations: {} nodeSelector: ~ customClusterRoleRules: [] + # set to override global.imagePullSecrets for the runner; leave empty to inherit the global imagePullSecrets: [] extraVolumes: [] extraVolumeMounts: []