New to KubeDB? Please start here.
Ignite Alerting with Prometheus
This tutorial shows you how to configure Prometheus-based alerting for a KubeDB-managed Ignite instance using the ignite-alerts Helm chart. This chart also bundles a Grafana dashboard that it imports automatically through a post-install Job — no separate dashboard chart is required.
Before You Begin
Ensure you have a Kubernetes cluster and that
kubectlis configured to communicate with it. If you do not already have a cluster, you can create one using kind.Install the KubeDB operator by following the steps here.
Deploy the database in the
alert-ignitenamespace:$ kubectl create ns alert-ignite namespace/alert-ignite createdTo learn more about how Prometheus monitoring works with KubeDB, see the overview here.
You will also need a Grafana API key / token with Editor permission so the chart’s dashboard-import Job can push the dashboard. See Step 1 below.
Note: YAML files used in this tutorial are stored in docs/examples/ignite folder in GitHub repository kubedb/docs.
Configuration
Step 1 (
kube-prometheus-stack) is required to follow this tutorial. Step 2 (Panopticon) is required for the Provisioner Group alerts below (KubeDBIgnitePhase...) — skip it only if you just want the exporter-based Database Group alerts. If you have already completed the step(s) you need in another guide, skip ahead.
Step 1: Deploy kube-prometheus-stack
kube-prometheus-stack installs Prometheus, Prometheus Operator, Alertmanager, and Grafana together. This is the recommended way to get the full monitoring stack on Kubernetes.
Add the prometheus-community Helm repo and install:
$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm repo update
$ helm upgrade --install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring --create-namespace \
--set grafana.image.tag=7.5.5
Wait for all pods to be ready:
$ kubectl get pods -n monitoring
NAME READY STATUS RESTARTS AGE
alertmanager-prometheus-kube-prometheus-alertmanager-0 2/2 Running 0 2m
prometheus-grafana-xxxx 3/3 Running 0 2m
prometheus-kube-prometheus-operator-xxxx 1/1 Running 0 2m
prometheus-kube-prometheus-prometheus-0 2/2 Running 0 2m
prometheus-kube-state-metrics-xxxx 1/1 Running 0 2m
Find the serviceMonitorSelector/ruleSelector labels that Prometheus uses to pick up ServiceMonitor/PrometheusRule objects — this is the release: prometheus label used throughout this tutorial.
$ kubectl get prometheus -n monitoring -o jsonpath='{.items[0].spec.ruleSelector}'
{"matchLabels":{"release":"prometheus"}}
$ kubectl get prometheus -n monitoring -o jsonpath='{.items[0].spec.serviceMonitorSelector}'
{"matchLabels":{"release":"prometheus"}}
Step 2: Install Panopticon (required for the Provisioner Group alerts)
Panopticon is the Appscode operator that exports the KubeDB operator’s own view of every resource — kubedb_com_ignite_status_phase and related metrics. It’s what powers the Provisioner Group alerts below (KubeDBIgnitePhaseNotReady/KubeDBIgnitePhaseCritical). Skip this step if you only need the exporter-based Database Group alerts.
$ helm repo add appscode https://charts.appscode.com/stable/
$ helm repo update
$ helm upgrade --install panopticon appscode/panopticon \
--version v2026.4.30 \
--namespace kubeops --create-namespace \
--set monitoring.enabled=true \
--set monitoring.agent=prometheus.io/operator \
--set monitoring.serviceMonitor.labels.release=prometheus \
--set-file license=/path/to/kubedb-license.txt \
--wait --timeout 5m0s
Verify Panopticon is running:
$ kubectl get pods -n kubeops
NAME READY STATUS RESTARTS AGE
panopticon-xxxx 1/1 Running 0 1m
Overview
- KubeDB deploys Ignite with a metrics-exporter sidecar (container
exporter) that exposes Ignite’s own JMX-derived metrics (sys_*,io_*,cluster_*,ignite_*). - ServiceMonitor (named
{ignite-name}-stats) is created automatically by KubeDB and tells Prometheus to scrape the exporter every 10 seconds. - PrometheusRule is created by the
ignite-alertschart and contains alert definitions grouped by concern: database health (which also embeds KubeDB-operator-sourcedIgniteDown/IgnitePhaseCriticalalerts) and provisioner. - Dashboard-import Job — when
grafana.enabledistrue, the chart also creates a one-shotJobthatPOSTs a bundled dashboard JSON straight to your Grafana instance’s/api/dashboards/importendpoint. - Prometheus Operator evaluates every rule expression every 30 seconds and fires matching alerts to AlertManager.
- AlertManager groups, inhibits, and silences alerts, then routes them to configured receivers (Slack, email, PagerDuty, webhook, etc.).
Deploy Ignite with Monitoring Enabled
At first, let’s deploy an Ignite instance with monitoring enabled. Below is the Ignite object we are going to create.
apiVersion: kubedb.com/v1alpha2
kind: Ignite
metadata:
name: ignite-alert-demo
namespace: alert-ignite
spec:
replicas: 1
version: "2.17.0"
storage:
storageClassName: "local-path"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
deletionPolicy: WipeOut
monitor:
agent: prometheus.io/operator
prometheus:
serviceMonitor:
labels:
release: prometheus
interval: 10s
Here,
spec.replicas: 1deploys a single-node Ignite instance.spec.monitor.agent: prometheus.io/operatortells KubeDB to create aServiceMonitorresource managed by the Prometheus operator.spec.monitor.prometheus.serviceMonitor.labels.release: prometheusadds therelease: prometheuslabel to the createdServiceMonitor, matching the PrometheusserviceMonitorSelectorso the target is discovered automatically.
$ kubectl apply -f https://github.com/kubedb/docs/raw/v2026.7.10/docs/examples/ignite/monitoring/ignite-alert-demo.yaml
ignite.kubedb.com/ignite-alert-demo created
Now, wait for the database to go into Ready state.
$ kubectl get ignite -n alert-ignite ignite-alert-demo
NAME VERSION STATUS AGE
ignite-alert-demo 2.17.0 Ready 3m
KubeDB creates a dedicated stats service with the -stats suffix for monitoring.
$ kubectl get svc -n alert-ignite --selector="app.kubernetes.io/instance=ignite-alert-demo"
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ignite-alert-demo ClusterIP 10.43.10.20 <none> 10800/TCP 3m
ignite-alert-demo-pods ClusterIP None <none> 10800/TCP 3m
ignite-alert-demo-stats ClusterIP 10.43.10.21 <none> 8080/TCP 3m
KubeDB also creates a ServiceMonitor that tells Prometheus where to scrape.
$ kubectl get servicemonitor -n alert-ignite
NAME AGE
ignite-alert-demo-stats 3m
Verify that the ServiceMonitor carries the release: prometheus label so Prometheus discovers it.
$ kubectl get servicemonitor -n alert-ignite ignite-alert-demo-stats \
-o jsonpath='{.metadata.labels.release}'
prometheus
Step 1 — Create a Grafana API Key
The chart’s dashboard-import Job authenticates to Grafana with a bearer token, so create one first.
Grafana 9+: Administration → Service accounts → Add service account → role Editor → Add token. Copy the token.
Grafana 8.x and earlier (no Service Accounts UI, e.g. the bundled
kube-prometheus-stackGrafana 7.5.5): use the legacy API Keys endpoint instead:# Port-forward Grafana $ kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80& # Retrieve the admin password $ kubectl get secret -n monitoring prometheus-grafana \ -o jsonpath='{.data.admin-password}' | base64 -d && echo # Create an API key with Editor role $ curl -s -X POST -H "Content-Type: application/json" \ -u admin:<grafana_password> \ http://localhost:3000/api/auth/keys \ -d '{"name":"ignite-alerts-demo","role":"Editor"}' # Note the returned "key" # Stop the port-forward $ kill %1
Either way, you end up with a bearer token to use as grafana.apikey below.
Step 2 — Install ignite-alerts
Why the Helm release name matters
The chart derives the PrometheusRule name and scopes every PromQL expression from the Helm release name — so the release name must match the Ignite object’s name (ignite-alert-demo).
Install
$ helm upgrade -i ignite-alert-demo oci://ghcr.io/appscode-charts/ignite-alerts \
-n alert-ignite \
--create-namespace \
--version=v2026.7.14 \
--set form.alert.labels.release=prometheus \
--set grafana.enabled=true \
--set grafana.url="http://prometheus-grafana.monitoring.svc:80" \
--set grafana.apikey="<token-from-above>" \
--set grafana.jobName=ignite-alert-demo-stats \
--set form.alert.appSuffix=ig-grafana-demo
| Flag | Value | Purpose |
|---|---|---|
grafana.url | in-cluster Grafana URL | The dashboard-import Job runs inside the cluster, so this must be a cluster-internal address, not localhost |
grafana.apikey | token from Step 1 | Authenticates the dashboard-import POST request |
grafana.jobName | ignite-alert-demo-stats | Required — the chart’s default (kubedb-databases) doesn’t match any real Prometheus job, so most of the dashboard’s panels show “No data” unless you override it to your instance’s actual stats-service name |
To install alerts only, without the dashboard, omit the
grafana.*flags (or set--set grafana.enabled=false).
Verify the PrometheusRule is created
$ kubectl get prometheusrule -n alert-ignite
NAME AGE
ignite-alert-demo 30s
$ kubectl get prometheusrule -n alert-ignite ignite-alert-demo \
-o jsonpath='{.metadata.labels.release}'
prometheus
Verify the dashboard-import Job
$ kubectl get job -n alert-ignite
NAME STATUS COMPLETIONS AGE
ignite-alert-demo-post-job Complete 1/1 17s
$ kubectl logs -n alert-ignite job/ignite-alert-demo-post-job
{"pluginId":"","title":"kubedb.com / Ignite / alert-ignite / ignite-alert-demo","imported":true, ...}
A "imported":true response confirms the dashboard kubedb.com / Ignite / alert-ignite / ignite-alert-demo now exists in Grafana.
Confirm Prometheus loaded the rules
$ kubectl port-forward -n monitoring \
svc/prometheus-kube-prometheus-prometheus 9090:9090
Open http://localhost:9090/rules and locate the ignite.database and ignite.provisioner groups.

Both groups should show OK. ignite-alerts v2026.7.14 has no opsManager/stash/kubeStash groups — only database and provisioner.
Note the overlap: the
databasegroup’sIgniteDown(for: 30s) andIgnitePhaseCritical(for: 1m) key off the samekubedb_com_ignite_status_phasemetric as theprovisionergroup’sKubeDBIgnitePhaseNotReady/KubeDBIgnitePhaseCritical(for: 1m/15m) — expect both pairs to eventually fire together during a real outage, at different times.
Verify End-to-End
1. Check the Prometheus target is UP
Open http://localhost:9090/query?g0.expr=up%7Bnamespace%3D%22alert-ignite%22%7D&g0.tab=1.

2. Confirm the Ignite alerts are inactive
Open http://localhost:9090/alerts.

All rules should show INACTIVE. IgniteClusterNoBaselineNode will only have data once the cluster’s baseline topology is activated (a normal part of Ignite persistence setup, not KubeDB-specific).
3. Check AlertManager
$ kubectl port-forward -n monitoring \
svc/prometheus-kube-prometheus-alertmanager 9093:9093
Open http://localhost:9093.

Simulating a Firing Alert
This section deliberately triggers IgniteDown (for: 30s, the fastest down-signal) by crashing the main Ignite JVM process.
1. Crash the Ignite process
$ kubectl exec -n alert-ignite ignite-alert-demo-0 -c ignite -- sh -c '
end=$(( $(date +%s) + 60 ));
while [ $(date +%s) -lt $end ]; do
pid=$(pgrep -f "org.apache.ignite" | head -1);
[ -n "$pid" ] && kill -9 "$pid" 2>/dev/null;
sleep 1;
done'
2. Watch the alert fire in Prometheus
Open http://localhost:9090/alerts.

IgniteDown (kubedb_com_ignite_status_phase{phase!="Ready"} == 1, for: 30s) should transition to FIRING first.
3. Check the AlertManager dashboard
Open http://localhost:9093.

4. Restore Ignite
Stop the loop from step 1.
$ kubectl get ignite -n alert-ignite ignite-alert-demo -w
NAME VERSION STATUS AGE
ignite-alert-demo 2.17.0 Ready 24m
If Ignite does not recover on its own within a minute or two, force a clean restart: kubectl delete pod -n alert-ignite ignite-alert-demo-0.
Alert Reference
All alerts are scoped to the ignite-alert-demo instance in the alert-ignite namespace via job="ignite-alert-demo-stats" / namespace="alert-ignite" (database group), or app="ignite-alert-demo" / namespace="alert-ignite" (provisioner group and the two operator-phase alerts embedded in the database group).
Database Group
Fired based on live metrics from the Ignite exporter sidecar and node/kubelet metrics, plus two KubeDB-operator-sourced phase alerts (IgniteDown, IgnitePhaseCritical).
| Alert | Severity | For | What It Means |
|---|---|---|---|
IgniteDown | critical | 30s | KubeDB operator view: resource not Ready. Fastest down-signal available. |
IgnitePhaseCritical | warning | 1m | KubeDB operator view: resource Critical (duplicates the provisioner group’s own version at a different for). |
IgniteClusterNoBaselineNode | warning | 1m | The cluster has no baseline topology node registered. |
IgniteRestarted | warning | 1m | Uptime indicates a recent restart. |
IgniteHighCPULoad | warning | 1m | System CPU load exceeds 80%. |
IgniteHighHeapMemoryUsed | warning | 1m | JVM heap usage is high. |
IgniteHighDataregionOffHeapUsed | warning | 1m | Off-heap data region usage is high. |
IgniteJVMPausesTotalDuration | warning | 1m | Long JVM GC pauses detected. |
DiskUsageHigh | warning | 1m | Persistent volume usage exceeds 80%. |
DiskAlmostFull | critical | 1m | Persistent volume usage exceeds 95%. |
Provisioner Group
Monitors the KubeDB operator’s view of the Ignite resource phase.
| Alert | Severity | For | What It Means |
|---|---|---|---|
KubeDBIgnitePhaseNotReady | critical | 1m | KubeDB marked the Ignite resource NotReady. |
KubeDBIgnitePhaseCritical | warning | 15m | Ignite is degraded but not fully unavailable. |
Customising Alerts
# custom-alerts.yaml
form:
alert:
labels:
release: prometheus
groups:
database:
enabled: warning
rules:
igniteHighCPULoad:
enabled: true
duration: "5m"
severity: warning
$ helm upgrade ignite-alert-demo oci://ghcr.io/appscode-charts/ignite-alerts \
-n alert-ignite \
--version=v2026.7.14 \
-f custom-alerts.yaml
Cleaning up
To remove all resources created in this tutorial, run the following commands.
# Remove the ignite-alerts release (PrometheusRule + dashboard-import Job)
$ helm uninstall ignite-alert-demo -n alert-ignite
# Remove the imported Grafana dashboard (it is not removed by helm uninstall)
$ curl -s -X DELETE -H "Authorization: Bearer <grafana-token>" \
http://localhost:3000/api/dashboards/uid/<uid>
$ kubectl delete ignite -n alert-ignite ignite-alert-demo
$ kubectl delete ns alert-ignite
# Uninstall monitoring stack (optional — skip if other tutorials on this cluster still need them)
$ helm uninstall panopticon -n kubeops
$ helm uninstall prometheus -n monitoring
Next Steps
- Monitor your Ignite instance with KubeDB using built-in Prometheus.
- Monitor your Ignite instance with KubeDB using Prometheus operator.
- Want to hack on KubeDB? Check our contribution guidelines.
































