In this guide you will learn how to set up Prometheus for monitoring on a Kubernetes cluster. The setup uses Kubernetes service discovery so Prometheus automatically finds and scrapes nodes, pods, and services. You will create a namespace, RBAC, a ConfigMap with scrape configs and alert rules, a Deployment, and a Service (or Ingress) to access the Prometheus UI.
By the end you will have Prometheus running in the cluster and scraping Kubernetes API servers, nodes (kubelet/cAdvisor), and optionally pods and services that expose a /metrics endpoint. For a production-ready stack with authentication, persistence, and high availability, see the Production-Ready Prometheus on Kubernetes guide.
About Prometheus
Prometheus is an open source systems monitoring and alerting toolkit. It was originally built at SoundCloud and is now a standalone project. Prometheus stores metrics as time series data: each sample has a timestamp and optional labels (e.g. job, instance), so you can query and graph metrics over time.
- Pull model: Prometheus scrapes metrics over HTTP from targets you configure. For short-lived jobs (e.g. Kubernetes Jobs/CronJobs), you can use Pushgateway to push metrics.
- Metrics endpoint: Targets expose metrics on a
/metricsendpoint in Prometheus text format. Prometheus scrapes at a configurable interval (e.g. 15s). - PromQL: Prometheus provides PromQL for querying and aggregating metrics. The Prometheus UI and Grafana use PromQL for dashboards.
- Exporters: Exporters convert third-party metrics into Prometheus format (e.g. Node Exporter for host metrics).
- TSDB: Prometheus stores data in a local time-series database. For long-term or highly available storage, you can integrate remote write.
For running Prometheus locally, see How to Run Prometheus with Docker and Docker Compose. For a Linux server install, see How to Install and Configure Prometheus on a Linux Server. Prometheus is often used with Alertmanager for alerting and Grafana for dashboards.
Prerequisites
- A Kubernetes cluster (1.20+) with
kubectlconfigured on your workstation. - Optional: Node Exporter and kube-state-metrics deployed if you want node and API-object metrics (the scrape configs in this guide expect them; see the optional sections below).
If you need to create a cluster, see for example:
- Set up Kubernetes Cluster on Ubuntu 20.04 with kubeadm
- Set up Kubernetes Cluster on Debian 11 with kubeadm and CRI-O
- Set up Kubernetes Cluster with K3s in Rocky Linux 8
- Setup Kubernetes Cluster on Rocky Linux 9 using kubeadm
Prometheus is available as a Docker image; we use that image in the Deployment below.
Create a Namespace
Create a dedicated namespace for monitoring resources:
namespace.yaml:
| |
| |
Create RBAC (ClusterRole and ClusterRoleBinding)
Prometheus needs read access to the Kubernetes API to discover and scrape nodes, pods, and services. Create a ClusterRole with get, list, and watch on the required resources and a ClusterRoleBinding that grants it to the default ServiceAccount in the prometheus namespace.
The role below includes nodes, nodes/proxy, services, endpoints, pods, and ingresses (both legacy extensions and networking.k8s.io). Add other resources if you need them.
clusterRole.yaml:
| |
| |
Create ConfigMap (Prometheus Config and Rules)
Store the Prometheus configuration and alert rules in a ConfigMap. The container will mount it at /etc/prometheus. When you change the config, update the ConfigMap and restart the Prometheus pods.
The example config includes:
- alerting: Optional Alertmanager (same namespace). If you do not deploy Alertmanager, Prometheus will log connection errors but still run. Use
alertmanager.prometheus.svc:9093when Alertmanager is in theprometheusnamespace. - rule_files: Path to the rules file inside the container.
- scrape_configs: Jobs for node-exporter, Kubernetes API servers, nodes, pods, cAdvisor, service endpoints, and kube-state-metrics. Some jobs require Node Exporter and kube-state-metrics to be deployed; otherwise those targets will be down until you add them.
config-map.yaml:
| |
| |
Scrape jobs in this config:
| Job | Description |
|---|---|
node-exporter | Endpoints named node-exporter (deploy Node Exporter DaemonSet for host). |
kubernetes-apiservers | API server metrics. |
kubernetes-nodes | Kubelet metrics per node. |
kubernetes-pods | Pods with annotation prometheus.io/scrape=true (and optional port/path). |
kube-state-metrics | kube-state-metrics in kube-system (deploy for deployment/pod/job). |
kubernetes-cadvisor | Container metrics (CPU, memory) per node. |
kubernetes-service-endpoints | Services with annotation prometheus.io/scrape=true. |
Create the Prometheus Deployment
The Deployment uses the official Prometheus image, mounts the ConfigMap at /etc/prometheus, and stores TSDB data in an emptyDir volume. For production, use a PersistentVolumeClaim so data survives pod restarts; see the Production-Ready Prometheus guide.
deployment.yaml:
| |
| |
Check that the pod is running:
| |
Accessing the Prometheus UI
You can access the Prometheus UI in three ways: port-forward (quick test), NodePort/LoadBalancer Service, or Ingress.
Option 1: Port-forward (quick test)
From your workstation:
| |
Open http://localhost:8080 in your browser. Replace the pod name with deployment/prometheus so the forward works even after the pod is recreated.
Option 2: NodePort or LoadBalancer Service
Create a Service so Prometheus is reachable on a node IP (NodePort) or via a cloud load balancer (LoadBalancer).
service.yaml:
| |
| |
Access Prometheus at http://<node-ip>:30000. On AWS, Azure, or GCP you can use type: LoadBalancer so the cloud provider creates a load balancer; then use the assigned external IP/hostname.
The Service annotations (prometheus.io/scrape, prometheus.io/port) allow the kubernetes-service-endpoints job to scrape this service if you want Prometheus to scrape itself via the Service.
Option 3: Ingress
If you have an Ingress controller (e.g. NGINX, Traefik), create an Ingress to expose Prometheus with a hostname and optional TLS:
| |
Replace prometheus.example.com and ingressClassName with your values. For TLS, add a tls section and use cert-manager or your ingress controller’s TLS configuration. See Kubernetes TLS Security Hardening for TLS and security options.
Verifying the Setup
- Open the Prometheus UI (port-forward, NodePort, or Ingress).
- Go to Status → Targets. You should see targets for
kubernetes-apiservers,kubernetes-nodes,kubernetes-cadvisor, andkubernetes-service-endpoints. Some may be DOWN until you deploy Node Exporter and kube-state-metrics (see below). - Go to Graph, enter
upand run the query. You should see series withjoblabels for each scrape job.
Optional: Node Exporter
Node Exporter exposes host metrics (CPU, memory, disk, network) from each node. Deploy it as a DaemonSet so it runs on every node; the node-exporter scrape job in the ConfigMap discovers endpoints named node-exporter. For a step-by-step, see How to Set up Prometheus Node Exporter in Kubernetes. After deployment, the node-exporter targets in Status → Targets should turn UP.
Optional: Kube State Metrics
kube-state-metrics exposes metrics about Kubernetes API objects (deployments, pods, jobs, CronJobs, etc.). The ConfigMap already has a job that scrapes kube-state-metrics.kube-system.svc.cluster.local:8080. Deploy kube-state-metrics in the kube-system namespace (or adjust the target in the ConfigMap), then the kube-state-metrics job will show UP.
Optional: Alertmanager
Alertmanager receives alerts from Prometheus and routes them to Slack, email, PagerDuty, etc. The ConfigMap points to alertmanager.prometheus.svc:9093. If you do not deploy Alertmanager, Prometheus will log connection errors but continue running. Deploy Alertmanager in the prometheus namespace and ensure a Service named alertmanager listens on port 9093. For configuring Alertmanager on Linux, see How to Install and Configure Prometheus Alertmanager in Linux.
Optional: Grafana
Grafana can use Prometheus as a data source to build dashboards. Add Prometheus’s URL (e.g. http://prometheus.prometheus.svc:9090 from inside the cluster, or your NodePort/LoadBalancer/Ingress URL from outside). Import community dashboards for Kubernetes (e.g. from Grafana.com).
Production Considerations
This setup uses an emptyDir volume for Prometheus data, so metrics are lost when the pod is recreated. For production:
- Use a PersistentVolumeClaim for
/prometheusand consider retention and disk size. - Restrict access to the Prometheus UI (e.g. Ingress with auth, network policies). See Production-Ready Prometheus on Kubernetes for authentication and TLS.
- Consider Prometheus Operator or kube-prometheus-stack (Helm) to manage Prometheus, Alertmanager, and Grafana.
- For long-term or highly available storage, consider Thanos or remote write to a compatible backend.
Troubleshooting
- Targets DOWN: Check that the corresponding component is deployed (Node Exporter, kube-state-metrics) and that the Service names and namespaces match the scrape config. For API/node/cAdvisor jobs, ensure RBAC is applied and the ServiceAccount has the ClusterRoleBinding.
- Prometheus pod CrashLoopBackOff: Check logs with
kubectl logs -n prometheus deployment/prometheus. Often the cause is invalid YAML in the ConfigMap (e.g. indentation or invalid relabel regex). Validateprometheus.ymllocally withpromtool check config. - No data in Graph: Ensure at least one scrape job has UP targets and wait for the scrape interval (e.g. 15s). Check Status → Configuration to confirm the loaded config.
Summary
You have set up Prometheus on Kubernetes with:
- A namespace, RBAC (ClusterRole/ClusterRoleBinding), and a ConfigMap with scrape configs and alert rules.
- A Deployment that mounts the ConfigMap and uses an emptyDir for storage (replace with PVC for production).
- Access to the UI via port-forward, NodePort/LoadBalancer Service, or Ingress.
Scrape jobs discover Kubernetes API servers, nodes, pods, services, cAdvisor, and (if deployed) Node Exporter and kube-state-metrics. For a production-grade stack with persistence, authentication, and alerting, see the Production-Ready Prometheus on Kubernetes guide.
Related Posts
- Production-Ready Prometheus on Kubernetes – Auth, HA, persistence, alerting
- How to Run Prometheus with Docker and Docker Compose – Prometheus in Docker
- How to Install and Configure Prometheus on a Linux Server – Host-based install
- How to Set up Prometheus Node Exporter in Kubernetes – Node Exporter DaemonSet
- How to Install and Configure Prometheus Alertmanager in Linux – Alertmanager setup
- Monitor Linux Server With Prometheus and Grafana – Prometheus + Grafana on a host