Dosu LogoDosu Logo
Ask
Join our Discord
kyvernoPublic
Nirmata
Documentskyverno
Prometheus Metrics Integration
Prometheus Metrics Integration
Type
Topic
Status
Published
Created
Aug 10, 2026
Updated
Aug 10, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Prometheus Metrics Integration#

Kyverno's metrics subsystem is built on OpenTelemetry and exposes metrics via two backends: Prometheus (pull-based, default for most deployments) and OTLP/gRPC (push-based, for OpenTelemetry collectors). The entry point for the entire subsystem is InitMetrics in pkg/metrics/init.go.

Architecture Overview#

The subsystem has three main layers:

  1. Configuration — MetricsConfiguration (pkg/config/metricsconfig.go) holds namespace filters, histogram bucket boundaries, per-metric exposure config, and the metricsRefreshInterval. It is loaded from a Kubernetes ConfigMap and guards all fields with a sync.RWMutex .

  2. MeterProvider — An OTel sdkmetric.MeterProvider is created by either NewPrometheusConfig or NewOTLPGRPCConfig. Both functions apply the same aggregationSelector (customizing histogram bucket boundaries) and exemplarFilter, and attach an OTel resource identifying the service — kyverno-svc-metrics for Prometheus, kyverno (the MeterName constant) for gRPC .

  3. MetricsConfigManager — The MetricsConfigManager interface (implemented by MetricsConfig) is a process-wide singleton set via SetManager. It owns instrument handles for all metric categories: policy changes, client queries, kyverno info, admission, policy engine, controllers, circuit breakers, events, HTTP, cleanup, TTL, and policy-type-specific metrics . Instruments are (re-)registered by calling initializeMetrics.

Initialization Flow#

InitMetrics (pkg/metrics/init.go) orchestrates startup:

  1. Creates a MetricsConfig via NewMetricsConfigManager and registers it as the global manager with SetManager .
  2. If disableMetricsExport is set, falls back to the default no-op OTel MeterProvider and returns early .
  3. Selects a backend based on otelProvider:
    • "grpc" → NewOTLPGRPCConfig: creates an OTLP exporter with a 2-second periodic reader; optionally fetches TLS credentials from a Kubernetes ConfigMap .
    • "prometheus" → NewPrometheusConfig: creates a Prometheus pull exporter; also registers promhttp.Handler() on config.MetricsPath .
  4. Sets the new provider globally via otel.SetMeterProvider and calls initializeMetrics to bind all instruments .

Periodic MeterProvider Re-creation (Prometheus Only)#

When the provider is "prometheus" and metricsRefreshInterval > 0, InitMetrics starts a background goroutine that periodically tears down and rebuilds the entire MeterProvider :

ticker fires
  → shutdown existing sdkmetric.MeterProvider
  → call NewPrometheusConfig (creates a fresh exporter + provider)
  → otel.SetMeterProvider(new provider)
  → initializeMetrics(new provider) ← re-registers all instruments

The goroutine exits cleanly when the passed context.Context is cancelled . Errors at any step are logged and the iteration is skipped (continue), leaving the previous provider in place until the next tick .

Why re-create? The Prometheus exporter accumulates in-memory metric state. Periodic recreation resets that state — useful for long-running deployments where stale label cardinality or accumulated histogram data can bloat memory.

Configuring the interval: Set metricsRefreshInterval in the kyverno-metrics ConfigMap. The value is a Go time.Duration string (e.g., "1h"). When absent or zero, the refresh goroutine is never started .

MetricsConfiguration Reference#

All configuration lives in pkg/config/metricsconfig.go . Key ConfigMap keys:

ConfigMap keyTypeDefaultPurpose
metricsRefreshIntervaltime.Duration0 (disabled)Interval for Prometheus MeterProvider recreation
namespacesJSONinclude allNamespace allow/deny list for metric exposure
bucketBoundariesJSON array15 buckets (0.005–30s)Histogram bucket boundaries
metricsExposureJSON mapall enabledPer-metric enable/disable and label filtering

The configuration supports hot-reload via Load(*corev1.ConfigMap); a notify() callback chain is invoked on each reload . BuildMeterProviderViews translates the metricsExposure map into OTel sdkmetric.View objects applied when a MeterProvider is constructed.

Key Source Files#

FilePurpose
pkg/metrics/init.goInitMetrics — subsystem entry point, provider selection, refresh goroutine
pkg/metrics/metrics.goMetricsConfig, MetricsConfigManager, NewPrometheusConfig, NewOTLPGRPCConfig, initializeMetrics, ShutDownController
pkg/config/metricsconfig.goMetricsConfiguration interface and metricsConfig implementation — ConfigMap parsing, refresh interval, bucket boundaries, views
Documents
Background Controller Trigger Validation
Background Controller UpdateRequest Processing
Background Mutation Engine
Background Scan Report Reconciliation
CEL Context Injection
CEL Policy Exception Handling
CLI Policy Result Processing
CLI Policy Testing
CLI Resource Resolution
CLI Worker Pool Management
Concurrency Safety
Engine Context Propagation
Generate Policy UpdateRequest Lifecycle
GeneratingPolicy Downstream Cleanup
GeneratingPolicy Synchronization and Reconciliation
Image Verification CEL Path
ImageValidatingPolicy Webhook Architecture
JMESPath Type Safety
JSON Patch Mutation
MutatingPolicy Resource Targeting
NamespaceSelector Policy Enforcement
OCI Referrers API Fallback
Policy Controller Reconciliation
Projected Service Account Token
Prometheus Metrics Integration
Report Controller Goroutine Lifecycle
Sigstore & TUF Integration
TTL Controller Lifecycle
ValidatingPolicy Autogen
ValidatingPolicy Engine
ValidatingPolicy Status Management
Webhook Generation
Webhook Lifecycle Management
Webhook Selector Grouping