Flux health
Everything on the cluster is reconciled by Flux, so “is the platform healthy”
mostly reduces to “are the Flux objects Ready”. A Kustomization whose health
check times out and a HelmRelease whose chart failed to install look
identical from the outside: the object’s Ready condition goes false, and
everything around it keeps reporting green.
This page covers the two views of that signal, on gcp-0 and anywhere else
the repository is deployed.
The report: scripts/ops/k8s/flux-health.sh
scripts/ops/k8s/flux-health.sh prints one line per Kustomization or
HelmRelease that is not Ready:
$ scripts/ops/k8s/flux-health.sh
Kustomization flux-system/apps: HealthCheck failed: timeout waiting for health check
HelmRelease observability/victoria-metrics-k8s-stack: Helm install failed: context deadline exceeded
The line is <kind> <namespace>/<name>: <reason>, where <reason> is the
message of the object’s Ready condition. An object with no Ready
condition at all yet — just created, or the status never arrived — is reported
as no Ready condition reported, because silence is not health.
It is a report, not a gate:
- it exits
0whatever the count, so it never breaks whatever runs it; - it reads only (
kubectl get), changes nothing; - if the cluster is unreachable or the Flux CRDs are absent it still exits
0, with a warning on stderr and whatever it could list on stdout.
scripts/ci/tests/test-flux-health.sh runs the script against a canned
kubectl get -o json fixture, covering the not-ready, ready, and
no-condition cases for both kinds plus the unreachable-cluster path.
Why a second script, when flux-not-ready.sh already exists? That one covers
the Kustomizations only. On gcp-0 the HelmReleases are just as
load-bearing — a chart that fails to reconcile surfaces its error in the
object’s Ready condition, nowhere else.
The panel: Not-Ready Flux resources
The flux-cluster dashboard (vendored inline in
flux/observability/grafana-dashboards.yaml) has a Not-Ready Flux
resources panel: a time series of the count of Kustomizations and
HelmReleases that are not Ready, one line per kind:
sum(gotk_resource_info{exported_namespace=~"$namespace",
customresource_kind=~"Kustomization|HelmRelease", ready!="True"})
by (customresource_kind)The gotk_resource_info metric is exported by the Flux controllers
themselves; the $namespace variable is the dashboard’s namespace filter.
How to read it
- Flat on zero — every
KustomizationandHelmReleaseon the selected namespaces is Ready. - A line that steps up and back — a reconciliation in flight, or a transient failure that the next reconcile fixed. The Flux controllers retry; a blip that resolves itself is normal.
- A line that steps up and stays — something is stuck. Run the script above to get the per-object reason, and see Troubleshooting for the failures specific to this platform.
Note that ready!="True" is deliberately wider than the dashboard’s Failing
Reconcilers stat, which counts ready="False" only: this panel also counts
Unknown — objects whose reconciliation has not concluded. That matches the
script’s definition of not-Ready (an object is Ready, or it is not), so the
panel and the script answer the same question.
Reading on
- GitOps — the reconciliation model behind these conditions
- Observability — where the dashboards live and how they reach the cluster
- Troubleshooting — the failures specific to this platform