Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

Monitoring & Observability

Deploying Prometheus with the Operator and Helm on Kubernetes

We deploy Prometheus either as a standalone server or, on Kubernetes, through the Prometheus Operator installed with Helm. The operator manages Prometheus and Alertmanager as custom resources, so scrape targets and rules become reviewable YAML in Git rather than hand-edited config files.

Key takeaways

  • On Kubernetes, the operator turns scrape config and alert rules into declarative custom resources.
  • Storage, retention and cardinality are sized up front, because they decide cost and stability.
  • Everything is installed from version-controlled Helm values, so rebuilding a cluster rebuilds monitoring.
  • Plain Prometheus on a VM is still the right answer for small, non-Kubernetes estates.
  • We plan for upgrades, high availability and remote storage before the first dashboard is built.

Why the deployment model matters

Most Prometheus problems we are called in to fix are not exotic. A server running on an undersized node that restarts every few days. A configuration file edited by hand on one pod and lost at the next reschedule. A disk that filled at 3am because someone added a label with a user ID in it. The software is solid, but the way it is installed decides whether you can trust it during an incident.

Prometheus is the metrics engine of the monitoring and observability service we deliver, so it gets built first and built carefully. Everything else, including dashboards, alerts and SLOs, reads from it. For background on the project itself, see our Prometheus glossary entry.

What a good deployment looks like

We hold every Prometheus install to the same criteria:

  • Declarative. Install and configuration live in Git and are applied by Helm, Argo CD or Terraform. No one edits a running pod.
  • Sized from evidence. Memory, disk and retention come from a measured estimate of active series, not a copied example.
  • Resilient enough for the job. Persistent storage, resource requests and limits, and a known behaviour on restart.
  • Observable itself. Prometheus alerts when its own scrapes fail, rules error or the disk is nearly full.
  • Upgradable. Chart and CRD upgrades are rehearsed, because CRDs are not upgraded by Helm in the same way as other resources.

Operator or plain Prometheus

SituationOur recommendation
Kubernetes cluster, several teams adding servicesPrometheus Operator via kube-prometheus-stack
Kubernetes, tiny footprint, one teamOperator still, with a trimmed values file
A handful of VMs, no clusterPlain Prometheus under systemd or Docker, managed with Ansible
Mixed estateOperator in the cluster, plus a scrape job or agent for the VMs

The operator earns its place on Kubernetes because scrape configuration follows the workloads. A team ships a Deployment, a Service and a ServiceMonitor in the same chart, and monitoring appears with the service. Without that, someone has to remember to update a central config file, and eventually nobody does. For the Kubernetes-specific exporters and dashboards that sit on top, see our Kubernetes monitoring page.

How it works in practice

Installing from a values file

The common route is the community kube-prometheus-stack chart. We keep a values file per environment in your repository and install with pinned chart versions:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
  --namespace monitoring --create-namespace \
  --version <pinned-chart-version> \
  -f values/production.yaml

A trimmed production values file usually covers storage, retention, resources and selector behaviour:

prometheus:
  prometheusSpec:
    retention: 15d
    replicas: 2
    resources:
      requests: { cpu: "500m", memory: "2Gi" }
      limits: { memory: "4Gi" }
    serviceMonitorSelectorNilUsesHelmValues: false
    podMonitorSelectorNilUsesHelmValues: false
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: gp3
          resources:
            requests:
              storage: 100Gi

The values above are an illustration of structure, not a recommendation for your cluster. The setting serviceMonitorSelectorNilUsesHelmValues: false matters more than it looks: by default the operator only picks up ServiceMonitors that carry the Helm release label, so teams add monitors and wonder why nothing is scraped.

Declaring what to scrape

Application teams describe their metrics endpoint with a ServiceMonitor that sits beside the Service:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: checkout
  namespace: production
spec:
  selector:
    matchLabels:
      app: checkout
  endpoints:
    - port: metrics
      interval: 30s
      path: /metrics

Alert and recording rules follow the same pattern as PrometheusRule resources, which we cover in the Alertmanager routing page and the alerting rules guide.

Decisions and trade-offs

Retention versus remote storage. Local retention of a couple of weeks is cheap and fast. Keeping a year of data on one server is a poor idea. If you need long-range trends, we add Thanos or Mimir rather than growing a single disk.

One Prometheus or several. A single instance is simpler to reason about. Splitting by team or environment limits blast radius and cardinality accidents, at the cost of more things to operate. We usually start with one per cluster and split when evidence says so.

Prometheus in agent mode. For edge clusters or when metrics ship to a central store, agent mode forwards samples without local querying. It is useful, but you lose local alert evaluation, so we only use it with a clear reason.

When not to self-host. If you have no one to look after it and your metric volume is small, a managed offering can be cheaper than the engineering time. We will say so. Self-hosting wins on cost at scale and on control, but it is a system you own.

Failure modes we design out

  • Cardinality explosions. Labels with unbounded values multiply series. We review labels during onboarding and use sample_limit on scrape configs as a guard.
  • Out-of-memory restarts. Memory limits set below real usage cause a restart loop and a gap in data. We size from measured series.
  • Orphaned monitors. A renamed Service leaves a ServiceMonitor scraping nothing. A rule alerting on up == 0 for expected jobs catches it.
  • CRD drift. Chart upgrades that skip CRD updates break the operator. We apply CRDs deliberately and test the upgrade in a non-production cluster first.
  • No alert on Prometheus itself. If the monitor dies silently, nothing tells you. We add a dead-man’s-switch alert that must always fire, routed to an external check.

Delivery and handover

You receive the Helm values, the Git repository layout, ServiceMonitor templates for your common service types, and a short operations guide covering upgrades, scaling and restoring from a volume snapshot. If your team uses GitOps, we wire the chart into Argo CD or Flux so changes arrive through pull requests. We stay available for the first weeks of production traffic, because that is when the real series count and retention needs show up.

How to tell it is working

Look at scrape success rate across targets, rule evaluation duration against interval, the head series count trend, disk usage against the volume, and the time it takes a new service to appear in Prometheus after deploy. If a team can add a new application and see its metrics in the same day without asking us, the deployment is doing its job. To scope a deployment for your cluster, book a consultation.

References

How we deliver it

  1. 01

    Scope and sizing

    We count workloads, estimate active series and scrape intervals, and choose retention, disk and memory so the server is not guessed at.

  2. 02

    Choose the deployment model

    Operator with Helm for Kubernetes, or a plain binary or container on VMs for estates without a cluster.

  3. 03

    Install from values files

    kube-prometheus-stack or the operator chart is installed from Helm values committed to your repository.

  4. 04

    Add scrape targets

    ServiceMonitor and PodMonitor resources are written for your applications, with consistent labels.

  5. 05

    Harden and make resilient

    Persistent volumes, pod resources, replicas, network policy and an upgrade path are configured and tested.

  6. 06

    Verify and hand over

    We check targets, rules and storage health, then document day-two operations for your team.

Tools and technologies

PrometheusPrometheus Operatorkube-prometheus-stackHelmAlertmanagerkube-state-metricsnode-exporterServiceMonitorArgo CDTerraform

Frequently asked questions

What is the Prometheus Operator?
The Prometheus Operator is a Kubernetes controller that runs Prometheus and Alertmanager for you and exposes their configuration as custom resources such as Prometheus, ServiceMonitor, PodMonitor and PrometheusRule. You declare what to scrape and alert on in YAML, and the operator generates and reloads the actual Prometheus configuration.
Should I use kube-prometheus-stack or install Prometheus myself?
For most Kubernetes teams, kube-prometheus-stack is the sensible start because it bundles the operator, Prometheus, Alertmanager, Grafana, exporters and default rules. Hand-rolling is only worth it when you need a very small footprint or already have strong conventions. We trim the defaults you do not need.
How much storage does Prometheus need?
It depends on active series, scrape interval and retention, so there is no honest universal number. We estimate from your workload count and exporters, measure after a week of real traffic, then set retention and volume size with headroom. High-cardinality labels are the usual cause of surprises.
Is a single Prometheus enough for production?
A single replica is fine for many teams if you accept gaps during restarts and reschedules. For tighter needs we run two replicas with the same config, and add Thanos or Mimir when you want a single query view and longer retention. We explain the trade-off before choosing.
Can you deploy Prometheus without Kubernetes?
Yes. On virtual machines we run Prometheus under systemd or in a container, with file-based or cloud service discovery, node_exporter on each host and configuration managed by Ansible or Terraform. The operator pattern only makes sense when you have a cluster to host it.

Talk to an engineer about prometheus operator helm deployment

Book a free 30-minute call. We review your current setup and tell you honestly whether and how we can help.

Written by Saddique Khan, DevOps / SRE / Cloud Consultant Engineer. Last updated 2026-10-08.