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
Merged
Conversation
…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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
grafana-operatorhas restarted 190 times in 70 days — roughly three times a day, still happening. It never showed up asCrashLoopBackOffbecause it survives two minutes or more per cycle, so pod status looked healthy.Every exit is identical:
Root cause
The release pinned the operator to
kubernetes.io/arch: arm64, which places it on an Enschede Pi. The stated reasoning was: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
nodeSelectoris 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/productionbuilds clean.cd platform/tests && node --test— 58/58 pass.