This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 7f53be7f43f Add registry.secretNames and registry.connections options
to Helm chart (#58094)
7f53be7f43f is described below
commit 7f53be7f43ff441ee8c0c8c58b8ea1c7b56144e7
Author: Jorge Rocamora <[email protected]>
AuthorDate: Sun Nov 9 22:47:43 2025 +0100
Add registry.secretNames and registry.connections options to Helm chart
(#58094)
Co-authored-by: Your Name <[email protected]>
---
chart/docs/production-guide.rst | 6 ++-
chart/files/pod-template-file.kubernetes-helm-yaml | 5 +-
chart/newsfragments/57615.misc.rst | 1 +
chart/templates/_helpers.yaml | 16 +++++-
.../api-server/api-server-deployment.yaml | 5 +-
chart/templates/cleanup/cleanup-cronjob.yaml | 5 +-
.../dag-processor/dag-processor-deployment.yaml | 5 +-
chart/templates/flower/flower-deployment.yaml | 5 +-
chart/templates/jobs/create-user-job.yaml | 5 +-
chart/templates/jobs/migrate-database-job.yaml | 5 +-
.../templates/pgbouncer/pgbouncer-deployment.yaml | 5 +-
chart/templates/redis/redis-statefulset.yaml | 5 +-
.../templates/scheduler/scheduler-deployment.yaml | 5 +-
chart/templates/secrets/registry-secret.yaml | 2 +-
chart/templates/statsd/statsd-deployment.yaml | 5 +-
.../templates/triggerer/triggerer-deployment.yaml | 5 +-
.../templates/webserver/webserver-deployment.yaml | 5 +-
chart/templates/workers/worker-deployment.yaml | 5 +-
chart/values.schema.json | 21 +++++++-
chart/values.yaml | 11 +++-
.../helm_tests/airflow_aux/test_airflow_common.py | 59 ++++++++++++++++++++++
21 files changed, 122 insertions(+), 64 deletions(-)
diff --git a/chart/docs/production-guide.rst b/chart/docs/production-guide.rst
index 6c1736cd14b..71311b525b9 100644
--- a/chart/docs/production-guide.rst
+++ b/chart/docs/production-guide.rst
@@ -661,12 +661,14 @@ flower Basic Auth using the ``_CMD`` or ``_SECRET``
variant without disabling th
+-------------------------------------------------------+------------------------------------------+------------------------------------------------+
| ``<RELEASE_NAME>-pgbouncer-certificates`` |
| |
+-------------------------------------------------------+------------------------------------------+------------------------------------------------+
-| ``<RELEASE_NAME>-registry`` |
``.Values.registry.secretName`` |
|
-+-------------------------------------------------------+------------------------------------------+------------------------------------------------+
| ``<RELEASE_NAME>-kerberos-keytab`` |
| |
+-------------------------------------------------------+------------------------------------------+------------------------------------------------+
| ``<RELEASE_NAME>-flower`` |
``.Values.flower.secretName`` |
``AIRFLOW__CELERY__FLOWER_BASIC_AUTH`` |
+-------------------------------------------------------+------------------------------------------+------------------------------------------------+
+A secret named ``<RELEASE_NAME>-registry`` is also created when
``.Values.registry.connection`` is
+defined and neither ``.Values.registry.secretName`` nor
``.Values.imagePullSecrets`` is set. However,
+this behavior is deprecated in favor of explicitly defining
``.Values.imagePullSecrets``.
+
You can read more about advanced ways of setting configuration variables in the
:doc:`apache-airflow:howto/set-config`.
diff --git a/chart/files/pod-template-file.kubernetes-helm-yaml
b/chart/files/pod-template-file.kubernetes-helm-yaml
index fd149325afb..e8db91c7f41 100644
--- a/chart/files/pod-template-file.kubernetes-helm-yaml
+++ b/chart/files/pod-template-file.kubernetes-helm-yaml
@@ -216,10 +216,7 @@ spec:
{{- if .Values.workers.runtimeClassName }}
runtimeClassName: {{ .Values.workers.runtimeClassName }}
{{- end }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{- include "image_pull_secrets" . | nindent 4 }}
{{- if .Values.workers.hostAliases }}
hostAliases: {{- toYaml .Values.workers.hostAliases | nindent 4 }}
{{- end }}
diff --git a/chart/newsfragments/57615.misc.rst
b/chart/newsfragments/57615.misc.rst
new file mode 100644
index 00000000000..1b2ec4c4fcd
--- /dev/null
+++ b/chart/newsfragments/57615.misc.rst
@@ -0,0 +1 @@
+Add ``.Values.imagePullSecrets`` as the new mechanism for configuring registry
credentials, deprecating both ``.Values.registry.secretName`` and the automatic
creation of the ``<RELEASE_NAME>-registry`` secret from
``.Values.registry.connection``.
diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml
index 17f56e1343e..59a5b488407 100644
--- a/chart/templates/_helpers.yaml
+++ b/chart/templates/_helpers.yaml
@@ -460,8 +460,20 @@ If release name contains chart name it will be used as a
full name.
{{- default (printf "%s-pgbouncer-stats" (include "airflow.fullname" .))
.Values.pgbouncer.metricsExporterSidecar.statsSecretName }}
{{- end }}
-{{- define "registry_secret" -}}
- {{- default (printf "%s-registry" (include "airflow.fullname" .))
.Values.registry.secretName }}
+{{- define "image_pull_secrets" -}}
+ {{- $secrets := (default (list .Values.registry.secretName)
.Values.imagePullSecrets) -}}
+ {{- $secrets = ($secrets | compact | uniq) -}}
+ {{- if and (not $secrets) (or .Values.registry.connection) -}}
+ {{- $secrets = append $secrets (printf "%s-registry" (include
"airflow.fullname" .)) -}}
+ {{- end -}}
+ {{- $out := list -}}
+ {{- range $n := $secrets }}
+ {{- if kindIs "string" $n }}
+ {{- $n = dict "name" $n -}}
+ {{- end -}}
+ {{- $out = append $out (dict "name" $n.name) -}}
+ {{- end -}}
+ {{- toYaml $out -}}
{{- end }}
{{- define "elasticsearch_secret" -}}
diff --git a/chart/templates/api-server/api-server-deployment.yaml
b/chart/templates/api-server/api-server-deployment.yaml
index 61475256c41..06d86dd6843 100644
--- a/chart/templates/api-server/api-server-deployment.yaml
+++ b/chart/templates/api-server/api-server-deployment.yaml
@@ -122,10 +122,7 @@ spec:
topologySpreadConstraints: {{- toYaml $topologySpreadConstraints |
nindent 8 }}
restartPolicy: Always
securityContext: {{ $securityContext | nindent 8 }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{- include "image_pull_secrets" . | nindent 8 }}
initContainers:
{{- if .Values.apiServer.waitForMigrations.enabled }}
- name: wait-for-airflow-migrations
diff --git a/chart/templates/cleanup/cleanup-cronjob.yaml
b/chart/templates/cleanup/cleanup-cronjob.yaml
index 39cac3f33a4..a5591807426 100644
--- a/chart/templates/cleanup/cleanup-cronjob.yaml
+++ b/chart/templates/cleanup/cleanup-cronjob.yaml
@@ -86,10 +86,7 @@ spec:
tolerations: {{- toYaml $tolerations | nindent 12 }}
topologySpreadConstraints: {{- toYaml $topologySpreadConstraints |
nindent 12 }}
serviceAccountName: {{ include "cleanup.serviceAccountName" . }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{- include "image_pull_secrets" . | nindent 12 }}
securityContext: {{ $securityContext | nindent 12 }}
containers:
- name: airflow-cleanup-pods
diff --git a/chart/templates/dag-processor/dag-processor-deployment.yaml
b/chart/templates/dag-processor/dag-processor-deployment.yaml
index f628d94627d..67958a71938 100644
--- a/chart/templates/dag-processor/dag-processor-deployment.yaml
+++ b/chart/templates/dag-processor/dag-processor-deployment.yaml
@@ -116,10 +116,7 @@ spec:
restartPolicy: Always
serviceAccountName: {{ include "dagProcessor.serviceAccountName" . }}
securityContext: {{ $securityContext | nindent 8 }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{ include "image_pull_secrets" . | nindent 8 }}
initContainers:
{{- if .Values.dagProcessor.waitForMigrations.enabled }}
- name: wait-for-airflow-migrations
diff --git a/chart/templates/flower/flower-deployment.yaml
b/chart/templates/flower/flower-deployment.yaml
index 7b6750921e5..50bfc1520ff 100644
--- a/chart/templates/flower/flower-deployment.yaml
+++ b/chart/templates/flower/flower-deployment.yaml
@@ -85,10 +85,7 @@ spec:
{{- end }}
restartPolicy: Always
securityContext: {{ $securityContext | nindent 8 }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{- include "image_pull_secrets" . | nindent 8 }}
containers:
- name: flower
image: {{ template "flower_image" . }}
diff --git a/chart/templates/jobs/create-user-job.yaml
b/chart/templates/jobs/create-user-job.yaml
index ffa8d19ce18..f0bde008cc1 100644
--- a/chart/templates/jobs/create-user-job.yaml
+++ b/chart/templates/jobs/create-user-job.yaml
@@ -86,10 +86,7 @@ spec:
tolerations: {{- toYaml $tolerations | nindent 8 }}
topologySpreadConstraints: {{- toYaml $topologySpreadConstraints |
nindent 8 }}
serviceAccountName: {{ include "createUserJob.serviceAccountName" . }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{- include "image_pull_secrets" . | nindent 8 }}
{{- if .Values.createUserJob.extraInitContainers }}
initContainers:
{{- tpl (toYaml .Values.createUserJob.extraInitContainers) . | nindent
8 }}
diff --git a/chart/templates/jobs/migrate-database-job.yaml
b/chart/templates/jobs/migrate-database-job.yaml
index dd969339d9a..1237f46d624 100644
--- a/chart/templates/jobs/migrate-database-job.yaml
+++ b/chart/templates/jobs/migrate-database-job.yaml
@@ -86,10 +86,7 @@ spec:
tolerations: {{- toYaml $tolerations | nindent 8 }}
topologySpreadConstraints: {{- toYaml $topologySpreadConstraints |
nindent 8 }}
serviceAccountName: {{ include "migrateDatabaseJob.serviceAccountName" .
}}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{- include "image_pull_secrets" . | nindent 8 }}
{{- if .Values.migrateDatabaseJob.extraInitContainers }}
initContainers:
{{- tpl (toYaml .Values.migrateDatabaseJob.extraInitContainers) . |
nindent 8 }}
diff --git a/chart/templates/pgbouncer/pgbouncer-deployment.yaml
b/chart/templates/pgbouncer/pgbouncer-deployment.yaml
index 682a858f69d..74412f2d4eb 100644
--- a/chart/templates/pgbouncer/pgbouncer-deployment.yaml
+++ b/chart/templates/pgbouncer/pgbouncer-deployment.yaml
@@ -90,10 +90,7 @@ spec:
serviceAccountName: {{ include "pgbouncer.serviceAccountName" . }}
securityContext: {{ $securityContext | nindent 8 }}
restartPolicy: Always
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{- include "image_pull_secrets" . | nindent 8 }}
containers:
- name: pgbouncer
image: {{ template "pgbouncer_image" . }}
diff --git a/chart/templates/redis/redis-statefulset.yaml
b/chart/templates/redis/redis-statefulset.yaml
index b8374d81e9d..646e87b6dc2 100644
--- a/chart/templates/redis/redis-statefulset.yaml
+++ b/chart/templates/redis/redis-statefulset.yaml
@@ -82,10 +82,7 @@ spec:
{{- if .Values.schedulerName }}
schedulerName: {{ .Values.schedulerName }}
{{- end }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{ include "image_pull_secrets" . | nindent 8 }}
securityContext: {{ $securityContext | nindent 8 }}
containers:
- name: redis
diff --git a/chart/templates/scheduler/scheduler-deployment.yaml
b/chart/templates/scheduler/scheduler-deployment.yaml
index 903d4767d0f..53e2975cc40 100644
--- a/chart/templates/scheduler/scheduler-deployment.yaml
+++ b/chart/templates/scheduler/scheduler-deployment.yaml
@@ -138,10 +138,7 @@ spec:
terminationGracePeriodSeconds: {{
.Values.scheduler.terminationGracePeriodSeconds }}
serviceAccountName: {{ include "scheduler.serviceAccountName" . }}
securityContext: {{ $securityContext | nindent 8 }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{ include "image_pull_secrets" . | nindent 8 }}
{{- if .Values.scheduler.hostAliases }}
hostAliases: {{- toYaml .Values.scheduler.hostAliases | nindent 8 }}
{{- end }}
diff --git a/chart/templates/secrets/registry-secret.yaml
b/chart/templates/secrets/registry-secret.yaml
index 967eb90ac79..4acbe1bf881 100644
--- a/chart/templates/secrets/registry-secret.yaml
+++ b/chart/templates/secrets/registry-secret.yaml
@@ -20,7 +20,7 @@
################################
## Registry Secret
#################################
-{{- if (and .Values.registry.connection (not .Values.registry.secretName)) }}
+{{- if (and (or .Values.registry.connection) (not (or
.Values.registry.secretName .Values.imagePullSecrets))) }}
apiVersion: v1
kind: Secret
metadata:
diff --git a/chart/templates/statsd/statsd-deployment.yaml
b/chart/templates/statsd/statsd-deployment.yaml
index ecbd1f80f41..57ab8b477a9 100644
--- a/chart/templates/statsd/statsd-deployment.yaml
+++ b/chart/templates/statsd/statsd-deployment.yaml
@@ -86,10 +86,7 @@ spec:
serviceAccountName: {{ include "statsd.serviceAccountName" . }}
securityContext: {{ $securityContext | nindent 8 }}
restartPolicy: Always
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{ include "image_pull_secrets" . | nindent 8 }}
containers:
- name: statsd
image: {{ template "statsd_image" . }}
diff --git a/chart/templates/triggerer/triggerer-deployment.yaml
b/chart/templates/triggerer/triggerer-deployment.yaml
index de6d2403121..21cddea9521 100644
--- a/chart/templates/triggerer/triggerer-deployment.yaml
+++ b/chart/templates/triggerer/triggerer-deployment.yaml
@@ -130,10 +130,7 @@ spec:
restartPolicy: Always
serviceAccountName: {{ include "triggerer.serviceAccountName" . }}
securityContext: {{ $securityContext | nindent 8 }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{ include "image_pull_secrets" . | nindent 8 }}
initContainers:
{{- if .Values.triggerer.waitForMigrations.enabled }}
- name: wait-for-airflow-migrations
diff --git a/chart/templates/webserver/webserver-deployment.yaml
b/chart/templates/webserver/webserver-deployment.yaml
index 63910bc19d4..f1d4b2d92ee 100644
--- a/chart/templates/webserver/webserver-deployment.yaml
+++ b/chart/templates/webserver/webserver-deployment.yaml
@@ -131,10 +131,7 @@ spec:
restartPolicy: Always
terminationGracePeriodSeconds: {{
.Values.webserver.terminationGracePeriodSeconds }}
securityContext: {{ $securityContext | nindent 8 }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{- include "image_pull_secrets" . | nindent 8 }}
initContainers:
{{- if .Values.webserver.waitForMigrations.enabled }}
- name: wait-for-airflow-migrations
diff --git a/chart/templates/workers/worker-deployment.yaml
b/chart/templates/workers/worker-deployment.yaml
index 5e9e7a097bf..ee7277d265e 100644
--- a/chart/templates/workers/worker-deployment.yaml
+++ b/chart/templates/workers/worker-deployment.yaml
@@ -142,10 +142,7 @@ spec:
serviceAccountName: {{ include "worker.serviceAccountName" . }}
{{- end }}
securityContext: {{ $securityContext | nindent 8 }}
- {{- if or .Values.registry.secretName .Values.registry.connection }}
- imagePullSecrets:
- - name: {{ template "registry_secret" . }}
- {{- end }}
+ imagePullSecrets: {{ include "image_pull_secrets" . | nindent 8 }}
initContainers:
{{- if and $persistence .Values.workers.persistence.fixPermissions }}
- name: volume-permissions
diff --git a/chart/values.schema.json b/chart/values.schema.json
index 0b5cc179fa2..9bfa5491208 100644
--- a/chart/values.schema.json
+++ b/chart/values.schema.json
@@ -226,6 +226,23 @@
"type": "string"
}
},
+ "imagePullSecrets": {
+ "description": "List of existing Kubernetes secrets containing
Base64 encoded credentials to connect to private registries (will get passed to
imagePullSecrets).",
+ "type": "array",
+ "default": [],
+ "x-docsSection": "Kubernetes",
+ "items": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "$ref":
"#/definitions/io.k8s.api.core.v1.LocalObjectReference"
+ }
+ ]
+ },
+ "uniqueItems": true
+ },
"ingress": {
"description": "Ingress configuration.",
"type": "object",
@@ -8360,7 +8377,7 @@
"additionalProperties": false,
"properties": {
"secretName": {
- "description": "Name of the Kubernetes secret containing
Base64 encoded credentials to connect to a private registry (will get passed to
imagePullSecrets).",
+ "description": "Name of the Kubernetes secret containing
Base64 encoded credentials to connect to a private registry (will get passed to
imagePullSecrets) (Deprecated - renamed to `registry.secretNames`).",
"type": [
"string",
"null"
@@ -8368,7 +8385,7 @@
"default": null
},
"connection": {
- "description": "Credentials to connect to a private
registry, these will get Base64 encoded and stored in a secret (will get passed
to imagePullSecrets).",
+ "description": "Credentials to connect to a private
registry, these will get Base64 encoded and stored in a secret (will get passed
to imagePullSecrets) (create manually the credentials secret and add to
`imagePullSecrets` instead).",
"type": "object",
"default": {},
"additionalProperties": false,
diff --git a/chart/values.yaml b/chart/values.yaml
index 19581503397..66650b98acf 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -139,6 +139,10 @@ schedulerName: ~
# Add common labels to all objects and pods defined in this chart.
labels: {}
+# List of existing Kubernetes secrets containing Base64 encoded credentials to
connect to private
+# registries. Items can be either strings or {name: secret} objects.
+imagePullSecrets: []
+
# Ingress configuration
ingress:
# Enable all ingress resources
@@ -2729,11 +2733,16 @@ redis:
labels: {}
podAnnotations: {}
-# Auth secret for a private registry
+
+# Auth secret for a private registry (Deprecated - use `imagePullSecrets`
instead)
# This is used if pulling airflow images from a private registry
registry:
+ # Name of the Kubernetes secret containing Base64 encoded credentials to
connect to a private registry
+ # (Deprecated - renamed to `imagePullSecrets`).
secretName: ~
+ # Credentials to connect to a private registry, these will get Base64
encoded and stored in a secret
+ # (Deprecated - create manually the credentials secret and add to
`imagePullSecrets` instead).
# Example:
# connection:
# user: ~
diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
b/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
index 5a24465eb78..dac2f458242 100644
--- a/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
+++ b/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
@@ -491,3 +491,62 @@ class TestAirflowCommon:
priority = doc["spec"]["template"]["spec"]["priorityClassName"]
assert priority == f"low-priority-{component}"
+
+ @pytest.mark.parametrize(
+ ("image_pull_secrets", "registry_secret_name", "registry_connection",
"expected_image_pull_secrets"),
+ [
+ ([], None, {}, []),
+ (
+ [],
+ None,
+ {"host": "example.com", "user": "user", "pass": "pass",
"email": "[email protected]"},
+ ["test-basic-registry"],
+ ),
+ ([], "regcred", {}, ["regcred"]),
+ (["regcred2"], "regcred", {}, ["regcred2"]),
+ (
+ ["regcred2"],
+ None,
+ {"host": "example.com", "user": "user", "pass": "pass",
"email": "[email protected]"},
+ ["regcred2"],
+ ),
+ (["regcred", {"name": "regcred2"}, ""], None, {}, ["regcred",
"regcred2"]),
+ ],
+ )
+ def test_image_pull_secrets(
+ self, image_pull_secrets, registry_secret_name, registry_connection,
expected_image_pull_secrets
+ ):
+ release_name = "test-basic"
+ docs = render_chart(
+ name=release_name,
+ values={
+ "imagePullSecrets": image_pull_secrets,
+ "registry": {"secretName": registry_secret_name, "connection":
registry_connection},
+ "flower": {"enabled": True},
+ "pgbouncer": {"enabled": True},
+ "cleanup": {"enabled": True},
+ },
+ show_only=[
+ "templates/flower/flower-deployment.yaml",
+ "templates/pgbouncer/pgbouncer-deployment.yaml",
+ "templates/scheduler/scheduler-deployment.yaml",
+ "templates/statsd/statsd-deployment.yaml",
+ "templates/triggerer/triggerer-deployment.yaml",
+ "templates/dag-processor/dag-processor-deployment.yaml",
+ "templates/webserver/webserver-deployment.yaml",
+ "templates/workers/worker-deployment.yaml",
+ "templates/cleanup/cleanup-cronjob.yaml",
+ "templates/jobs/migrate-database-job.yaml",
+ "templates/jobs/create-user-job.yaml",
+ ],
+ )
+
+ expected_image_pull_secrets = [{"name": name} for name in
expected_image_pull_secrets]
+
+ for doc in docs:
+ got_image_pull_secrets = (
+
doc["spec"]["jobTemplate"]["spec"]["template"]["spec"]["imagePullSecrets"]
+ if doc["kind"] == "CronJob"
+ else doc["spec"]["template"]["spec"]["imagePullSecrets"]
+ )
+ assert got_image_pull_secrets == expected_image_pull_secrets