fix(alert-tuning): [SPRE-5878] suppress EtcdHighNumberOfLeaderChanges during cluster upgrades - #1266
Conversation
PR Summary by QodoTune EtcdHighNumberOfLeaderChanges alert threshold (>2 → >4)
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
1.
|
The stable-counter no-alert test was missing namespace="openshift-etcd" on the input series, meaning it never matched the alert expression (which filters on that label). The test passed vacuously rather than genuinely asserting no alert fires for a stable counter. Caught by qodo code review on PR redhat-appstudio#1266. Jira: https://redhat.atlassian.net/browse/SPRE-5878
gcpsoares
left a comment
There was a problem hiding this comment.
Check if we can inhibit the alert during ongoing upgrades.
… during cluster upgrades
## Problem
EtcdHighNumberOfLeaderChanges was generating ~109 false positive firings
across two consecutive 14-day investigation windows with 0% actionable
signal. Every firing fell strictly within scheduled OCP upgrade windows.
Root cause: during a rolling upgrade, the MachineConfigOperator drains and
reboots control plane nodes one at a time. Each restart stops the local etcd
member, forcing a Raft leader re-election. A 3-node cluster produces 2-3
elections per upgrade (~70-minute window), consistently crossing the > 2
threshold. The alert is mathematically guaranteed to fire on every upgrade.
## Why not raise the threshold
Raising the threshold from > 2 to > 4 was considered and rejected. The
maximum observed increase() value during any upgrade was 3.158 — raising to
> 4 would eliminate all false positives but creates a blind spot: genuine
instability (e.g. disk pressure, network blip) causing 3-4 elections during
normal operation would go silently undetected. Preserving full sensitivity
(> 2) is the correct behaviour.
## Resolution
Suppress the alert per-cluster during active upgrades using a recording rule
derived from ClusterUpgradeOngoing as the inhibition signal:
(increase(etcd_server_leader_changes_seen_total{namespace="openshift-etcd"}[10m]) > 2)
unless on (source_cluster)
cluster_upgrade_ongoing
This preserves full sensitivity during normal operation and suppresses only
when an upgrade is confirmed firing on the same cluster. An upgrade on one
cluster does not affect alerting on others.
## Why a recording rule instead of ALERTS{} directly
The unless clause references cluster_upgrade_ongoing (a recording rule) rather
than ALERTS{alertname="ClusterUpgradeOngoing"} directly, per reviewer feedback:
1. ALERTS{} silently matches both alertstate="firing" and alertstate="pending".
The recording rule explicitly filters alertstate="firing" — suppression only
activates once the upgrade is confirmed, not while it is still pending.
2. ALERTS{} is an internal Prometheus construct. A named recording rule
produces a stable, well-defined, reusable time series.
Known tradeoff: the recording rule adds one evaluation cycle (~1 min) of
additional lag before suppression activates. This is negligible given the
~70-minute upgrade window and the etcd alert's own for: 1m gate.
Label alignment verified in production RHOBS: cluster_name in
aus_cluster_upgrade_policy_info matches source_cluster on
etcd_server_leader_changes_seen_total across all RHTAP clusters.
## Changes
rhobs/recording/cluster_upgrade_recording_rules.yaml (new):
Recording rule that materialises cluster_upgrade_ongoing{source_cluster}=1
only when ClusterUpgradeOngoing is alertstate="firing". Uses
max by (source_cluster) to produce a clean per-cluster signal.
rhobs/alerting/data_plane/prometheus.cluster_ongoing_updrade_alert.yaml:
Wrap expression in label_replace() to copy cluster_name into source_cluster,
enabling per-cluster join with etcd metrics via unless on (source_cluster).
rhobs/alerting/data_plane/prometheus.cluster_capacity_alerts.yaml:
Add unless on (source_cluster) cluster_upgrade_ongoing inhibition to
EtcdHighNumberOfLeaderChanges. Threshold stays at > 2.
test/promql/tests/data_plane/cluster_upgrade_ongoing_alert_test.yaml:
Assert source_cluster label is present in the fired alert.
test/promql/tests/data_plane/cluster_capacity_test.yaml:
- Fix pre-existing bug: stable-counter test was missing
namespace="openshift-etcd", causing vacuous pass
- Add suppression test: same-cluster upgrade suppresses the alert
- Add per-cluster specificity test: different-cluster upgrade does not
- Add stable-counter negative test
test/promql/tests/recording/cluster_upgrade_recording_rules_test.yaml (new):
- alertstate="firing" → cluster_upgrade_ongoing{source_cluster}=1
- alertstate="pending" → no output
## Test results
promtool test rules (quay.io/prometheus/prometheus):
cluster_capacity_test.yaml SUCCESS
cluster_upgrade_ongoing_alert_test.yaml SUCCESS
cluster_upgrade_recording_rules_test.yaml SUCCESS
Jira: https://redhat.atlassian.net/browse/SPRE-5878
58ca96a to
3b64337
Compare
Summary
Resolves SPRE-5878 — Alert Review & Tuning:
EtcdHighNumberOfLeaderChangesSuppresses the alert per-cluster during active OCP upgrades using a recording
rule as the inhibition signal, while preserving full sensitivity (
> 2)during normal operation.
EtcdHighNumberOfLeaderChangesgenerated ~109 false positive firings acrosstwo consecutive 14-day investigation windows with 0% actionable signal and
zero associated PagerDuty incidents or user-impacting events.
Every firing occurred strictly within scheduled weekly OCP upgrade windows.
During a rolling upgrade, the MachineConfigOperator drains and reboots control
plane nodes one at a time — each restart forces a Raft leader re-election. A
standard 3-node etcd cluster produces 2–3 elections per upgrade (~70-minute
window), mathematically guaranteeing a crossing of the
> 2threshold on everyupgrade cycle.
Why not raise the threshold
Raising the threshold from
> 2to> 4was considered and rejected. Themaximum observed
increase()value during any upgrade was 3.158 — raisingto
> 4would eliminate all false positives, but creates a blind spot: genuineinstability (e.g. disk pressure, network blip) causing 3–4 leader elections
during normal operation would go silently undetected. Preserving full sensitivity
(
> 2) is the correct behaviour.Resolution
Suppress the alert per-cluster during active upgrades using the Prometheus
unlessoperator with a dedicated recording rule as the inhibition signal: