Monitoring CloudNativePG Clusters with the PLG Stack
Monitoring your CloudNativePG (CNPG) clusters is essential. Without proper visibility, small issues can quickly escalate into major outages or performance bottlenecks that affect your entire application.
Fortunately, CNPG makes monitoring straightforward. While many monitoring solutions exist, this post focuses on the popular PLG stack—Prometheus, Loki, and Grafana—which integrates seamlessly with Kubernetes.
What Is the PLG Stack?
- Prometheus: An open-source time-series database and monitoring system. It collects and stores metrics from your applications and infrastructure. Unlike traditional threshold-based tools, Prometheus gathers data points over time, enabling powerful querying and alerting.
- Loki: A lightweight, horizontally scalable log aggregation system inspired by Prometheus. It indexes metadata labels rather than the full content of logs, making it cost-effective and easy to operate.
- Grafana: A powerful open-source visualization platform. It connects to various data sources (including Prometheus and Loki) to create rich dashboards, charts, and alerts. Grafana itself does not store monitoring data—it simply displays it.
Together, these tools provide a complete observability solution: metrics, logs, and beautiful visualizations.
The Tech Stack in This Environment
In this setup, a dedicated Prometheus instance runs inside Kubernetes alongside Thanos for long-term storage and MinIO as a cost-effective object store. This approach also collects metrics from the underlying Linux nodes, not just Kubernetes resources.
Grafana runs as a single instance integrated with Keycloak for authentication. Loki operates quietly in the background, feeding logs into Grafana.
How CNPG Monitoring Works
The great news is that no changes are required inside CNPG itself. Every CNPG pod automatically exposes metrics on port 9187. If you are using poolers, they expose metrics on port 9127.
Prometheus discovers and scrapes these metrics using Kubernetes service discovery.
Here is the recommended scrape configuration for Prometheus:
- job_name: 'cnpg-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
# Keep only CNPG PostgreSQL pods
- source_labels: [__meta_kubernetes_pod_label_cnpg_io_cluster]
action: keep
regex: .+
# Keep only the metrics port
- source_labels: [__meta_kubernetes_pod_container_port_name]
action: keep
regex: ^metrics$
# Add useful labels
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- source_labels: [__meta_kubernetes_pod_label_cnpg_io_cluster]
target_label: cluster
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
# Clean up instance label
- source_labels: [__address__]
target_label: instance
regex: '(.+):\d+'
replacement: '$1'
- job_name: 'cnpg-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
# Keep only CNPG PostgreSQL pods
- source_labels: [__meta_kubernetes_pod_label_cnpg_io_cluster]
action: keep
regex: .+
# Keep only the metrics port
- source_labels: [__meta_kubernetes_pod_container_port_name]
action: keep
regex: ^metrics$
# Add useful labels
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- source_labels: [__meta_kubernetes_pod_label_cnpg_io_cluster]
target_label: cluster
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
# Clean up instance label
- source_labels: [__address__]
target_label: instance
regex: '(.+):\d+'
replacement: '$1'
Required Permissions (RBAC)
For Prometheus to discover CNPG pods, it needs the right permissions. Create the following resources:
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus-svc-acc
namespace: prometheus
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus-cnpg-discovery
rules:
- apiGroups: [""]
resources:
- nodes
- nodes/metrics
- services
- endpoints
- pods
verbs: ["get", "list", "watch"]
- apiGroups: ["extensions", "networking.k8s.io"]
resources:
- ingresses
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus-cnpg-discovery
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus-cnpg-discovery
subjects:
- kind: ServiceAccount
name: prometheus-svc-acc
namespace: prometheus
Once these are applied, Prometheus should show your CNPG pods as healthy targets.
Visualizing Data in Grafana
Connect Grafana to your Prometheus instance as a data source. You can then import the official CloudNativePG dashboard using ID 20417.
How the PLG Stack Works Together

Flow Summary:
- CNPG pods expose metrics and logs.
- Prometheus scrapes metrics.
- Loki collects and stores logs.
- Grafana queries both systems and presents everything in user-friendly dashboards.
This setup gives you comprehensive visibility into your database clusters with minimal ongoing maintenance.
In the next post, we will explore backups and archiving strategies for CloudNativePG. Stay tuned!
Did you find this post helpful? You can support me.
Related posts
- Databases – Postgresql – Pilot
- Databases – Postgresql – Gitea and PGBouncer
- Databases – Postgresql – PGbouncer
- CNPG – Cloud Native Postgresql – Pilot
- CNPG – considerations for migrating databases
- CNPG – installation
- CNPG – Installation – Roles and Databases
- CNPG – Installation – Database Import
- CNPG – Installation – Connection pooling
Author Profile
Latest entries
blog02.07.2026CNPG – Installation – Monitoring
blog01.07.2026CNPG – Installation – Connection pooling
blog27.06.2026CNPG – Installation – Database Import
blog27.06.2026CNPG – Installation – Roles and Databases



