From f3ada9023479886ae01889ba6769fd6ab56be1cf Mon Sep 17 00:00:00 2001 From: nailo2c Date: Thu, 6 Aug 2026 16:09:35 +0800 Subject: [PATCH] Add startup probe for Kerberos worker sidecars --- .../pod-template-file.kubernetes-helm-yaml | 9 +++ .../templates/workers/worker-deployment.yaml | 9 +++ .../airflow_aux/test_pod_template_file.py | 46 +++++++++++++ .../helm_tests/security/test_kerberos.py | 49 ++++++++++++++ chart/values.schema.json | 64 +++++++++++++++++++ chart/values.yaml | 18 ++++++ 6 files changed, 195 insertions(+) diff --git a/chart/files/pod-template-file.kubernetes-helm-yaml b/chart/files/pod-template-file.kubernetes-helm-yaml index 76d7316ac150e..e9ffea6e0fb00 100644 --- a/chart/files/pod-template-file.kubernetes-helm-yaml +++ b/chart/files/pod-template-file.kubernetes-helm-yaml @@ -175,6 +175,15 @@ spec: {{- end }} args: ["kerberos"] resources: {{- toYaml .Values.workers.kubernetes.kerberosSidecar.resources | nindent 8 }} + {{- if .Values.workers.kubernetes.kerberosSidecar.startupProbe.enabled }} + startupProbe: + exec: + command: ["klist", "-s"] + timeoutSeconds: {{ .Values.workers.kubernetes.kerberosSidecar.startupProbe.timeoutSeconds }} + initialDelaySeconds: {{ .Values.workers.kubernetes.kerberosSidecar.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.workers.kubernetes.kerberosSidecar.startupProbe.periodSeconds }} + failureThreshold: {{ .Values.workers.kubernetes.kerberosSidecar.startupProbe.failureThreshold }} + {{- end }} volumeMounts: - name: logs mountPath: {{ template "airflow_logs" . }} diff --git a/chart/templates/workers/worker-deployment.yaml b/chart/templates/workers/worker-deployment.yaml index 536e73a216a14..ea893150c3da9 100644 --- a/chart/templates/workers/worker-deployment.yaml +++ b/chart/templates/workers/worker-deployment.yaml @@ -403,6 +403,15 @@ spec: {{- end }} args: ["kerberos"] resources: {{- toYaml .Values.workers.celery.kerberosSidecar.resources | nindent 12 }} + {{- if .Values.workers.celery.kerberosSidecar.startupProbe.enabled }} + startupProbe: + exec: + command: ["klist", "-s"] + timeoutSeconds: {{ .Values.workers.celery.kerberosSidecar.startupProbe.timeoutSeconds }} + initialDelaySeconds: {{ .Values.workers.celery.kerberosSidecar.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.workers.celery.kerberosSidecar.startupProbe.periodSeconds }} + failureThreshold: {{ .Values.workers.celery.kerberosSidecar.startupProbe.failureThreshold }} + {{- end }} volumeMounts: - name: logs mountPath: {{ template "airflow_logs" . }} diff --git a/chart/tests/helm_tests/airflow_aux/test_pod_template_file.py b/chart/tests/helm_tests/airflow_aux/test_pod_template_file.py index 42a776b5fb628..8cded90b6292a 100644 --- a/chart/tests/helm_tests/airflow_aux/test_pod_template_file.py +++ b/chart/tests/helm_tests/airflow_aux/test_pod_template_file.py @@ -1343,6 +1343,52 @@ def test_kerberos_sidecar_security_context(self): "allowPrivilegeEscalation": False } + @pytest.mark.parametrize( + ("override", "expected"), + [ + ( + {}, + { + "exec": {"command": ["klist", "-s"]}, + "timeoutSeconds": 5, + "initialDelaySeconds": 0, + "periodSeconds": 10, + "failureThreshold": 6, + }, + ), + ( + { + "timeoutSeconds": 11, + "initialDelaySeconds": 12, + "periodSeconds": 13, + "failureThreshold": 14, + }, + { + "exec": {"command": ["klist", "-s"]}, + "timeoutSeconds": 11, + "initialDelaySeconds": 12, + "periodSeconds": 13, + "failureThreshold": 14, + }, + ), + ({"enabled": False}, None), + ], + ids=["default", "custom", "disabled"], + ) + def test_kerberos_sidecar_startup_probe(self, override, expected): + docs = render_chart( + values={ + "workers": {"kubernetes": {"kerberosSidecar": {"enabled": True, "startupProbe": override}}} + }, + show_only=["templates/pod-template-file.yaml"], + chart_dir=self.temp_chart_dir, + ) + + assert ( + jmespath.search("spec.containers[?name=='worker-kerberos'] | [0].startupProbe", docs[0]) + == expected + ) + def test_kerberos_init_container_default(self): docs = render_chart( show_only=["templates/pod-template-file.yaml"], diff --git a/chart/tests/helm_tests/security/test_kerberos.py b/chart/tests/helm_tests/security/test_kerberos.py index ad8bca571930c..270c1aab93a30 100644 --- a/chart/tests/helm_tests/security/test_kerberos.py +++ b/chart/tests/helm_tests/security/test_kerberos.py @@ -19,6 +19,7 @@ import json import jmespath +import pytest from chart_utils.helm_template_generator import render_chart @@ -153,3 +154,51 @@ def test_kerberos_keytab_secret_unavailable_when_not_specified(self): ) assert len(docs) == 0 + + @pytest.mark.parametrize( + ("override", "expected"), + [ + ( + {}, + { + "exec": {"command": ["klist", "-s"]}, + "timeoutSeconds": 5, + "initialDelaySeconds": 0, + "periodSeconds": 10, + "failureThreshold": 6, + }, + ), + ( + { + "timeoutSeconds": 11, + "initialDelaySeconds": 12, + "periodSeconds": 13, + "failureThreshold": 14, + }, + { + "exec": {"command": ["klist", "-s"]}, + "timeoutSeconds": 11, + "initialDelaySeconds": 12, + "periodSeconds": 13, + "failureThreshold": 14, + }, + ), + ({"enabled": False}, None), + ], + ids=["default", "custom", "disabled"], + ) + def test_kerberos_sidecar_startup_probe(self, override, expected): + docs = render_chart( + values={ + "executor": "CeleryExecutor", + "workers": {"celery": {"kerberosSidecar": {"enabled": True, "startupProbe": override}}}, + }, + show_only=["templates/workers/worker-deployment.yaml"], + ) + + assert ( + jmespath.search( + "spec.template.spec.containers[?name=='worker-kerberos'] | [0].startupProbe", docs[0] + ) + == expected + ) diff --git a/chart/values.schema.json b/chart/values.schema.json index 7402d3b48f7d6..8cbd87fc50df2 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -2111,6 +2111,38 @@ "type": "boolean", "default": false }, + "startupProbe": { + "description": "Startup probe for the Kerberos worker sidecar (runs `klist -s`).", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable the Kerberos sidecar startup probe. Disable for custom images without `klist`.", + "type": "boolean", + "default": true + }, + "timeoutSeconds": { + "description": "Number of seconds after which the probe times out.", + "type": "integer", + "default": 5 + }, + "initialDelaySeconds": { + "description": "Number of seconds after the container has started before the startup probe is initiated.", + "type": "integer", + "default": 0 + }, + "periodSeconds": { + "description": "How often (in seconds) to perform the probe.", + "type": "integer", + "default": 10 + }, + "failureThreshold": { + "description": "Number of consecutive failures required for the startup probe to fail.", + "type": "integer", + "default": 6 + } + } + }, "resources": { "description": "Resources on kerberos sidecar.", "type": "object", @@ -2859,6 +2891,38 @@ "type": "boolean", "default": false }, + "startupProbe": { + "description": "Startup probe for the Kerberos worker sidecar (runs `klist -s`).", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable the Kerberos sidecar startup probe. Disable for custom images without `klist`.", + "type": "boolean", + "default": true + }, + "timeoutSeconds": { + "description": "Number of seconds after which the probe times out.", + "type": "integer", + "default": 5 + }, + "initialDelaySeconds": { + "description": "Number of seconds after the container has started before the startup probe is initiated.", + "type": "integer", + "default": 0 + }, + "periodSeconds": { + "description": "How often (in seconds) to perform the probe.", + "type": "integer", + "default": 10 + }, + "failureThreshold": { + "description": "Number of consecutive failures required for the startup probe to fail.", + "type": "integer", + "default": 6 + } + } + }, "resources": { "description": "Resources on kerberos sidecar.", "type": "object", diff --git a/chart/values.yaml b/chart/values.yaml index 4551250ee0ac4..c49daf2c8ab5a 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -839,6 +839,15 @@ workers: # Container level lifecycle hooks containerLifecycleHooks: {} + # Startup probe for the kerberos sidecar: `klist -s` succeeds once the credential + # cache holds a valid, unexpired ticket. Disable for custom images without `klist`. + startupProbe: + enabled: true + timeoutSeconds: 5 + initialDelaySeconds: 0 + periodSeconds: 10 + failureThreshold: 6 + # Kerberos init container configuration for Airflow Celery workers # If not set, the values from `workers.kerberosInitContainer` section will be used. kerberosInitContainer: @@ -1086,6 +1095,15 @@ workers: # Container level lifecycle hooks containerLifecycleHooks: {} + # Startup probe for the kerberos sidecar: `klist -s` succeeds once the credential + # cache holds a valid, unexpired ticket. Disable for custom images without `klist`. + startupProbe: + enabled: true + timeoutSeconds: 5 + initialDelaySeconds: 0 + periodSeconds: 10 + failureThreshold: 6 + # Kerberos init container configuration for pods created with pod-template-file # If not set, the values from `workers.kerberosInitContainer` section will be used. kerberosInitContainer: