Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions chart/docs/production-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,28 @@ This will generate the following scheduler deployment:
- name: scheduler
...

Omitting default ``securityContext`` values
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

On OpenShift, the ``restricted`` SCC assigns ``runAsUser`` and ``fsGroup`` automatically and rejects Pods
that request specific values without the ``anyuid`` SCC in place. Since an empty ``securityContexts.pod``
falls back to :ref:`uid <parameters:Airflow>` / :ref:`gid <parameters:Airflow>` (as shown above), leaving
it empty is not enough to avoid hard-coded values. Set ``securityContexts.disableDefaults`` to stop the
chart from filling in these defaults wherever ``securityContexts.pod`` / ``securityContexts.containers``
(or the equivalent per-component overrides) are left empty:

.. code-block:: yaml
:caption: values.yaml

securityContexts:
disableDefaults: true

This omits ``runAsUser`` / ``fsGroup`` (pod) and ``runAsUser`` (container) from the rendered
``securityContext`` entirely wherever they are not explicitly set, allowing the SCC to supply its own
values. Explicit values set in ``securityContexts.pod`` / ``securityContexts.containers`` (or a
component's local override, e.g. ``scheduler.securityContexts.pod``) still take priority over
``disableDefaults``.

Built-in secrets and environment variables
------------------------------------------

Expand Down
1 change: 1 addition & 0 deletions chart/newsfragments/70238.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added ``securityContexts.disableDefaults`` to the Helm chart. When set, the chart no longer fills in default ``runAsUser``/``fsGroup`` (pod) or ``runAsUser`` (container) values, letting platforms such as OpenShift assign them automatically via SCC instead of the chart hard-coding them.
52 changes: 34 additions & 18 deletions chart/templates/_helpers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,10 @@ If release name contains chart name it will be used as a full name.
- name: {{ .Values.dags.gitSync.containerName }}{{ if .is_init }}-init{{ end }}
image: {{ template "git_sync_image" . }}
imagePullPolicy: {{ .Values.images.gitSync.pullPolicy }}
securityContext: {{- include "localContainerSecurityContext" .Values.dags.gitSync | nindent 4 }}
{{- $gitSyncContainerSecurityContext := include "localContainerSecurityContext" (list .Values.dags.gitSync .Values) }}
{{- if $gitSyncContainerSecurityContext }}
securityContext: {{ $gitSyncContainerSecurityContext | nindent 4 }}
{{- end }}
envFrom: {{- include "custom_git_sync_environment_from" . | default "\n []" | indent 2 }}
env:
- name: GIT_SYNC_REV
Expand Down Expand Up @@ -854,7 +857,7 @@ Priority of values are from left to right, meaning if first value is not empty,
{{- end }}
{{- if $result }}
{{- toYaml $result | print }}
{{- else }}
{{- else if not $.securityContexts.disableDefaults }}
runAsUser: {{ $.uid }}
fsGroup: {{ $.gid }}
{{- end }}
Expand All @@ -869,15 +872,18 @@ If no value is passed for <node>.securityContexts.pod, defaults to UID in the lo
+-----------------------------+ +------------+

The template can be called like so:
include "localPodSecurityContext" (list . .Values.schedule)
include "localPodSecurityContext" (list .Values.redis .Values)

Where `.Values` is the global variables scope and `.Values.redis` the local variables scope for the redis template.
It is important to pass the local variables scope to this template as it is used to determine the local node value for uid.
*/}}
{{- define "localPodSecurityContext" -}}
{{- if .securityContexts.pod -}}
{{ toYaml .securityContexts.pod | print }}
{{- else -}}
runAsUser: {{ .uid }}
{{- $ := last . }}
{{- $node := first . }}
{{- if $node.securityContexts.pod -}}
{{ toYaml $node.securityContexts.pod | print }}
{{- else if not $.securityContexts.disableDefaults -}}
runAsUser: {{ $node.uid }}
{{- end -}}
{{- end -}}

Expand All @@ -890,15 +896,18 @@ If no value is passed for <node>.securityContexts.container, defaults to UID in
+-----------------------------------+ +------------+

The template can be called like so:
include "localContainerSecurityContext" .Values.statsd
include "localContainerSecurityContext" (list .Values.dags.gitSync .Values)

Where `.Values` is the global variables scope and `.Values.dags.gitSync` the local variables scope.
It is important to pass the local variables scope to this template as it is used to determine the local node value for uid.
*/}}
{{- define "localContainerSecurityContext" -}}
{{- if .securityContexts.container -}}
{{ toYaml .securityContexts.container | print }}
{{- else -}}
runAsUser: {{ .uid }}
{{- $ := last . }}
{{- $node := first . }}
{{- if $node.securityContexts.container -}}
{{ toYaml $node.securityContexts.container | print }}
{{- else if not $.securityContexts.disableDefaults -}}
runAsUser: {{ $node.uid }}
{{- end -}}
{{- end -}}

Expand All @@ -914,6 +923,9 @@ The template looks for `runAsUser` and `fsGroup` specifically, any other paramet
Values are not accumulated meaning that if runAsUser is set to 10 in <node>.securityContexts.pod,
any extra values set to securityContexts or uid+gid will be ignored.

If securityContexts.disableDefaults is true and no explicit runAsUser/fsGroup is set anywhere,
this template renders an empty string, since there is no meaningful id to chown to.

The template can be called like so:
include "airflowPodSecurityContextsIds" (list . .Values.webserver)

Expand All @@ -926,7 +938,7 @@ Where `.` is the global variables scope and `.Values.workers` the local variable
{{ pluck "runAsUser" .securityContexts.pod | first | default $.Values.uid }}:{{ pluck "fsGroup" .securityContexts.pod | first | default $.Values.gid }}
{{- else if $.Values.securityContexts.pod -}}
{{ pluck "runAsUser" $.Values.securityContexts.pod | first | default $.Values.uid }}:{{ pluck "fsGroup" $.Values.securityContexts.pod | first | default $.Values.gid }}
{{- else -}}
{{- else if not $.Values.securityContexts.disableDefaults -}}
{{ $.Values.uid }}:{{ $.Values.gid }}
{{- end -}}
{{- end -}}
Expand Down Expand Up @@ -959,7 +971,7 @@ Priority of values are from left to right, meaning if first value is not empty,
{{- toYaml $result | print }}
{{- else if and (hasKey $ "securityContexts") (hasKey $.securityContexts "containers") $.securityContexts.containers }}
{{- toYaml $.securityContexts.containers | print }}
{{- else -}}
{{- else if not $.securityContexts.disableDefaults }}
allowPrivilegeEscalation: false
capabilities:
drop:
Expand All @@ -976,12 +988,16 @@ If no value is passed for <node>.securityContexts.container, defaults to deny pr
+-----------------------------------+ +------------------------------------------------------------+

The template can be called like so:
include "externalContainerSecurityContext" .Values.statsd
include "externalContainerSecurityContext" (list .Values.statsd .Values)

Where `.Values` is the global variables scope and `.Values.statsd` the local variables scope.
*/}}
{{- define "externalContainerSecurityContext" -}}
{{- if .securityContexts.container -}}
{{ toYaml .securityContexts.container | print }}
{{- else -}}
{{- $ := last . }}
{{- $node := first . }}
{{- if $node.securityContexts.container -}}
{{ toYaml $node.securityContexts.container | print }}
{{- else if not $.securityContexts.disableDefaults -}}
allowPrivilegeEscalation: false
capabilities:
drop:
Expand Down
6 changes: 6 additions & 0 deletions chart/templates/api-server/api-server-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,19 @@ spec:
tolerations: {{- toYaml $tolerations | nindent 8 }}
topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }}
restartPolicy: Always
{{- if $securityContext }}
securityContext: {{ $securityContext | nindent 8 }}
{{- end }}
imagePullSecrets: {{- include "image_pull_secrets" . | nindent 8 }}
initContainers:
{{- if .Values.apiServer.waitForMigrations.enabled }}
- name: wait-for-airflow-migrations
resources: {{- toYaml .Values.apiServer.resources | nindent 12 }}
image: {{ template "airflow_image_for_migrations" . }}
imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
{{- if $containerSecurityContextWaitForMigrations }}
securityContext: {{ $containerSecurityContextWaitForMigrations | nindent 12 }}
{{- end }}
volumeMounts:
{{- include "airflow_config_mount" . | nindent 12 }}
{{- if .Values.volumeMounts }}
Expand All @@ -163,7 +167,9 @@ spec:
- name: api-server
image: {{ template "airflow_image" . }}
imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
{{- if $containerSecurityContext }}
securityContext: {{ $containerSecurityContext | nindent 12 }}
{{- end }}
{{- if $containerLifecycleHooks }}
lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }}
{{- end }}
Expand Down
4 changes: 4 additions & 0 deletions chart/templates/cleanup/cleanup-cronjob.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,16 @@ spec:
serviceAccountName: {{ include "cleanup.serviceAccountName" . }}
enableServiceLinks: {{ .Values.enableServiceLinks }}
imagePullSecrets: {{- include "image_pull_secrets" . | nindent 12 }}
{{- if $securityContext }}
securityContext: {{ $securityContext | nindent 12 }}
{{- end }}
containers:
- name: airflow-cleanup-pods
image: {{ template "airflow_image" . }}
imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
{{- if $containerSecurityContext }}
securityContext: {{ $containerSecurityContext | nindent 16 }}
{{- end }}
{{- if $containerLifecycleHooks }}
lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 16 }}
{{- end }}
Expand Down
8 changes: 8 additions & 0 deletions chart/templates/dag-processor/dag-processor-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,19 @@ spec:
restartPolicy: Always
serviceAccountName: {{ include "dagProcessor.serviceAccountName" . }}
enableServiceLinks: {{ .Values.enableServiceLinks }}
{{- if $securityContext }}
securityContext: {{ $securityContext | nindent 8 }}
{{- end }}
imagePullSecrets: {{ include "image_pull_secrets" . | nindent 8 }}
initContainers:
{{- if .Values.dagProcessor.waitForMigrations.enabled }}
- name: wait-for-airflow-migrations
resources: {{- toYaml .Values.dagProcessor.resources | nindent 12 }}
image: {{ template "airflow_image_for_migrations" . }}
imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
{{- if $containerSecurityContextWaitForMigrations }}
securityContext: {{ $containerSecurityContextWaitForMigrations | nindent 12 }}
{{- end }}
volumeMounts:
{{- if .Values.volumeMounts }}
{{- tpl (toYaml .Values.volumeMounts) . | nindent 12 }}
Expand Down Expand Up @@ -147,7 +151,9 @@ spec:
- name: dag-processor
image: {{ template "airflow_image" . }}
imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
{{- if $containerSecurityContext }}
securityContext: {{ $containerSecurityContext | nindent 12 }}
{{- end }}
{{- if $containerLifecycleHooks }}
lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }}
{{- end }}
Expand Down Expand Up @@ -199,7 +205,9 @@ spec:
resources: {{- toYaml .Values.dagProcessor.logGroomerSidecar.resources | nindent 12 }}
image: {{ template "airflow_image" . }}
imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
{{- if $containerSecurityContextLogGroomerSidecar }}
securityContext: {{ $containerSecurityContextLogGroomerSidecar | nindent 12 }}
{{- end }}
{{- if .Values.dagProcessor.logGroomerSidecar.command }}
command: {{ tpl (toYaml .Values.dagProcessor.logGroomerSidecar.command) . | nindent 12 }}
{{- end }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,16 @@ spec:
serviceAccountName: {{ include "databaseCleanup.serviceAccountName" . }}
enableServiceLinks: {{ .Values.enableServiceLinks }}
imagePullSecrets: {{- include "image_pull_secrets" . | nindent 12 }}
{{- if $securityContext }}
securityContext: {{ $securityContext | nindent 12 }}
{{- end }}
containers:
- name: database-cleanup
image: {{ template "airflow_image" . }}
imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
{{- if $containerSecurityContext }}
securityContext: {{ $containerSecurityContext | nindent 16 }}
{{- end }}
{{- if $containerLifecycleHooks }}
lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 16 }}
{{- end }}
Expand Down
4 changes: 4 additions & 0 deletions chart/templates/flower/flower-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,17 @@ spec:
priorityClassName: {{ .Values.flower.priorityClassName }}
{{- end }}
restartPolicy: Always
{{- if $securityContext }}
securityContext: {{ $securityContext | nindent 8 }}
{{- end }}
imagePullSecrets: {{- include "image_pull_secrets" . | nindent 8 }}
containers:
- name: flower
image: {{ template "flower_image" . }}
imagePullPolicy: {{ .Values.images.flower.pullPolicy }}
{{- if $containerSecurityContext }}
securityContext: {{ $containerSecurityContext | nindent 12 }}
{{- end }}
{{- if $containerLifecycleHooks }}
lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }}
{{- end }}
Expand Down
4 changes: 4 additions & 0 deletions chart/templates/jobs/create-user-job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ spec:
{{- end }}
{{- end }}
spec:
{{- if $securityContext }}
securityContext: {{ $securityContext | nindent 8 }}
{{- end }}
restartPolicy: {{ .Values.createUserJob.restartPolicy }}
{{- if .Values.createUserJob.priorityClassName }}
priorityClassName: {{ .Values.createUserJob.priorityClassName }}
Expand All @@ -96,7 +98,9 @@ spec:
- name: create-user
image: {{ template "airflow_image" . }}
imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
{{- if $containerSecurityContext }}
securityContext: {{ $containerSecurityContext | nindent 12 }}
{{- end }}
{{- if $containerLifecycleHooks }}
lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }}
{{- end }}
Expand Down
4 changes: 4 additions & 0 deletions chart/templates/jobs/migrate-database-job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ spec:
{{- end }}
{{- end }}
spec:
{{- if $securityContext }}
securityContext: {{ $securityContext | nindent 8 }}
{{- end }}
restartPolicy: {{ .Values.migrateDatabaseJob.restartPolicy }}
{{- if .Values.migrateDatabaseJob.priorityClassName }}
priorityClassName: {{ .Values.migrateDatabaseJob.priorityClassName }}
Expand All @@ -96,7 +98,9 @@ spec:
- name: run-airflow-migrations
image: {{ template "airflow_image_for_migrations" . }}
imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
{{- if $containerSecurityContext }}
securityContext: {{ $containerSecurityContext | nindent 12 }}
{{- end }}
{{- if $containerLifecycleHooks }}
lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }}
{{- end }}
Expand Down
12 changes: 9 additions & 3 deletions chart/templates/pgbouncer/pgbouncer-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
{{- $tolerations := or .Values.pgbouncer.tolerations .Values.tolerations }}
{{- $topologySpreadConstraints := or .Values.pgbouncer.topologySpreadConstraints .Values.topologySpreadConstraints }}
{{- $revisionHistoryLimit := include "airflow.revisionHistoryLimit" (list .Values.pgbouncer.revisionHistoryLimit .Values.revisionHistoryLimit) }}
{{- $securityContext := include "localPodSecurityContext" .Values.pgbouncer }}
{{- $containerSecurityContext := include "externalContainerSecurityContext" .Values.pgbouncer }}
{{- $containerSecurityContextMetricsExporter := include "externalContainerSecurityContext" .Values.pgbouncer.metricsExporterSidecar }}
{{- $securityContext := include "localPodSecurityContext" (list .Values.pgbouncer .Values) }}
{{- $containerSecurityContext := include "externalContainerSecurityContext" (list .Values.pgbouncer .Values) }}
{{- $containerSecurityContextMetricsExporter := include "externalContainerSecurityContext" (list .Values.pgbouncer.metricsExporterSidecar .Values) }}
{{- $containerLifecycleHooks := .Values.pgbouncer.containerLifecycleHooks }}
{{- $containerLifecycleHooksMetricsExporter := .Values.pgbouncer.metricsExporterSidecar.containerLifecycleHooks }}
apiVersion: apps/v1
Expand Down Expand Up @@ -89,14 +89,18 @@ spec:
topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }}
serviceAccountName: {{ include "pgbouncer.serviceAccountName" . }}
enableServiceLinks: {{ .Values.enableServiceLinks }}
{{- if $securityContext }}
securityContext: {{ $securityContext | nindent 8 }}
{{- end }}
restartPolicy: Always
imagePullSecrets: {{- include "image_pull_secrets" . | nindent 8 }}
containers:
- name: pgbouncer
image: {{ template "pgbouncer_image" . }}
imagePullPolicy: {{ .Values.images.pgbouncer.pullPolicy }}
{{- if $containerSecurityContext }}
securityContext: {{ $containerSecurityContext | nindent 12 }}
{{- end }}
{{- if .Values.pgbouncer.command }}
command: {{ tpl (toYaml .Values.pgbouncer.command) . | nindent 12 }}
{{- end }}
Expand Down Expand Up @@ -160,7 +164,9 @@ spec:
resources: {{- toYaml .Values.pgbouncer.metricsExporterSidecar.resources | nindent 12 }}
image: {{ template "pgbouncer_exporter_image" . }}
imagePullPolicy: {{ .Values.images.pgbouncerExporter.pullPolicy }}
{{- if $containerSecurityContextMetricsExporter }}
securityContext: {{ $containerSecurityContextMetricsExporter | nindent 12 }}
{{- end }}
env:
- name: DATABASE_URL
valueFrom:
Expand Down
8 changes: 6 additions & 2 deletions chart/templates/redis/redis-statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
{{- $affinity := or .Values.redis.affinity .Values.affinity }}
{{- $tolerations := or .Values.redis.tolerations .Values.tolerations }}
{{- $topologySpreadConstraints := or .Values.redis.topologySpreadConstraints .Values.topologySpreadConstraints }}
{{- $securityContext := include "localPodSecurityContext" .Values.redis }}
{{- $containerSecurityContext := include "externalContainerSecurityContext" .Values.redis }}
{{- $securityContext := include "localPodSecurityContext" (list .Values.redis .Values) }}
{{- $containerSecurityContext := include "externalContainerSecurityContext" (list .Values.redis .Values) }}
{{- $containerLifecycleHooks := .Values.redis.containerLifecycleHooks }}
{{- $persistence := .Values.redis.persistence.enabled }}
apiVersion: apps/v1
Expand Down Expand Up @@ -88,12 +88,16 @@ spec:
schedulerName: {{ .Values.schedulerName }}
{{- end }}
imagePullSecrets: {{ include "image_pull_secrets" . | nindent 8 }}
{{- if $securityContext }}
securityContext: {{ $securityContext | nindent 8 }}
{{- end }}
containers:
- name: redis
image: {{ template "redis_image" . }}
imagePullPolicy: {{ .Values.images.redis.pullPolicy }}
{{- if $containerSecurityContext }}
securityContext: {{ $containerSecurityContext | nindent 12 }}
{{- end }}
{{- if $containerLifecycleHooks }}
lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }}
{{- end }}
Expand Down
Loading