Prometheus exporters as HelmReleases: Kafka, MongoDB, Redis, RabbitMQ

Published: 2026-02-21

kube-prometheus-stack gives you node metrics, kubelet metrics, and Kubernetes API metrics out of the box. Application-level metrics — Kafka consumer lag, Redis memory hit ratio, MongoDB operation rates — need dedicated exporters. Here's how we deploy and wire them all via FluxCD with a consistent pattern.


Pattern

Each exporter follows the same HelmRelease pattern:

  1. Deploy to the same namespace as the workload (not observability)
  2. Enable serviceMonitor with release: kube-prom-stack label — this is how the Prometheus operator discovers the ServiceMonitor
  3. Set relabelings to fix the job label to a stable, human-readable value
  4. Set resource requests/limits — exporters are cheap, but unbounded they can consume significant memory during metric collection spikes

Why the same namespace as the workload? Exporters need network access to the service they scrape. Putting them in the same namespace means short hostnames work (redis-master.db.svc.cluster.local vs cross-namespace). It also co-locates observability concerns with the service they observe, making it easier to understand what's being monitored and by whom.


kafka-exporter

yamlapiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: kafka-exporter
  namespace: kafka
spec:
  chart:
    spec:
      chart: prometheus-kafka-exporter
      version: "3.0.1"
      sourceRef:
        kind: HelmRepository
        name: prometheus-community
        namespace: flux-system
  values:
    kafkaServer:
      - kafka.kafka.svc.cluster.local:9092
    prometheus:
      serviceMonitor:
        enabled: true
        additionalLabels:
          release: kube-prom-stack
        interval: 30s
        relabelings:
          - targetLabel: job
            replacement: kafka
    resources:
      requests:
        cpu: 25m
        memory: 64Mi
      limits:
        cpu: 200m
        memory: 128Mi

Exposes: consumer group lag (per partition, per group), topic partition counts, broker up/down, under-replicated partitions, message rates.

Key metrics for alerting:

  • kafka_consumergroup_lag_sum — total lag per consumer group
  • kafka_topic_partition_under_replicated_partition — replication health
  • kafka_brokers — number of visible brokers

For multi-broker clusters, add all brokers:

yamlkafkaServer:
  - kafka-0.kafka-headless.kafka.svc.cluster.local:9092
  - kafka-1.kafka-headless.kafka.svc.cluster.local:9092
  - kafka-2.kafka-headless.kafka.svc.cluster.local:9092

mongodb-exporter

yamlapiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: mongodb-exporter
  namespace: db
spec:
  chart:
    spec:
      chart: prometheus-mongodb-exporter
      version: "3.8.0"
      sourceRef:
        kind: HelmRepository
        name: prometheus-community
        namespace: flux-system
  values:
    mongodb:
      uri: "mongodb://exporter:${MONGO_EXPORTER_PASS}@mongodb.db.svc.cluster.local:27017/admin"
    serviceMonitor:
      enabled: true
      additionalLabels:
        release: kube-prom-stack
      interval: 30s
      relabelings:
        - targetLabel: job
          replacement: mongodb
    resources:
      requests:
        cpu: 25m
        memory: 64Mi
      limits:
        cpu: 200m
        memory: 128Mi

The mongodb.uri contains credentials — injected via ExternalSecret from Vault, never hardcoded in Git.

MongoDB exporter user

Create a dedicated MongoDB user with minimal permissions:

javascriptuse admin
db.createUser({
  user: "exporter",
  pwd: "secure-password",
  roles: [
    { role: "clusterMonitor", db: "admin" },
    { role: "read", db: "local" }
  ]
})

Exposes: document counts per collection, replication lag, index stats, operation rates by type (insert/update/delete/query), WiredTiger cache hit ratio, connection pool usage.

Key metrics for alerting:

  • mongodb_mongod_replset_member_replication_lag — replica lag
  • mongodb_mongod_wiredtiger_cache_bytes{type="currently in cache"} — cache pressure
  • mongodb_mongod_connections{state="current"} — connection count

redis-exporter

yamlapiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: redis-exporter
  namespace: db
spec:
  chart:
    spec:
      chart: prometheus-redis-exporter
      version: "6.9.0"
      sourceRef:
        kind: HelmRepository
        name: prometheus-community
        namespace: flux-system
  values:
    redisAddress: redis://redis-master.db.svc.cluster.local:6379
    auth:
      enabled: true
      secret:
        name: redis-password
        key: redis-password
    serviceMonitor:
      enabled: true
      labels:
        release: kube-prom-stack
      interval: 15s
      relabelings:
        - targetLabel: job
          replacement: redis
    resources:
      requests:
        cpu: 10m
        memory: 32Mi
      limits:
        cpu: 100m
        memory: 64Mi

interval: 15s — Redis metrics change fast (cache hit rates, command rates). More frequent scraping gives better signal for alerting on Redis latency issues.

Exposes: keyspace hits/misses, connected clients, memory used/max, evicted keys, command rates per operation type, replication offset (for replicas).

Key metrics for alerting:

  • redis_keyspace_hits_total / redis_keyspace_misses_total — cache hit ratio
  • redis_memory_used_bytes vs redis_memory_max_bytes — memory pressure
  • redis_evicted_keys_total — evictions (indicates memory pressure)
  • redis_connected_clients — connection pool saturation

Redis hit ratio recording rule

yaml- record: job:redis_hit_ratio:5m
  expr: |
    rate(redis_keyspace_hits_total[5m])
    /
    (rate(redis_keyspace_hits_total[5m]) + rate(redis_keyspace_misses_total[5m]))

Alert when hit ratio drops below 80%:

yaml- alert: RedisLowHitRatio
  expr: job:redis_hit_ratio:5m < 0.8
  for: 10m
  labels:
    severity: warning
    event: 'Redis Low Hit Ratio |{{$value | humanize}}'

rabbitmq-exporter

RabbitMQ ships with a built-in Prometheus endpoint — no separate exporter needed. Enable it in the RabbitMQ Helm chart values:

yamlvalues:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true
      labels:
        release: kube-prom-stack
      interval: 30s
      relabelings:
        - targetLabel: job
          replacement: rabbitmq

Exposes: queue depths, consumer counts, message rates (published/delivered/acked), channel stats, node memory/disk alarms, connection count.

Key metrics for alerting:

  • rabbitmq_queue_messages — messages in queue (consumer lag proxy)
  • rabbitmq_queue_consumers — active consumers (0 = no one consuming)
  • rabbitmq_node_mem_alarm — memory alarm flag (1 = alarm triggered)
  • rabbitmq_node_disk_free_alarm — disk alarm flag

helm-exporter

Track Helm release versions and status across clusters:

yamlapiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: helm-exporter
  namespace: observability
spec:
  chart:
    spec:
      chart: helm-exporter
      sourceRef:
        kind: HelmRepository
        name: sstarcher
  values:
    serviceMonitor:
      create: true
      labels:
        release: kube-prom-stack

Exposes one gauge per Helm release with chart, version, namespace, and status labels. Use it to build a Grafana panel showing all releases and their statuses at a glance, and to alert on releases stuck in failed or pending-upgrade state:

yaml- alert: HelmReleaseFailed
  expr: helm_chart_info{status!="deployed"} > 0
  for: 15m
  labels:
    severity: warning
    event: 'Helm Release Failed |{{$labels.chart}}|{{$labels.namespace}}'

ServiceMonitor discovery: how it works

The key mechanism: Prometheus operator watches for ServiceMonitor CRDs with labels matching the Prometheus CR's serviceMonitorSelector:

yaml# kube-prometheus-stack default Prometheus CR
serviceMonitorSelector:
  matchLabels:
    release: kube-prom-stack

If your ServiceMonitor doesn't have this label, Prometheus never scrapes the target. Check with:

bashkubectl get servicemonitor -A -l release=kube-prom-stack
# Should list your exporter's ServiceMonitor

And verify the targets are in Prometheus:

bashkubectl port-forward -n observability svc/kube-prom-stack-prometheus 9090:9090
# localhost:9090/targets — should show kafka, mongodb, redis, rabbitmq