Files
homelab/kubernetes/apps/monitoring-rules/loki-servicemonitor.yaml
claude-bot 15ec3ce2f0 fix(monitoring): stop double-scraping two authentik outposts
Chasing a stale comment turned up a live duplicate. Since serviceMonitorSelector
was loosened to {}, Prometheus discovers the goauthentik.io operator's own
ServiceMonitors — which is why it was loosened. The hand-written copies for ldap
and paperless-gate, added back when the strict selector was dropping the
operator's, now scrape the same endpoints a second time.

Measured, not assumed: 10.244.4.113:9300 and 10.244.4.76:9300 were each
producing 40 samples per 10 minutes against 20 for every other outpost, and
ldap picked up a third target because the hand-written selector matched the
plain Service as well as the -metrics one. No duplicate-timestamp errors,
because the two pools scrape at different offsets — the cost is doubled
ingestion and a target list that lies about how many outposts there are.

Radius stays, and the comment now says why it is not the same case: the
operator's ServiceMonitor for it selects on managed-by=goauthentik.io together
with service-type=metrics, and no Service carries both — the operator's has the
first, the one defined here has the second. It is the only thing scraping
radius, so deleting it would have been a silent loss.

Also corrects the comments that claimed the release label is required for
discovery. It is not, for ServiceMonitors and PodMonitors: those two selectors
are empty. It very much is for Probes, PrometheusRules and ScrapeConfigs, whose
selectors still match on it, so probes-blackbox.yaml now says so explicitly —
otherwise the corrected comments elsewhere read as license to drop the label
there too.

Live selector state, for the record:
  serviceMonitorSelector {}   podMonitorSelector {}
  probeSelector / ruleSelector / scrapeConfigSelector  release=kube-prometheus-stack
2026-08-28 09:00:58 +02:00

30 lines
1.0 KiB
YAML

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: loki
namespace: monitoring
labels:
app.kubernetes.io/name: loki
# Not required for discovery — serviceMonitorSelector is empty — but kept
# for consistency with the other monitors.
release: kube-prometheus-stack
spec:
# Matches the `loki` (single-binary) and `loki-canary` services, but
# not `loki-headless` (variant=headless, chart marks it opt-out) or
# `loki-memberlist` (no http-metrics port, would be skipped anyway).
selector:
matchLabels:
app.kubernetes.io/name: loki
matchExpressions:
- { key: variant, operator: DoesNotExist }
endpoints:
- port: http-metrics
path: /metrics
interval: 30s
relabelings:
# Operator default would label both endpoints job=monitoring/loki,
# which collapses loki and loki-canary onto the same job. Promote
# the service name to `job` so alerts can target them separately.
- sourceLabels: [__meta_kubernetes_service_name]
targetLabel: job