fix(helm): authenticate ServiceMonitor scrapes of the /metrics endpoint

This commit is contained in:
mubashir1osmani 2026-07-07 11:29:16 -07:00
parent 7d15f2fc68
commit 706065c5d8
5 changed files with 86 additions and 1 deletions

View file

@ -18,7 +18,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.1.0
version: 1.2.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to

View file

@ -53,6 +53,10 @@ If `db.useStackgresOperator` is used (not yet implemented):
| `pdb.maxUnavailable` | Maximum number/percentage of pods that can be unavailable during **voluntary** disruptions (choose **one** of minAvailable/maxUnavailable) | `null` |
| `pdb.annotations` | Extra metadata annotations to add to the PDB | `{}` |
| `pdb.labels` | Extra metadata labels to add to the PDB | `{}` |
| `serviceMonitor.enabled` | Create a Prometheus Operator ServiceMonitor that scrapes the proxy's `/metrics/` endpoint | `false` |
| `serviceMonitor.authSecret.enabled` | Authenticate scrapes with a bearer token. The proxy requires authentication on `/metrics` unless `litellm_settings.require_auth_for_metrics_endpoint` is `false`. When `authSecret.name` is empty, the master key secret is used. The master key grants full admin access to the proxy, so consider pointing `authSecret.name`/`authSecret.key` at a secret holding a dedicated virtual key instead. | `true` |
| `serviceMonitor.authSecret.name` | Name of an existing Kubernetes Secret holding the bearer token used to scrape `/metrics/`. Must live in the same namespace as the ServiceMonitor (the release namespace). | `""` |
| `serviceMonitor.authSecret.key` | Key within `serviceMonitor.authSecret.name` that holds the token. Required when `authSecret.name` is set. | `""` |
#### Example `proxy_config` ConfigMap from values (default):

View file

@ -31,6 +31,18 @@ spec:
interval: {{ .interval }}
scrapeTimeout: {{ .scrapeTimeout }}
scheme: http
{{- if .authSecret.enabled }}
authorization:
type: Bearer
credentials:
{{- if .authSecret.name }}
name: {{ .authSecret.name }}
key: {{ required "serviceMonitor.authSecret.key is required when serviceMonitor.authSecret.name is set" .authSecret.key }}
{{- else }}
name: {{ $.Values.masterkeySecretName | default (printf "%s-masterkey" (include "litellm.fullname" $)) }}
key: {{ $.Values.masterkeySecretKey | default "masterkey" }}
{{- end }}
{{- end }}
{{- if .relabelings }}
relabelings:
{{- toYaml .relabelings | nindent 4 }}

View file

@ -0,0 +1,65 @@
suite: test service monitor
templates:
- servicemonitor.yaml
release:
name: my-release
tests:
- it: should not render a ServiceMonitor when disabled
set:
serviceMonitor.enabled: false
asserts:
- hasDocuments:
count: 0
- it: should authenticate scrapes with the generated masterkey secret by default
set:
serviceMonitor.enabled: true
asserts:
- isKind:
of: ServiceMonitor
- equal:
path: spec.endpoints[0].authorization.type
value: Bearer
- equal:
path: spec.endpoints[0].authorization.credentials.name
value: my-release-litellm-masterkey
- equal:
path: spec.endpoints[0].authorization.credentials.key
value: masterkey
- it: should authenticate scrapes with masterkeySecretName and masterkeySecretKey when set
set:
serviceMonitor.enabled: true
masterkeySecretName: my-masterkey-secret
masterkeySecretKey: my-key
asserts:
- equal:
path: spec.endpoints[0].authorization.credentials.name
value: my-masterkey-secret
- equal:
path: spec.endpoints[0].authorization.credentials.key
value: my-key
- it: should authenticate scrapes with a custom auth secret when set
set:
serviceMonitor.enabled: true
serviceMonitor.authSecret.name: metrics-token
serviceMonitor.authSecret.key: token
asserts:
- equal:
path: spec.endpoints[0].authorization.credentials.name
value: metrics-token
- equal:
path: spec.endpoints[0].authorization.credentials.key
value: token
- it: should fail when a custom auth secret name is set without a key
set:
serviceMonitor.enabled: true
serviceMonitor.authSecret.name: metrics-token
asserts:
- failedTemplate:
errorMessage: serviceMonitor.authSecret.key is required when serviceMonitor.authSecret.name is set
- it: should not send credentials when authSecret is disabled
set:
serviceMonitor.enabled: true
serviceMonitor.authSecret.enabled: false
asserts:
- notExists:
path: spec.endpoints[0].authorization

View file

@ -417,6 +417,10 @@ serviceMonitor:
# kubernetes.io/test: test
interval: 15s
scrapeTimeout: 10s
authSecret:
enabled: true
name: ""
key: ""
relabelings: []
# - targetLabel: __meta_kubernetes_pod_node_name
# replacement: $1