Skip to content

Commit e0c0d76

Browse files
authored
Merge pull request #34 from upcloud-tools/helm/observability
feat: add metrics support to helm chart and the driver
2 parents 393380d + 9c1792b commit e0c0d76

20 files changed

Lines changed: 781 additions & 18 deletions

AGENTS.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,13 @@
88
- **Security policy**: Defined in `SECURITY.md` at the repo root. Direct reporters to GitHub's Private vulnerability reporting tool.
99
- **Code scanning**: Use `github/codeql-action` (latest v3.x, pinned by SHA) with `go` language matrix.
1010
- **Dependabot**: Config in `.github/dependabot.yml` tracks `gomod`, `github-actions`, and `docker` ecosystems daily.
11+
- **Versioning and changelogs**:
12+
- Two separate changelogs, never mix: `/CHANGELOG.md` for app (Go code), `deploy/helm/CHANGELOG.md` for Helm chart (templates, values, schema)
13+
- App version format `vX.Y.Z` — tracked in `deploy/helm/Chart.yaml` (`appVersion`) and root `CHANGELOG.md`
14+
- Chart version format `X.Y.Z` — tracked in `deploy/helm/Chart.yaml` (`version`) and Helm `CHANGELOG.md`
15+
- When Go code changes: bump `appVersion`, update root `CHANGELOG.md`
16+
- When Helm template/values change: bump chart `version`, update Helm `CHANGELOG.md`
17+
- `artifacthub.io/changes` in `Chart.yaml`: replace with the changes for the current version only, not cumulative across versions
18+
- **Helm chart conventions**:
19+
- `# @schema` annotations inline on same line as value (Traefik style): `fieldName: value # @schema type:[integer, null]`
20+
- Run helm unit tests via `make helm-unittest`

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
## [Unreleased]
5+
## [2.6.0] - 2026-06-20
6+
7+
### Added
8+
- metrics: Prometheus metrics server on `--metrics-address` (default `:8090`) with go/process collectors at `/metrics`
9+
- metrics: CSI gRPC operation counters and histograms — `csi_plugin_operations_total`, `csi_plugin_operation_duration_seconds`, `csi_plugin_operations_in_flight`
10+
- metrics: instrumented UpCloud API client wrapper — `upcloud_api_requests_total`, `upcloud_api_request_duration_seconds`
611

712
## [2.5.1] - 2026-06-20
813

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ validation. Full E2E coverage for snapshot creation and PVC restore from snapsho
3232
Multistage Containerfile produces an Alpine-based image with only the packages required for block storage operations
3333
(`xfsprogs`, `e2fsprogs`, `cloud-utils-growpart`, etc.) — no superfluous binaries.
3434

35+
### Prometheus Metrics
36+
The driver exposes Prometheus metrics at `:8090/metrics` (configurable via `--metrics-address`). Includes:
37+
38+
- **CSI gRPC operations**`csi_plugin_operations_total` (by method + status), `csi_plugin_operation_duration_seconds` (histogram), `csi_plugin_operations_in_flight` (gauge)
39+
- **UpCloud API calls**`upcloud_api_requests_total` (by method + result), `upcloud_api_request_duration_seconds` (histogram)
40+
- **Go runtime** — goroutines, GC, memory, CPU, and file descriptor metrics
41+
42+
The Helm chart provides a ClusterIP metrics Service and optional `ServiceMonitor` / `PrometheusRule` resources for
43+
prometheus-operator. Controller sidecars expose `--http-endpoint` on ports 8080–8083.
44+
3545
## Repository Security
3646

3747
This repository uses the following security and supply-chain measures:

deploy/helm/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Helm chart changelog
22

3+
## [1.5.0] - 2026-06-20
4+
5+
### Changed
6+
- App version bumped to `v2.6.0`
7+
8+
### Added
9+
- `metrics` block with configurable ServiceMonitor and PrometheusRule support — controller sidecars now expose `--http-endpoint` on standard ports (8080-8083) and a ClusterIP metrics Service is created by default
10+
- Driver metrics port (`csi-metrics:8090`) on controller and node, wired into metrics Service and ServiceMonitor
11+
312
## [1.4.0] - 2026-06-20
413

514
### Added

deploy/helm/Chart.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ apiVersion: v2
22
name: upcloud-csi
33
description: CSI driver for UpCloud block storage
44
type: application
5-
version: "1.4.0"
6-
appVersion: "v2.5.1"
5+
version: "1.5.0"
6+
appVersion: "v2.6.0"
77
kubeVersion: ">=1.21.0"
88
keywords:
99
- csi
@@ -25,6 +25,6 @@ annotations:
2525
- name: Support
2626
url: https://github.com/upcloud-tools/upcloud-csi/issues
2727
artifacthub.io/changes: |
28-
- "Add extraObjects support"
29-
- "Add imagePullSecrets per component"
30-
- "Make updateStrategy, lifecycle, topology, and other pod spec fields configurable"
28+
- "Add metrics Service, ServiceMonitor, and PrometheusRule support"
29+
- "Driver plugin exposes Prometheus metrics via --metrics-address flag"
30+
- "Driver metrics port on controller and node, wired into Service and ServiceMonitor"

deploy/helm/templates/controller-statefulset.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ spec:
9292
- "--csi-address=$(ADDRESS)"
9393
- "--v={{ .Values.controller.logLevel | default .Values.logLevel }}"
9494
- "--timeout=600s"
95+
{{- if .Values.metrics.enabled }}
96+
- "--http-endpoint=:8080"
97+
{{- end }}
9598
env:
9699
- name: ADDRESS
97100
value: /var/lib/csi/sockets/pluginproxy/csi.sock
@@ -106,13 +109,22 @@ spec:
106109
resources:
107110
{{- tpl (toYaml .) $ | nindent 12 }}
108111
{{- end }}
112+
{{- if .Values.metrics.enabled }}
113+
ports:
114+
- containerPort: 8080
115+
name: prov-metrics
116+
protocol: TCP
117+
{{- end }}
109118
- name: csi-attacher
110119
image: "{{ .Values.controller.sidecars.csiAttacher.repository }}:{{ .Values.controller.sidecars.csiAttacher.tag }}"
111120
imagePullPolicy: {{ .Values.controller.sidecars.csiAttacher.pullPolicy }}
112121
args:
113122
- "--v={{ .Values.controller.logLevel | default .Values.logLevel }}"
114123
- "--csi-address=$(ADDRESS)"
115124
- "--timeout=600s"
125+
{{- if .Values.metrics.enabled }}
126+
- "--http-endpoint=:8081"
127+
{{- end }}
116128
env:
117129
- name: ADDRESS
118130
value: /var/lib/csi/sockets/pluginproxy/csi.sock
@@ -127,6 +139,12 @@ spec:
127139
resources:
128140
{{- tpl (toYaml .) $ | nindent 12 }}
129141
{{- end }}
142+
{{- if .Values.metrics.enabled }}
143+
ports:
144+
- containerPort: 8081
145+
name: att-metrics
146+
protocol: TCP
147+
{{- end }}
130148
- name: csi-resizer
131149
image: "{{ .Values.controller.sidecars.csiResizer.repository }}:{{ .Values.controller.sidecars.csiResizer.tag }}"
132150
imagePullPolicy: {{ .Values.controller.sidecars.csiResizer.pullPolicy }}
@@ -135,6 +153,9 @@ spec:
135153
- "--timeout=600s"
136154
- "--csi-address=$(ADDRESS)"
137155
- "--handle-volume-inuse-error=true"
156+
{{- if .Values.metrics.enabled }}
157+
- "--http-endpoint=:8082"
158+
{{- end }}
138159
env:
139160
- name: ADDRESS
140161
value: /var/lib/csi/sockets/pluginproxy/csi.sock
@@ -149,6 +170,12 @@ spec:
149170
resources:
150171
{{- tpl (toYaml .) $ | nindent 12 }}
151172
{{- end }}
173+
{{- if .Values.metrics.enabled }}
174+
ports:
175+
- containerPort: 8082
176+
name: res-metrics
177+
protocol: TCP
178+
{{- end }}
152179
- name: csi-snapshotter
153180
image: "{{ .Values.controller.sidecars.csiSnapshotter.repository }}:{{ .Values.controller.sidecars.csiSnapshotter.tag }}"
154181
imagePullPolicy: {{ .Values.controller.sidecars.csiSnapshotter.pullPolicy }}
@@ -157,6 +184,9 @@ spec:
157184
- "--v={{ .Values.controller.logLevel | default .Values.logLevel }}"
158185
- "--timeout=600s"
159186
- "--leader-election=false"
187+
{{- if .Values.metrics.enabled }}
188+
- "--http-endpoint=:8083"
189+
{{- end }}
160190
env:
161191
- name: ADDRESS
162192
value: /var/lib/csi/sockets/pluginproxy/csi.sock
@@ -171,6 +201,12 @@ spec:
171201
resources:
172202
{{- tpl (toYaml .) $ | nindent 12 }}
173203
{{- end }}
204+
{{- if .Values.metrics.enabled }}
205+
ports:
206+
- containerPort: 8083
207+
name: snap-metrics
208+
protocol: TCP
209+
{{- end }}
174210
- name: csi-upcloud-plugin
175211
image: {{ include "upcloud-csi.driverImage" . }}
176212
imagePullPolicy: {{ .Values.image.pullPolicy }}
@@ -179,6 +215,9 @@ spec:
179215
- "--nodehost=$(NODE_ID)"
180216
- "--mode=monolith"
181217
- "--address=tcp://0.0.0.0:13071"
218+
{{- if .Values.metrics.enabled }}
219+
- "--metrics-address=tcp://0.0.0.0:8090"
220+
{{- end }}
182221
env:
183222
- name: CSI_ENDPOINT
184223
value: "unix:///var/lib/csi/sockets/pluginproxy/csi.sock"
@@ -208,6 +247,11 @@ spec:
208247
- containerPort: 13071
209248
name: health
210249
protocol: TCP
250+
{{- if .Values.metrics.enabled }}
251+
- containerPort: 8090
252+
name: csi-metrics
253+
protocol: TCP
254+
{{- end }}
211255
livenessProbe:
212256
httpGet:
213257
path: /health

deploy/helm/templates/node-daemonset.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ spec:
121121
- "--nodehost=$(NODE_ID)"
122122
- "--mode=monolith"
123123
- "--address=tcp://0.0.0.0:13071"
124+
{{- if .Values.metrics.enabled }}
125+
- "--metrics-address=tcp://0.0.0.0:8090"
126+
{{- end }}
124127
env:
125128
- name: CSI_ENDPOINT
126129
value: unix:///csi/csi.sock
@@ -150,6 +153,11 @@ spec:
150153
- containerPort: 13071
151154
name: health
152155
protocol: TCP
156+
{{- if .Values.metrics.enabled }}
157+
- containerPort: 8090
158+
name: csi-metrics
159+
protocol: TCP
160+
{{- end }}
153161
livenessProbe:
154162
httpGet:
155163
path: /health
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }}
2+
apiVersion: monitoring.coreos.com/v1
3+
kind: PrometheusRule
4+
metadata:
5+
name: {{ include "upcloud-csi.fullname" . }}
6+
namespace: {{ .Release.Namespace }}
7+
labels:
8+
{{- include "upcloud-csi.labels" . | nindent 4 }}
9+
{{- with .Values.metrics.prometheusRule.additionalLabels }}
10+
{{- toYaml . | nindent 4 }}
11+
{{- end }}
12+
spec:
13+
groups:
14+
- name: upcloud-csi
15+
rules:
16+
{{- toYaml .Values.metrics.prometheusRule.rules | nindent 8 }}
17+
{{- end }}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{{- if .Values.metrics.enabled }}
2+
apiVersion: v1
3+
kind: Service
4+
metadata:
5+
name: {{ include "upcloud-csi.fullname" . }}-metrics
6+
namespace: {{ .Release.Namespace }}
7+
labels:
8+
{{- include "upcloud-csi.labels" . | nindent 4 }}
9+
app.kubernetes.io/component: metrics
10+
spec:
11+
type: ClusterIP
12+
ports:
13+
- name: prov-metrics
14+
port: 8080
15+
targetPort: 8080
16+
protocol: TCP
17+
- name: att-metrics
18+
port: 8081
19+
targetPort: 8081
20+
protocol: TCP
21+
- name: res-metrics
22+
port: 8082
23+
targetPort: 8082
24+
protocol: TCP
25+
- name: snap-metrics
26+
port: 8083
27+
targetPort: 8083
28+
protocol: TCP
29+
- name: csi-metrics
30+
port: 8090
31+
targetPort: 8090
32+
protocol: TCP
33+
selector:
34+
{{- include "upcloud-csi.selectorLabels" . | nindent 4 }}
35+
app: {{ include "upcloud-csi.fullname" . }}-controller
36+
{{- end }}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }}
2+
apiVersion: monitoring.coreos.com/v1
3+
kind: ServiceMonitor
4+
metadata:
5+
name: {{ include "upcloud-csi.fullname" . }}
6+
namespace: {{ .Release.Namespace }}
7+
labels:
8+
{{- include "upcloud-csi.labels" . | nindent 4 }}
9+
{{- with .Values.metrics.serviceMonitor.additionalLabels }}
10+
{{- toYaml . | nindent 4 }}
11+
{{- end }}
12+
spec:
13+
endpoints:
14+
- port: prov-metrics
15+
interval: {{ .Values.metrics.serviceMonitor.interval }}
16+
- port: att-metrics
17+
interval: {{ .Values.metrics.serviceMonitor.interval }}
18+
- port: res-metrics
19+
interval: {{ .Values.metrics.serviceMonitor.interval }}
20+
- port: snap-metrics
21+
interval: {{ .Values.metrics.serviceMonitor.interval }}
22+
- port: csi-metrics
23+
interval: {{ .Values.metrics.serviceMonitor.interval }}
24+
namespaceSelector:
25+
matchNames:
26+
- {{ .Release.Namespace }}
27+
selector:
28+
matchLabels:
29+
{{- include "upcloud-csi.selectorLabels" . | nindent 6 }}
30+
app.kubernetes.io/component: metrics
31+
{{- end }}

0 commit comments

Comments
 (0)