diff --git a/helm/litellm-helm/Chart.yaml b/helm/litellm-helm/Chart.yaml index 3959d85edf3..a3cb388ffc6 100644 --- a/helm/litellm-helm/Chart.yaml +++ b/helm/litellm-helm/Chart.yaml @@ -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.2 +version: 1.1.3 # 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 diff --git a/helm/litellm-helm/README.md b/helm/litellm-helm/README.md index b242373de5d..003066a170f 100644 --- a/helm/litellm-helm/README.md +++ b/helm/litellm-helm/README.md @@ -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 | `false` | +| `serviceMonitor.authSecret.enabled` | Configure bearer authorization for metrics scraping from an existing Kubernetes Secret | `false` | +| `serviceMonitor.authSecret.name` | Name of the existing Secret containing a valid LiteLLM key | `""` | +| `serviceMonitor.authSecret.key` | Key within the existing Secret that contains the LiteLLM key | `""` | | `billingMetrics.enabled` | Enable enterprise billable-request metering. Requires an enterprise license. | `false` | | `billingMetrics.endpoint` | Collector that the billable-request counter is pushed to. | `https://telemetry.litellm.ai` | @@ -100,6 +104,21 @@ data: type: Opaque ``` +#### Authenticated Prometheus scraping + +LiteLLM requires authentication on `/metrics` by default. Store a valid LiteLLM key in a Kubernetes Secret in the ServiceMonitor namespace, then reference it from the chart: + +``` +serviceMonitor: + enabled: true + authSecret: + enabled: true + name: litellm-prometheus-key + key: token +``` + +Use a dedicated restricted key instead of the LiteLLM master key. The Prometheus Operator must be able to read the Secret. If unauthenticated metrics are acceptable for your deployment, leave `authSecret.enabled` set to `false` and set `litellm_settings.require_auth_for_metrics_endpoint: false` in `proxy_config` + #### Enterprise billable-request metering Enterprise licenses meter billable requests by pushing a counter to LiteLLM's collector over mutual TLS. The chart does not create the client certificate; it mounts one you already hold, read-only, so the private key is never exposed through the environment. Create the Secret under the name the chart expects, then turn the block on: diff --git a/helm/litellm-helm/templates/servicemonitor.yaml b/helm/litellm-helm/templates/servicemonitor.yaml index 743098deb3f..362a07e7e83 100644 --- a/helm/litellm-helm/templates/servicemonitor.yaml +++ b/helm/litellm-helm/templates/servicemonitor.yaml @@ -31,6 +31,12 @@ spec: interval: {{ .interval }} scrapeTimeout: {{ .scrapeTimeout }} scheme: http + {{- if .authSecret.enabled }} + authorization: + credentials: + name: {{ required "serviceMonitor.authSecret.name is required when serviceMonitor.authSecret.enabled is true" .authSecret.name | quote }} + key: {{ required "serviceMonitor.authSecret.key is required when serviceMonitor.authSecret.enabled is true" .authSecret.key | quote }} + {{- end }} {{- if .relabelings }} relabelings: {{- toYaml .relabelings | nindent 4 }} diff --git a/helm/litellm-helm/tests/servicemonitor_tests.yaml b/helm/litellm-helm/tests/servicemonitor_tests.yaml new file mode 100644 index 00000000000..0ddc47881e4 --- /dev/null +++ b/helm/litellm-helm/tests/servicemonitor_tests.yaml @@ -0,0 +1,51 @@ +suite: ServiceMonitor Configuration Tests +templates: + - servicemonitor.yaml +tests: + - it: should not create a ServiceMonitor by default + asserts: + - hasDocuments: + count: 0 + + - it: should create a ServiceMonitor without authorization when no secret is enabled + set: + serviceMonitor.enabled: true + asserts: + - isKind: + of: ServiceMonitor + - isNull: + path: spec.endpoints[0].authorization + + - it: should configure bearer authorization from an existing secret + set: + serviceMonitor.enabled: true + serviceMonitor.authSecret.enabled: true + serviceMonitor.authSecret.name: prometheus-litellm-key + serviceMonitor.authSecret.key: token + asserts: + - equal: + path: spec.endpoints[0].authorization + value: + credentials: + name: prometheus-litellm-key + key: token + - isNull: + path: spec.endpoints[0].bearerTokenSecret + + - it: should reject an enabled authorization secret without a name + set: + serviceMonitor.enabled: true + serviceMonitor.authSecret.enabled: true + serviceMonitor.authSecret.key: token + asserts: + - failedTemplate: + errorMessage: serviceMonitor.authSecret.name is required when serviceMonitor.authSecret.enabled is true + + - it: should reject an enabled authorization secret without a key + set: + serviceMonitor.enabled: true + serviceMonitor.authSecret.enabled: true + serviceMonitor.authSecret.name: prometheus-litellm-key + asserts: + - failedTemplate: + errorMessage: serviceMonitor.authSecret.key is required when serviceMonitor.authSecret.enabled is true diff --git a/helm/litellm-helm/values.yaml b/helm/litellm-helm/values.yaml index f8df98de102..e687981d00d 100644 --- a/helm/litellm-helm/values.yaml +++ b/helm/litellm-helm/values.yaml @@ -517,6 +517,10 @@ serviceMonitor: # kubernetes.io/test: test interval: 15s scrapeTimeout: 10s + authSecret: + enabled: false + name: "" + key: "" relabelings: [] # - targetLabel: __meta_kubernetes_pod_node_name # replacement: $1