This is an automated email from the ASF dual-hosted git repository.
ipolyzos pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fluss.git
The following commit(s) were added to refs/heads/main by this push:
new 2b207a479 [helm] Enable metrics reporting in helm charts (#2711)
2b207a479 is described below
commit 2b207a479806bbeb769c8e4f642966913b203c26
Author: Muhammet Orazov <[email protected]>
AuthorDate: Thu Mar 26 11:54:22 2026 +0100
[helm] Enable metrics reporting in helm charts (#2711)
---
Co-authored-by: Lorenzo Affetti <[email protected]>
---
helm/templates/NOTES.txt | 1 +
helm/templates/_helpers.tpl | 1 +
helm/templates/_metrics.tpl | 134 ++++++++++
helm/templates/configmap.yaml | 11 +
helm/templates/svc-metrics-coordinator.yaml | 47 ++++
helm/templates/svc-metrics-tablet.yaml | 47 ++++
helm/tests/metrics_test.yaml | 273 +++++++++++++++++++++
helm/values.yaml | 11 +
website/docs/install-deploy/deploying-with-helm.md | 69 +++++-
9 files changed, 593 insertions(+), 1 deletion(-)
diff --git a/helm/templates/NOTES.txt b/helm/templates/NOTES.txt
index d7a4af26f..7a2dfd2dd 100644
--- a/helm/templates/NOTES.txt
+++ b/helm/templates/NOTES.txt
@@ -21,3 +21,4 @@ CHART VERSION: {{ .Chart.Version }}
APP VERSION: {{ .Chart.AppVersion }}
{{ include "fluss.security.validateValues" . }}
+{{ include "fluss.metrics.validateValues" . }}
diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl
index ee13b2cb6..5fe371e0c 100644
--- a/helm/templates/_helpers.tpl
+++ b/helm/templates/_helpers.tpl
@@ -99,3 +99,4 @@ imagePullSecrets:
{{- end }}
{{- end }}
{{- end }}
+
diff --git a/helm/templates/_metrics.tpl b/helm/templates/_metrics.tpl
new file mode 100644
index 000000000..ccdcd6497
--- /dev/null
+++ b/helm/templates/_metrics.tpl
@@ -0,0 +1,134 @@
+#
+# 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.
+#
+
+{{/*
+Returns list of provided reporter names.
+*/}}
+{{- define "fluss.metrics.reporterNames" -}}
+{{- $metrics := .Values.metrics | default dict -}}
+{{- $reportersValue := (index $metrics "reporters" | default "") | toString |
trim -}}
+{{- if eq $reportersValue "" -}}
+[]
+{{- else -}}
+{{- $selected := list -}}
+{{- range $raw := regexSplit "\\s*,\\s*" $reportersValue -1 -}}
+{{- $name := trim $raw -}}
+{{- if ne $name "" -}}
+{{- $selected = append $selected $name -}}
+{{- end -}}
+{{- end -}}
+{{- $selected | toYaml -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Checks if metrics reporting is enabled, with any one of the reporters.
+*/}}
+{{- define "fluss.metrics.enabled" -}}
+{{- $reporters := include "fluss.metrics.reporterNames" . | fromYamlArray -}}
+{{- if gt (len $reporters) 0 -}}
+true
+{{- end -}}
+{{- end -}}
+
+{{/*
+Checks if a specific reporter is enabled.
+Usage:
+ {{ include "fluss.metrics.reporter.enabled" (dict "reporter" "prometheus"
"ctx" .) }}
+ {{ include "fluss.metrics.reporter.enabled" (dict "reporter" "jmx"
"ctx" .) }}
+*/}}
+{{- define "fluss.metrics.reporter.enabled" -}}
+{{- $reporterNames := include "fluss.metrics.reporterNames" .ctx |
fromYamlArray -}}
+{{- if has .reporter $reporterNames -}}
+true
+{{- end -}}
+{{- end -}}
+
+{{/*
+Checks if prometheus reporter is enabled.
+*/}}
+{{- define "fluss.metrics.reporter.prometheus.enabled" -}}
+{{- include "fluss.metrics.reporter.enabled" (dict "reporter" "prometheus"
"ctx" .) -}}
+{{- end -}}
+
+{{/*
+Checks if jmx reporter is enabled.
+*/}}
+{{- define "fluss.metrics.reporter.jmx.enabled" -}}
+{{- include "fluss.metrics.reporter.enabled" (dict "reporter" "jmx" "ctx" .)
-}}
+{{- end -}}
+
+{{/*
+Validates that each enabled reporter has a port configured.
+*/}}
+{{- define "fluss.metrics.validateReporterPorts" -}}
+{{- $metrics := .Values.metrics | default dict -}}
+{{- $reporterNames := include "fluss.metrics.reporterNames" . | fromYamlArray
-}}
+{{- range $name := $reporterNames -}}
+ {{- $reporterConfig := index $metrics $name | default dict -}}
+ {{- if not $reporterConfig.port -}}
+ {{- printf "metrics.%s.port must be set when metrics.reporters includes
%s" $name $name -}}
+ {{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Validates that reporter ports are not set via configurationOverrides.
+*/}}
+{{- define "fluss.metrics.validateNoPortOverrides" -}}
+{{- $config := .Values.configurationOverrides | default dict -}}
+{{- $reporterNames := include "fluss.metrics.reporterNames" . | fromYamlArray
-}}
+{{- range $name := $reporterNames -}}
+ {{- $portKey := printf "metrics.reporter.%s.port" $name -}}
+ {{- if hasKey $config $portKey -}}
+ {{- printf "metrics.reporter.%s.port must be set via metrics.%s.port in
values.yaml, not via configurationOverrides" $name $name -}}
+ {{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Validates that metrics.reporters is not set via configurationOverrides.
+*/}}
+{{- define "fluss.metrics.validateNoReportersOverrides" -}}
+{{- $config := .Values.configurationOverrides | default dict -}}
+{{- if hasKey $config "metrics.reporters" -}}
+ {{- printf "metrics.reporters must be set via metrics.reporters in
values.yaml, not via configurationOverrides" -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Validates metrics configuration values.
+Usage:
+ include "fluss.metrics.validateValues" .
+*/}}
+{{- define "fluss.metrics.validateValues" -}}
+
+{{- $errMessages := list -}}
+{{- $errMessages = append $errMessages (include
"fluss.metrics.validateReporterPorts" .) -}}
+{{- $errMessages = append $errMessages (include
"fluss.metrics.validateNoPortOverrides" .) -}}
+{{- $errMessages = append $errMessages (include
"fluss.metrics.validateNoReportersOverrides" .) -}}
+
+{{- $errMessages = without $errMessages "" -}}
+{{- $errMessage := join "\n" $errMessages -}}
+
+{{- if $errMessage -}}
+{{- printf "\nVALUES VALIDATION:\n%s" $errMessage | fail -}}
+{{- end -}}
+
+{{- end -}}
+
diff --git a/helm/templates/configmap.yaml b/helm/templates/configmap.yaml
index 78c618c4d..66f3eb095 100644
--- a/helm/templates/configmap.yaml
+++ b/helm/templates/configmap.yaml
@@ -41,4 +41,15 @@ data:
client.security.protocol: SASL
client.security.sasl.mechanism: {{ upper $internalMechanism }}
{{- end }}
+
+ {{- end }}
+
+ {{- if include "fluss.metrics.enabled" . }}
+ ### Metrics
+
+ metrics.reporters: {{ .Values.metrics.reporters }}
+ {{- range $name := (include "fluss.metrics.reporterNames" . |
fromYamlArray) }}
+ {{ printf "metrics.reporter.%s.port" $name }}: {{ (index $.Values.metrics
$name).port }}
+ {{- end }}
+
{{- end }}
diff --git a/helm/templates/svc-metrics-coordinator.yaml
b/helm/templates/svc-metrics-coordinator.yaml
new file mode 100644
index 000000000..77bbd94bf
--- /dev/null
+++ b/helm/templates/svc-metrics-coordinator.yaml
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+{{- if include "fluss.metrics.reporter.prometheus.enabled" . }}
+{{- $prometheus := .Values.metrics.prometheus | default dict }}
+{{- $promSvc := $prometheus.service | default dict }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Release.Name }}-coordinator-server-metrics-hs
+ labels:
+ {{- include "fluss.labels" . | nindent 4 }}
+ app.kubernetes.io/component: metrics
+ {{- with $promSvc.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with $promSvc.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ clusterIP: None
+ type: ClusterIP
+ ports:
+ - name: {{ default "metrics" $promSvc.portName }}
+ protocol: TCP
+ port: {{ $prometheus.port }}
+ targetPort: {{ $prometheus.port }}
+ selector:
+ {{- include "fluss.selectorLabels" . | nindent 4 }}
+ app.kubernetes.io/component: coordinator
+{{- end }}
diff --git a/helm/templates/svc-metrics-tablet.yaml
b/helm/templates/svc-metrics-tablet.yaml
new file mode 100644
index 000000000..2ecb59712
--- /dev/null
+++ b/helm/templates/svc-metrics-tablet.yaml
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+{{- if include "fluss.metrics.reporter.prometheus.enabled" . }}
+{{- $prometheus := .Values.metrics.prometheus | default dict }}
+{{- $promSvc := $prometheus.service | default dict }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Release.Name }}-tablet-server-metrics-hs
+ labels:
+ {{- include "fluss.labels" . | nindent 4 }}
+ app.kubernetes.io/component: metrics
+ {{- with $promSvc.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with $promSvc.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ clusterIP: None
+ type: ClusterIP
+ ports:
+ - name: {{ default "metrics" $promSvc.portName }}
+ protocol: TCP
+ port: {{ $prometheus.port }}
+ targetPort: {{ $prometheus.port }}
+ selector:
+ {{- include "fluss.selectorLabels" . | nindent 4 }}
+ app.kubernetes.io/component: tablet
+{{- end }}
diff --git a/helm/tests/metrics_test.yaml b/helm/tests/metrics_test.yaml
new file mode 100644
index 000000000..8352e0aad
--- /dev/null
+++ b/helm/tests/metrics_test.yaml
@@ -0,0 +1,273 @@
+#
+# 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: metrics-disabled-configmap
+templates:
+ - templates/configmap.yaml
+tests:
+ - it: does not add metrics reporter settings when reporters are empty
+ asserts:
+ - notMatchRegex:
+ path: data["server.yaml"]
+ pattern: 'metrics\.reporters:'
+ - notMatchRegex:
+ path: data["server.yaml"]
+ pattern: 'metrics\.reporter\.prometheus\.port:'
+---
+
+suite: metrics-enabled-configmap
+templates:
+ - templates/configmap.yaml
+tests:
+ - it: renders prometheus reporter port from values
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus:
+ port: 9249
+ asserts:
+ - matchRegex:
+ path: data["server.yaml"]
+ pattern: 'metrics\.reporters:\s*prometheus'
+ - matchRegex:
+ path: data["server.yaml"]
+ pattern: 'metrics\.reporter\.prometheus\.port:\s*9249'
+---
+
+suite: metrics-enabled-configmap-custom-reporters
+templates:
+ - templates/configmap.yaml
+tests:
+ - it: renders multiple reporter ports from structured metrics values
+ set:
+ metrics.reporters: grph,prometheus
+ metrics.grph:
+ port: 9020
+ metrics.prometheus:
+ port: 9249
+ asserts:
+ - matchRegex:
+ path: data["server.yaml"]
+ pattern: 'metrics\.reporters:\s*grph,prometheus'
+ - matchRegex:
+ path: data["server.yaml"]
+ pattern: 'metrics\.reporter\.grph\.port:\s*9020'
+ - matchRegex:
+ path: data["server.yaml"]
+ pattern: 'metrics\.reporter\.prometheus\.port:\s*9249'
+---
+
+suite: metrics-invalid-config
+templates:
+ - templates/NOTES.txt
+tests:
+ - it: fails when selected reporter port is missing
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus: null
+ asserts:
+ - failedTemplate:
+ errorMessage: "VALUES VALIDATION:\nmetrics.prometheus.port must be
set when metrics.reporters includes prometheus"
+ - it: fails when selected reporter port is empty
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus:
+ port: ""
+ asserts:
+ - failedTemplate:
+ errorMessage: "VALUES VALIDATION:\nmetrics.prometheus.port must be
set when metrics.reporters includes prometheus"
+---
+
+suite: metrics-config-overrides-precedence
+templates:
+ - templates/NOTES.txt
+tests:
+ - it: fails when reporter port is set via configurationOverrides
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus:
+ port: 9249
+ configurationOverrides:
+ metrics.reporter.prometheus.port: 9300
+ asserts:
+ - failedTemplate:
+ errorMessage: "VALUES VALIDATION:\nmetrics.reporter.prometheus.port
must be set via metrics.prometheus.port in values.yaml, not via
configurationOverrides"
+---
+
+suite: metrics-config-overrides-reporters
+templates:
+ - templates/NOTES.txt
+tests:
+ - it: fails when metrics.reporters is set via configurationOverrides
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus:
+ port: 9249
+ configurationOverrides:
+ metrics.reporters: prometheus
+ asserts:
+ - failedTemplate:
+ errorMessage: "VALUES VALIDATION:\nmetrics.reporters must be set via
metrics.reporters in values.yaml, not via configurationOverrides"
+---
+
+suite: metrics-service-disabled
+templates:
+ - templates/svc-metrics-coordinator.yaml
+tests:
+ - it: does not render coordinator metrics service when reporters are empty
+ asserts:
+ - hasDocuments:
+ count: 0
+ - it: does not render coordinator metrics service when prometheus reporter
is absent
+ set:
+ metrics.reporters: jmx
+ metrics.jmx:
+ port: 9250
+ asserts:
+ - hasDocuments:
+ count: 0
+---
+
+suite: metrics-service-enabled
+templates:
+ - templates/svc-metrics-coordinator.yaml
+tests:
+ - it: renders coordinator metrics service with named metrics port
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus:
+ port: 9249
+ asserts:
+ - equal:
+ path: metadata.name
+ value: RELEASE-NAME-coordinator-server-metrics-hs
+ - equal:
+ path: spec.ports[0].name
+ value: metrics
+ - equal:
+ path: spec.ports[0].port
+ value: 9249
+ - equal:
+ path: spec.clusterIP
+ value: None
+ - it: renders custom port name and service labels for ServiceMonitor
selectors
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus.service.portName: fluss-metrics
+ metrics.prometheus.service.labels:
+ monitoring: enabled
+ asserts:
+ - equal:
+ path: spec.ports[0].name
+ value: fluss-metrics
+ - equal:
+ path: metadata.labels.monitoring
+ value: enabled
+ - it: renders value-driven annotations on metrics service when provided
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus.service.annotations:
+ prometheus.io/scrape: "true"
+ prometheus.io/path: "/metrics"
+ prometheus.io/port: "9249"
+ asserts:
+ - equal:
+ path: metadata.annotations["prometheus.io/scrape"]
+ value: "true"
+ - equal:
+ path: metadata.annotations["prometheus.io/path"]
+ value: "/metrics"
+ - equal:
+ path: metadata.annotations["prometheus.io/port"]
+ value: "9249"
+ - it: renders no annotations when not configured
+ set:
+ metrics.reporters: prometheus
+ asserts:
+ - isNull:
+ path: metadata.annotations
+ - it: uses metrics component label
+ set:
+ metrics.reporters: prometheus
+ asserts:
+ - equal:
+ path: metadata.labels["app.kubernetes.io/component"]
+ value: metrics
+ - it: uses port from values on service
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus:
+ port: 9249
+ asserts:
+ - equal:
+ path: spec.ports[0].port
+ value: 9249
+ - equal:
+ path: spec.ports[0].targetPort
+ value: 9249
+---
+
+suite: pod-service-separation
+templates:
+ - templates/svc-coordinator.yaml
+ - templates/svc-tablet.yaml
+tests:
+ - it: keeps coordinator pod service without metrics annotations
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus.service.annotations:
+ prometheus.io/scrape: "true"
+ template: templates/svc-coordinator.yaml
+ asserts:
+ - notExists:
+ path: metadata.annotations
+ - it: keeps tablet pod service without metrics annotations
+ set:
+ metrics.reporters: prometheus
+ metrics.prometheus.service.annotations:
+ prometheus.io/scrape: "true"
+ template: templates/svc-tablet.yaml
+ asserts:
+ - notExists:
+ path: metadata.annotations
+---
+
+suite: metrics-enabled-statefulset
+templates:
+ - templates/sts-coordinator.yaml
+ - templates/sts-tablet.yaml
+tests:
+ - it: does not expose metrics container port for coordinator
+ set:
+ metrics.reporters: prometheus
+ template: templates/sts-coordinator.yaml
+ asserts:
+ - notContains:
+ path: spec.template.spec.containers[0].ports
+ content:
+ name: metrics
+ containerPort: 9249
+ - it: does not expose metrics container port for tablet
+ set:
+ metrics.reporters: prometheus
+ template: templates/sts-tablet.yaml
+ asserts:
+ - notContains:
+ path: spec.template.spec.containers[0].ports
+ content:
+ name: metrics
+ containerPort: 9249
diff --git a/helm/values.yaml b/helm/values.yaml
index 521553f67..63c11e724 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -75,6 +75,17 @@ security:
username: ""
password: ""
+metrics:
+ reporters: ""
+ prometheus:
+ port: 9249
+ service:
+ portName: metrics
+ labels: {}
+ annotations: {}
+ jmx:
+ port: 9250
+
resources: {}
# We usually recommend not to specify default resources and to leave this as
a conscious
# choice for the user. This also increases chances charts run on
environments with little
diff --git a/website/docs/install-deploy/deploying-with-helm.md
b/website/docs/install-deploy/deploying-with-helm.md
index 9bda9f1a8..ba9a8932b 100644
--- a/website/docs/install-deploy/deploying-with-helm.md
+++ b/website/docs/install-deploy/deploying-with-helm.md
@@ -139,7 +139,7 @@ The Fluss Helm chart deploys the following Kubernetes
resources:
- **CoordinatorServer**: 1x StatefulSet with Headless Service for cluster
coordination
- **TabletServer**: 3x StatefulSet with Headless Service for data storage and
processing
- **ConfigMap**: Configuration management for `server.yaml` settings
-- **Services**: Headless services providing stable pod DNS names
+- **Services**: Headless services providing stable pod DNS names, plus
optional dedicated headless services when metrics are enabled
### Step 3: Verify Installation
@@ -202,6 +202,17 @@ If the internal SASL username or password is left empty,
the chart automatically
It is recommended to set these explicitly in production.
+### Metrics Parameters
+
+| Parameter | Description | Default |
+|-----------|-------------|---------|
+| `metrics.reporters` | Comma-separated reporter selector; use `""` to disable
metrics | `""` |
+| `metrics.jmx.port` | JMX reporter port range | `9250` |
+| `metrics.prometheus.port` | Prometheus reporter port | `9249` |
+| `metrics.prometheus.service.portName` | Named port exposed on metrics
services | `metrics` |
+| `metrics.prometheus.service.labels` | Additional labels added to metrics
services | `{}` |
+| `metrics.prometheus.service.annotations` | Optional annotations added to
metrics services | `{}` |
+
### Fluss Configuration Overrides
| Parameter | Description | Default |
@@ -314,6 +325,62 @@ security:
password: internal-password
```
+### Metrics and Monitoring
+
+When `metrics.reporters` is set, the chart adds the following `server.yaml`
configuration entries:
+
+- `metrics.reporters`: comma-separated reporter names from `metrics.reporters`
+- `metrics.reporter.<name>.port`: port value from `metrics.<name>.port`
+
+These values are managed by the chart and cannot be set via
`configurationOverrides`. All other metrics reporter options (refer to the
[Fluss
configuration](https://fluss.apache.org/docs/maintenance/configuration/#metrics))
should be specified via `configurationOverrides`.
+
+#### Prometheus Annotation Based Scraping
+
+The example values below show how to add annotations to the metrics services
so that a Prometheus server can discover and scrape them automatically based on
the annotations:
+
+```yaml
+metrics:
+ reporters: prometheus
+ prometheus:
+ port: 9249
+ service:
+ annotations:
+ prometheus.io/scrape: "true"
+ prometheus.io/path: "/metrics"
+ prometheus.io/port: "9249"
+```
+
+#### Prometheus ServiceMonitor Based Scraping
+
+Similarly, if using the [Prometheus
Operator](https://prometheus-operator.dev/), use the values below to add labels
to the metrics services:
+
+```yaml
+metrics:
+ reporters: prometheus
+ prometheus:
+ port: 9249
+ service:
+ portName: metrics
+ labels:
+ monitoring: enabled
+```
+
+Then create a
[`ServiceMonitor`](https://prometheus-operator.dev/docs/api-reference/api/#monitoring.coreos.com/v1.ServiceMonitor)
that selects them matching the labels:
+
+```yaml
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: fluss-metrics
+spec:
+ selector:
+ matchLabels:
+ monitoring: enabled
+ endpoints:
+ # Matches `metrics.prometheus.service.portName`
+ - port: metrics
+```
+
### Storage Configuration
Configure different storage volumes for coordinator or tablet pods: