fix(monitoring-rules): drop the radius metrics Service; authentik's operator creates it

authentik-outpost-servicemonitors.yaml hand-wrote a headless Service
ak-outpost-local-radius-metrics (9300/TCP) and a ServiceMonitor for it,
because the radius outpost controller used not to expose its metrics port.
authentik 2026.8.3 does: the operator creates that same Service
(http-metrics 9300, managed-by goauthentik.io, service-type metrics) and its
own ServiceMonitor ak-outpost-local-radius selecting exactly those labels.

Restore test run 29 (2026-10-16): on a cold cluster the operator created the
Service first, with a ClusterIP. clusterIP is immutable, so the dry-run of
the hand-written clusterIP: None copy failed and took the whole
monitoring-rules Kustomization with it:

  Service/authentik/ak-outpost-local-radius-metrics dry-run failed (Invalid):
  spec.clusterIPs[0]: Invalid value: ["None"]: may not change once set

In production Flux had created it first; the operator adopted it, and Flux's
label managed-by: homelab now keeps the operator's ServiceMonitor from
matching. Removing the file lets the operator own both; when Flux prunes the
Service, the operator recreates it with its own labels.

No alert rule refers to the radius job.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-16 22:51:46 +02:00
co-authored by Claude Opus 5.5
parent 0933ccdf7b
commit afdeecc161
2 changed files with 0 additions and 64 deletions
@@ -1,63 +0,0 @@
---
# Only radius needs a hand-written ServiceMonitor. The goauthentik.io operator
# creates one per outpost and Prometheus discovers those directly, because
# serviceMonitorSelector here is empty (see monitoring/helmrelease-prometheus.yaml).
# Standalone copies for ldap and paperless-gate used to live here as well; they
# duplicated the operator's and were removed.
#
# Radius requires extra plumbing. The radius binary listens on :9300 just
# like ldap/proxy (hardcoded in authentik/lib/default.yml), but authentik's
# Python operator (`providers/radius/controllers/kubernetes.py`) omits the
# `DeploymentPort(9300, "http-metrics", "tcp", 9300)` entry from its
# `deployment_ports` list — that's an upstream bug; the ldap controller has
# it, radius does not. Result: the operator-managed `ak-outpost-local-radius`
# Service exposes only UDP 1812. Add a sibling Service here that selects the
# same pod labels and exposes 9300/TCP, then a ServiceMonitor for it.
#
# The operator's own `ak-outpost-local-radius` ServiceMonitor cannot cover
# this: it selects on `app.kubernetes.io/managed-by: goauthentik.io` together
# with `goauthentik.io/service-type: metrics`, and no Service carries both —
# the operator's has the first, the one below has the second.
apiVersion: v1
kind: Service
metadata:
name: ak-outpost-local-radius-metrics
namespace: authentik
labels:
app.kubernetes.io/managed-by: homelab
goauthentik.io/outpost-name: local-radius
goauthentik.io/outpost-type: radius
spec:
type: ClusterIP
clusterIP: None
selector:
goauthentik.io/outpost-name: local-radius
goauthentik.io/outpost-type: radius
ports:
- name: http-metrics
port: 9300
targetPort: 9300
protocol: TCP
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: authentik-outpost-radius
namespace: authentik
labels:
release: kube-prometheus-stack
spec:
namespaceSelector:
matchNames:
- authentik
selector:
# Pinned to the Service above. Without managed-by this would also match the
# operator's Service and scrape the same endpoint twice.
matchLabels:
app.kubernetes.io/managed-by: homelab
goauthentik.io/outpost-name: local-radius
goauthentik.io/outpost-type: radius
endpoints:
- port: http-metrics
path: /metrics
interval: 30s
@@ -49,7 +49,6 @@ resources:
# cannot live beside the Velero HelmRelease.
- velero-podmonitor.yaml
- velero-servicemonitor.yaml
- authentik-outpost-servicemonitors.yaml
- authentik-servicemonitor.yaml
# Rook's exporter/mgr monitors: the operator aborts its node-daemon reconcile
# when it cannot create these, which held the CephCluster in Progressing and