You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fluss.apache.org by ip...@apache.org on 2026/04/23 17:04:35 UTC
(fluss) branch release-0.9 updated: [helm] Add pod annotations, labels, and pod disruption budget support (#3114) (#3185)
This is an automated email from the ASF dual-hosted git repository.
polyzos pushed a commit to branch release-0.9
in repository https://gitbox.apache.org/repos/asf/fluss.git
The following commit(s) were added to refs/heads/release-0.9 by this push:
new a96d9e61b [helm] Add pod annotations, labels, and pod disruption budget support (#3114) (#3185)
a96d9e61b is described below
commit a96d9e61ba538338855b51ce4f8eb0443d3119cb
Author: Muhammet Orazov <91...@users.noreply.github.com>
AuthorDate: Thu Apr 23 19:04:30 2026 +0200
[helm] Add pod annotations, labels, and pod disruption budget support (#3114) (#3185)
* [helm] Add pod annotations, labels, and pod disruption budget support
* address feedback
(cherry picked from commit 845ced63e9410d3346d189f52b531649f18a7325)
Co-authored-by: Anton Borisov <14...@users.noreply.github.com>
---
helm/templates/NOTES.txt | 1 +
helm/templates/_helpers.tpl | 31 +++
helm/templates/{NOTES.txt => pdb-coordinator.yaml} | 25 +-
helm/templates/{NOTES.txt => pdb-tablet.yaml} | 25 +-
helm/templates/sts-coordinator.yaml | 7 +
helm/templates/sts-tablet.yaml | 7 +
helm/tests/pod_metadata_and_pdb_test.yaml | 285 +++++++++++++++++++++
helm/values.yaml | 12 +
website/docs/install-deploy/deploying-with-helm.md | 10 +
9 files changed, 391 insertions(+), 12 deletions(-)
diff --git a/helm/templates/NOTES.txt b/helm/templates/NOTES.txt
index 7a2dfd2dd..e47360e6c 100644
--- a/helm/templates/NOTES.txt
+++ b/helm/templates/NOTES.txt
@@ -22,3 +22,4 @@ APP VERSION: {{ .Chart.AppVersion }}
{{ include "fluss.security.validateValues" . }}
{{ include "fluss.metrics.validateValues" . }}
+{{ include "fluss.pdb.validateValues" . }}
diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl
index 5fe371e0c..3933debca 100644
--- a/helm/templates/_helpers.tpl
+++ b/helm/templates/_helpers.tpl
@@ -100,3 +100,34 @@ imagePullSecrets:
{{- end }}
{{- end }}
+{{/*
+ Validate PodDisruptionBudget for a given component.
+ Usage: include "fluss.pdb.validate" (dict "component" "tablet" "pdb" .Values.tablet.podDisruptionBudget)
+*/}}
+{{- define "fluss.pdb.validate" -}}
+{{- if .pdb.enabled -}}
+ {{- $hasMin := hasKey .pdb "minAvailable" -}}
+ {{- $hasMax := hasKey .pdb "maxUnavailable" -}}
+ {{- if and $hasMin $hasMax -}}
+ {{- printf "%s.podDisruptionBudget: cannot set both minAvailable and maxUnavailable" .component -}}
+ {{- else if not (or $hasMin $hasMax) -}}
+ {{- printf "%s.podDisruptionBudget: must set either minAvailable or maxUnavailable when enabled" .component -}}
+ {{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+ Aggregate PDB validation for all components.
+ include "fluss.pdb.validateValues" .
+*/}}
+{{- define "fluss.pdb.validateValues" -}}
+{{- $errMessages := list -}}
+{{- $errMessages = append $errMessages (include "fluss.pdb.validate" (dict "component" "tablet" "pdb" .Values.tablet.podDisruptionBudget)) -}}
+{{- $errMessages = append $errMessages (include "fluss.pdb.validate" (dict "component" "coordinator" "pdb" .Values.coordinator.podDisruptionBudget)) -}}
+{{- $errMessages = without $errMessages "" -}}
+{{- $errMessage := join "\n" $errMessages -}}
+{{- if $errMessage -}}
+{{- printf "\nPDB VALIDATION:\n%s" $errMessage | fail -}}
+{{- end -}}
+{{- end -}}
+
diff --git a/helm/templates/NOTES.txt b/helm/templates/pdb-coordinator.yaml
similarity index 53%
copy from helm/templates/NOTES.txt
copy to helm/templates/pdb-coordinator.yaml
index 7a2dfd2dd..79e03f345 100644
--- a/helm/templates/NOTES.txt
+++ b/helm/templates/pdb-coordinator.yaml
@@ -16,9 +16,22 @@
# limitations under the License.
#
-CHART NAME: {{ .Chart.Name }}
-CHART VERSION: {{ .Chart.Version }}
-APP VERSION: {{ .Chart.AppVersion }}
-
-{{ include "fluss.security.validateValues" . }}
-{{ include "fluss.metrics.validateValues" . }}
+{{- if .Values.coordinator.podDisruptionBudget.enabled }}
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: coordinator-server
+ labels:
+ {{- include "fluss.labels" . | nindent 4 }}
+spec:
+ {{- if hasKey .Values.coordinator.podDisruptionBudget "minAvailable" }}
+ minAvailable: {{ .Values.coordinator.podDisruptionBudget.minAvailable }}
+ {{- end }}
+ {{- if hasKey .Values.coordinator.podDisruptionBudget "maxUnavailable" }}
+ maxUnavailable: {{ .Values.coordinator.podDisruptionBudget.maxUnavailable }}
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "fluss.selectorLabels" . | nindent 6 }}
+ app.kubernetes.io/component: coordinator
+{{- end }}
diff --git a/helm/templates/NOTES.txt b/helm/templates/pdb-tablet.yaml
similarity index 55%
copy from helm/templates/NOTES.txt
copy to helm/templates/pdb-tablet.yaml
index 7a2dfd2dd..ce7641efd 100644
--- a/helm/templates/NOTES.txt
+++ b/helm/templates/pdb-tablet.yaml
@@ -16,9 +16,22 @@
# limitations under the License.
#
-CHART NAME: {{ .Chart.Name }}
-CHART VERSION: {{ .Chart.Version }}
-APP VERSION: {{ .Chart.AppVersion }}
-
-{{ include "fluss.security.validateValues" . }}
-{{ include "fluss.metrics.validateValues" . }}
+{{- if .Values.tablet.podDisruptionBudget.enabled }}
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: tablet-server
+ labels:
+ {{- include "fluss.labels" . | nindent 4 }}
+spec:
+ {{- if hasKey .Values.tablet.podDisruptionBudget "minAvailable" }}
+ minAvailable: {{ .Values.tablet.podDisruptionBudget.minAvailable }}
+ {{- end }}
+ {{- if hasKey .Values.tablet.podDisruptionBudget "maxUnavailable" }}
+ maxUnavailable: {{ .Values.tablet.podDisruptionBudget.maxUnavailable }}
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "fluss.selectorLabels" . | nindent 6 }}
+ app.kubernetes.io/component: tablet
+{{- end }}
diff --git a/helm/templates/sts-coordinator.yaml b/helm/templates/sts-coordinator.yaml
index fbdd36712..1f5d046a0 100644
--- a/helm/templates/sts-coordinator.yaml
+++ b/helm/templates/sts-coordinator.yaml
@@ -32,8 +32,15 @@ spec:
template:
metadata:
labels:
+ {{- with .Values.coordinator.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
{{- include "fluss.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: coordinator
+ {{- with .Values.coordinator.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
spec:
{{- if .Values.serviceAccount.create }}
serviceAccountName: {{ .Values.serviceAccount.name | default (include "fluss.fullname" .) }}
diff --git a/helm/templates/sts-tablet.yaml b/helm/templates/sts-tablet.yaml
index bb8be8b57..94710561e 100644
--- a/helm/templates/sts-tablet.yaml
+++ b/helm/templates/sts-tablet.yaml
@@ -32,8 +32,15 @@ spec:
template:
metadata:
labels:
+ {{- with .Values.tablet.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
{{- include "fluss.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: tablet
+ {{- with .Values.tablet.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
spec:
{{- if .Values.serviceAccount.create }}
serviceAccountName: {{ .Values.serviceAccount.name | default (include "fluss.fullname" .) }}
diff --git a/helm/tests/pod_metadata_and_pdb_test.yaml b/helm/tests/pod_metadata_and_pdb_test.yaml
new file mode 100644
index 000000000..53527568f
--- /dev/null
+++ b/helm/tests/pod_metadata_and_pdb_test.yaml
@@ -0,0 +1,285 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+suite: pod-metadata-defaults
+templates:
+ - templates/sts-tablet.yaml
+ - templates/sts-coordinator.yaml
+
+tests:
+ - it: should not render pod annotations by default on tablet
+ asserts:
+ - isNull:
+ path: spec.template.metadata.annotations
+ template: templates/sts-tablet.yaml
+
+ - it: should not render pod annotations by default on coordinator
+ asserts:
+ - isNull:
+ path: spec.template.metadata.annotations
+ template: templates/sts-coordinator.yaml
+
+---
+
+suite: tablet-pod-annotations
+templates:
+ - templates/sts-tablet.yaml
+
+tests:
+ - it: should render pod annotations on tablet
+ set:
+ tablet.podAnnotations:
+ prometheus.io/scrape: "true"
+ prometheus.io/port: "9249"
+ asserts:
+ - equal:
+ path: spec.template.metadata.annotations
+ value:
+ prometheus.io/scrape: "true"
+ prometheus.io/port: "9249"
+
+ - it: should not apply coordinator annotations to tablet
+ set:
+ coordinator.podAnnotations:
+ prometheus.io/scrape: "true"
+ asserts:
+ - isNull:
+ path: spec.template.metadata.annotations
+
+---
+
+suite: coordinator-pod-annotations
+templates:
+ - templates/sts-coordinator.yaml
+
+tests:
+ - it: should render pod annotations on coordinator
+ set:
+ coordinator.podAnnotations:
+ prometheus.io/scrape: "true"
+ asserts:
+ - equal:
+ path: spec.template.metadata.annotations
+ value:
+ prometheus.io/scrape: "true"
+
+---
+
+suite: tablet-pod-labels
+templates:
+ - templates/sts-tablet.yaml
+
+tests:
+ - it: should render custom pod labels on tablet
+ set:
+ tablet.podLabels:
+ team: data-platform
+ env: production
+ asserts:
+ - equal:
+ path: spec.template.metadata.labels.team
+ value: data-platform
+ - equal:
+ path: spec.template.metadata.labels.env
+ value: production
+
+ - it: should preserve built-in labels when custom labels are added
+ set:
+ tablet.podLabels:
+ custom: label
+ asserts:
+ - equal:
+ path: spec.template.metadata.labels["app.kubernetes.io/component"]
+ value: tablet
+ - equal:
+ path: spec.template.metadata.labels.custom
+ value: label
+
+---
+
+suite: coordinator-pod-labels
+templates:
+ - templates/sts-coordinator.yaml
+
+tests:
+ - it: should render custom pod labels on coordinator
+ set:
+ coordinator.podLabels:
+ team: data-platform
+ asserts:
+ - equal:
+ path: spec.template.metadata.labels.team
+ value: data-platform
+
+---
+
+suite: pdb-defaults
+templates:
+ - templates/pdb-tablet.yaml
+ - templates/pdb-coordinator.yaml
+
+tests:
+ - it: should not render tablet PDB by default
+ asserts:
+ - hasDocuments:
+ count: 0
+ template: templates/pdb-tablet.yaml
+
+ - it: should not render coordinator PDB by default
+ asserts:
+ - hasDocuments:
+ count: 0
+ template: templates/pdb-coordinator.yaml
+
+---
+
+suite: tablet-pdb
+templates:
+ - templates/pdb-tablet.yaml
+
+tests:
+ - it: should render tablet PDB with minAvailable
+ set:
+ tablet.podDisruptionBudget:
+ enabled: true
+ minAvailable: 2
+ asserts:
+ - hasDocuments:
+ count: 1
+ - equal:
+ path: kind
+ value: PodDisruptionBudget
+ - equal:
+ path: metadata.name
+ value: tablet-server
+ - equal:
+ path: spec.minAvailable
+ value: 2
+ - equal:
+ path: spec.selector.matchLabels["app.kubernetes.io/component"]
+ value: tablet
+
+ - it: should render tablet PDB with maxUnavailable
+ set:
+ tablet.podDisruptionBudget:
+ enabled: true
+ maxUnavailable: 1
+ asserts:
+ - equal:
+ path: spec.maxUnavailable
+ value: 1
+ - isNull:
+ path: spec.minAvailable
+
+---
+
+suite: coordinator-pdb
+templates:
+ - templates/pdb-coordinator.yaml
+
+tests:
+ - it: should render coordinator PDB with minAvailable
+ set:
+ coordinator.podDisruptionBudget:
+ enabled: true
+ minAvailable: 1
+ asserts:
+ - hasDocuments:
+ count: 1
+ - equal:
+ path: kind
+ value: PodDisruptionBudget
+ - equal:
+ path: metadata.name
+ value: coordinator-server
+ - equal:
+ path: spec.minAvailable
+ value: 1
+ - equal:
+ path: spec.selector.matchLabels["app.kubernetes.io/component"]
+ value: coordinator
+
+---
+
+suite: pdb-validation
+templates:
+ - templates/NOTES.txt
+
+tests:
+ - it: should fail when both minAvailable and maxUnavailable are set on tablet
+ set:
+ tablet.podDisruptionBudget:
+ enabled: true
+ minAvailable: 2
+ maxUnavailable: 1
+ asserts:
+ - failedTemplate:
+ errorPattern: "cannot set both minAvailable and maxUnavailable"
+
+ - it: should fail when neither minAvailable nor maxUnavailable is set on tablet
+ set:
+ tablet.podDisruptionBudget:
+ enabled: true
+ asserts:
+ - failedTemplate:
+ errorPattern: "must set either minAvailable or maxUnavailable when enabled"
+
+ - it: should fail when both minAvailable and maxUnavailable are set on coordinator
+ set:
+ coordinator.podDisruptionBudget:
+ enabled: true
+ minAvailable: 1
+ maxUnavailable: 1
+ asserts:
+ - failedTemplate:
+ errorPattern: "cannot set both minAvailable and maxUnavailable"
+
+ - it: should fail when neither minAvailable nor maxUnavailable is set on coordinator
+ set:
+ coordinator.podDisruptionBudget:
+ enabled: true
+ asserts:
+ - failedTemplate:
+ errorPattern: "must set either minAvailable or maxUnavailable when enabled"
+
+---
+
+suite: pdb-zero-values
+templates:
+ - templates/pdb-tablet.yaml
+
+tests:
+ - it: should render tablet PDB with minAvailable set to zero
+ set:
+ tablet.podDisruptionBudget:
+ enabled: true
+ minAvailable: 0
+ asserts:
+ - equal:
+ path: spec.minAvailable
+ value: 0
+
+ - it: should render tablet PDB with maxUnavailable set to zero
+ set:
+ tablet.podDisruptionBudget:
+ enabled: true
+ maxUnavailable: 0
+ asserts:
+ - equal:
+ path: spec.maxUnavailable
+ value: 0
diff --git a/helm/values.yaml b/helm/values.yaml
index bf9f3022e..082b22b26 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -46,6 +46,12 @@ tablet:
extraVolumes: []
extraVolumeMounts: []
initContainers: []
+ podAnnotations: {}
+ podLabels: {}
+ podDisruptionBudget:
+ enabled: false
+ # minAvailable: 1
+ # maxUnavailable: 1
# Pod scheduling configuration
affinity: {}
# Example: spread tablet server pods across availability zones and nodes.
@@ -81,6 +87,12 @@ coordinator:
extraVolumes: []
extraVolumeMounts: []
initContainers: []
+ podAnnotations: {}
+ podLabels: {}
+ podDisruptionBudget:
+ enabled: false
+ # minAvailable: 1
+ # maxUnavailable: 1
affinity: {}
nodeSelector: {}
tolerations: []
diff --git a/website/docs/install-deploy/deploying-with-helm.md b/website/docs/install-deploy/deploying-with-helm.md
index 270c366df..f38a56299 100644
--- a/website/docs/install-deploy/deploying-with-helm.md
+++ b/website/docs/install-deploy/deploying-with-helm.md
@@ -284,9 +284,19 @@ It is recommended to set these explicitly in production.
| `coordinator.extraVolumes` | Extra volumes to add to the CoordinatorServer pod spec | `[]` |
| `coordinator.extraVolumeMounts` | Extra volume mounts to add to the coordinator container | `[]` |
| `coordinator.initContainers` | Init containers to run before the coordinator container starts | `[]` |
+| `coordinator.podAnnotations` | Annotations to add to CoordinatorServer pods | `{}` |
+| `coordinator.podLabels` | Additional labels to add to CoordinatorServer pods | `{}` |
+| `coordinator.podDisruptionBudget.enabled` | Enable PodDisruptionBudget for CoordinatorServer | `false` |
+| `coordinator.podDisruptionBudget.minAvailable` | Minimum available coordinator pods during disruption | Not set |
+| `coordinator.podDisruptionBudget.maxUnavailable` | Maximum unavailable coordinator pods during disruption | Not set |
| `tablet.extraVolumes` | Extra volumes to add to TabletServer pod specs | `[]` |
| `tablet.extraVolumeMounts` | Extra volume mounts to add to the tablet container | `[]` |
| `tablet.initContainers` | Init containers to run before the tablet container starts | `[]` |
+| `tablet.podAnnotations` | Annotations to add to TabletServer pods | `{}` |
+| `tablet.podLabels` | Additional labels to add to TabletServer pods | `{}` |
+| `tablet.podDisruptionBudget.enabled` | Enable PodDisruptionBudget for TabletServer | `false` |
+| `tablet.podDisruptionBudget.minAvailable` | Minimum available tablet server pods during disruption | Not set |
+| `tablet.podDisruptionBudget.maxUnavailable` | Maximum unavailable tablet server pods during disruption | Not set |
## Advanced Configuration