When many VMs share a host, you need to see which one is eating CPU, disk or network. This guide shows how to monitor KVM hosts with Prometheus and Grafana: host metrics with node_exporter and per-VM metrics from libvirt.
Before you start
- One or more KVM hosts with libvirt.
- A monitoring server (a small VM is fine) with Docker or package-installed Prometheus and Grafana.
- Firewall rules so only the monitoring server can reach exporter ports.
- For a simpler single-host option, see Netdata.
Install node_exporter on each host
sudo apt install -y prometheus-node-exporterIt listens on port 9100 and exposes CPU, memory, disk, filesystem and network metrics for the host. On RHEL-family systems install the binary from the Prometheus releases and run it as a systemd service.
Add a libvirt exporter
Community libvirt exporters read per-domain statistics (vCPU time, memory, block and interface counters) from libvirt and expose them for Prometheus. Install one following its project instructions, run it as a service with read access to the libvirt socket, and note its port.
Quick check that libvirt provides the data:
virsh domstats --cpu-total --balloon --block --interfaceConfigure Prometheus
In prometheus.yml:
scrape_configs:
- job_name: kvm-nodes
static_configs:
- targets: ['10.10.0.11:9100', '10.10.0.12:9100']
- job_name: kvm-libvirt
static_configs:
- targets: ['10.10.0.11:9177', '10.10.0.12:9177']Use the libvirt exporter's actual port. Reload Prometheus and check Status → Targets shows them up.
Build Grafana dashboards
- Add Prometheus as a data source in Grafana.
- Import a community dashboard for node_exporter (host overview).
- Create panels for per-VM CPU (rate of CPU time), memory, disk read/write bytes and network throughput, grouped by domain name.
Useful alerts
- Host memory available below 10%.
- Host filesystem or storage pool above 85% (thin pools especially).
- High host CPU iowait or load sustained.
- A VM with unusual network egress (possible abuse or compromise).
- Exporter target down.
Route alerts with Alertmanager to email or chat.
Troubleshooting
- Target down: firewall or exporter not listening on the expected interface.
- libvirt exporter permission denied: add its user to the
libvirtgroup or adjust socket permissions. - Too many time series: drop unneeded labels or metrics with relabelling.
Frequently asked questions
Can VPS customers use this?
node_exporter works inside any VPS; per-VM libvirt metrics need host access.
Prometheus or Netdata?
Netdata is quick for single servers; Prometheus and Grafana scale better across fleets with long retention.
How long should I keep metrics?
Weeks to months locally; use remote storage for longer.
