Skip to content
This repository was archived by the owner on Aug 26, 2026. It is now read-only.

fix(observability): stop grafana-operator losing leader election every few hours - #764

Merged
ExtraToast merged 1 commit into
mainfrom
fix/grafana-operator-leader-election
Aug 19, 2026
Merged

fix(observability): stop grafana-operator losing leader election every few hours#764
ExtraToast merged 1 commit into
mainfrom
fix/grafana-operator-leader-election

Conversation

@ExtraToast

Copy link
Copy Markdown
Owner

Problem

grafana-operator has restarted 190 times in 70 days — roughly three times a day, still happening. It never showed up as CrashLoopBackOff because it survives two minutes or more per cycle, so pod status looked healthy.

Every exit is identical:

info   setup  Failed to renew lease  {"lock": "observability/grafana-operator-...", "err": "context deadline exceeded"}
error  setup  problem running operator  {"error": "leader election lost"}
exit 1

Root cause

The release pinned the operator to kubernetes.io/arch: arm64, which places it on an Enschede Pi. The stated reasoning was:

Moved to a Pi to free Frankfurt CPU. The operator only talks to Grafana (cross-site ~30 ms) when reconciling CRs, which is rare — dashboards are static once synced. Negligible runtime overhead from the latency hit.

The premise holds for Grafana traffic and misses the lease. controller-runtime renews leader election against the kube-apiserver, not Grafana, every few seconds for the entire life of the process. The apiserver runs on the Frankfurt VPS, so from Enschede every single renewal crossed the tailnet. Jitter past the 10 s renew deadline terminates the operator.

Grafana itself already runs on frankfurt (nodeSelector: personal-stack/site: frankfurt) — only its operator was remote.

Change

The operator now selects personal-stack/site: frankfurt, co-located with both the Grafana it manages and the apiserver it renews against, removing the WAN hop from the renewal path.

It requests 50m CPU and 96Mi. Frankfurt sits at 46% of allocatable CPU requests, so the capacity handed back to Enschede was not worth a three-times-daily restart loop.

On values nesting

Top-level nodeSelector is correct for this chart, unlike the grafana/pyroscope trap fixed in #763. Verified against the live cluster rather than assumed — the running Deployment already carried {"kubernetes.io/arch":"arm64"}, proving the chart reads that key rather than silently discarding it.

Validation

  • kubectl kustomize platform/cluster/flux/clusters/production builds clean.
  • cd platform/tests && node --test — 58/58 pass.
  • Post-merge check is the restart counter: it should stop advancing past 190.

…y few hours

grafana-operator had restarted 190 times in 70 days, roughly three times
a day, always the same way:

    info  setup  Failed to renew lease  {"err": "context deadline exceeded"}
    error setup  problem running operator  {"error": "leader election lost"}
    exit 1

It never entered CrashLoopBackOff because it stayed up two minutes or
more per cycle, so the failure was invisible in pod status.

The release pinned the operator to `kubernetes.io/arch: arm64`, placing
it on an Enschede Pi to free Frankfurt CPU, on the stated reasoning that
it only reaches Grafana when reconciling CRs and could absorb the ~30 ms
cross-site hop. The lease is what that missed: controller-runtime renews
leader election against the kube-apiserver every few seconds for the life
of the process, and the apiserver runs on the Frankfurt VPS. Every
renewal crossed the tailnet, and jitter past the 10 s renew deadline
terminated the process.

The operator now selects `personal-stack/site: frankfurt`, alongside both
the Grafana it manages and the apiserver it renews against, which takes
the WAN hop out of the renewal path. It requests 50m CPU and 96Mi, so the
capacity it returns to Enschede is not worth the restart loop.

Top-level `nodeSelector` is correct for this chart — the live Deployment
already carried the arm64 selector from that same key, so it is read
rather than silently dropped.
@ExtraToast ExtraToast added the bug Something isn't working label Aug 19, 2026
@ExtraToast ExtraToast self-assigned this Aug 19, 2026
@ExtraToast
ExtraToast merged commit bc5ec60 into main Aug 19, 2026
22 checks passed
@ExtraToast
ExtraToast deleted the fix/grafana-operator-leader-election branch August 19, 2026 07:39
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant