swarm-otel: scrape grafana through its published name
Grafana's own metrics were scraped over loopback through the `grafana-metrics` nginx vhost, declared only where grafana and the collector share a host, so a collector on any other host had no job for it. Its target is now declared on every host as `https://<swarm.grafana.domain>/metrics`, next to the other published targets, and grafana's vhost serves `= /metrics` behind the collector's auth subrequest (`/__grafana_metrics_authz`, the forge's shape). The rules derived from `publishedScrapeTargets` admit the collector's client there and deny every other subject. The loopback scrape is gone with the vhost that served it and its `swarm.grafana.metricsPort` option, so a single host still scrapes grafana once, now by name. A config that sets that option now fails evaluation with "option does not exist". On the published vhost `/metrics` was answered with 403 for everyone. It now answers the collector's token, and a plain session gets authelia's `deny`. The design note that ruled the published vhost out for scraping predates the collector's credential; it is replaced by the location's own comment and a line on `swarm.grafana.domain`. Part of #5205
This commit is contained in:
parent
6f071f7963
commit
54f6061d41
7 changed files with 145 additions and 99 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# The swarm's metrics UI as every hive sees it: the name it is served under,
|
||||
# the port its `/metrics` is re-served on, and the OIDC client it is
|
||||
# registered as, identical on every host. What the host running it decides,
|
||||
# and the container itself, are in ./swarm-grafana.nix.
|
||||
# The swarm's metrics UI as every hive sees it: the name it is served under
|
||||
# and the OIDC client it is registered as, identical on every host. What the
|
||||
# host running it decides, and the container itself, are in
|
||||
# ./swarm-grafana.nix.
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
|
|
@ -20,12 +20,11 @@ in
|
|||
# `enable` is `services.hyperhive.deploy.grafana.enable` — see
|
||||
# ./deploy.nix. Whether this host runs the swarm's Grafana is a
|
||||
# deployment decision, and `swarm.*` has to be identical on every host.
|
||||
# Here is what the service IS to every hive: the name it is served under,
|
||||
# the port its `/metrics` is re-served on, and the OIDC client it is
|
||||
# registered as. What the host running it decides — which build it runs,
|
||||
# where its datasources point, which plugins are in its store path, and
|
||||
# the socket directory it shares with nginx — is `deploy.grafana`, in
|
||||
# ./swarm-grafana.nix.
|
||||
# Here is what the service IS to every hive: the name it is served under
|
||||
# and the OIDC client it is registered as. What the host running it
|
||||
# decides — which build it runs, where its datasources point, which plugins
|
||||
# are in its store path, and the socket directory it shares with nginx — is
|
||||
# `deploy.grafana`, in ./swarm-grafana.nix.
|
||||
options.services.hyperhive.swarm.grafana = {
|
||||
machine = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
|
|
@ -51,35 +50,13 @@ in
|
|||
⚠️ Changing this changes the OAuth redirect URI, which authelia
|
||||
matches exactly. Both sides move together because both derive from
|
||||
this option; an operator who pins one by hand breaks the login.
|
||||
'';
|
||||
};
|
||||
|
||||
metricsPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 9095;
|
||||
description = ''
|
||||
Loopback port on which the gateway's nginx re-serves Grafana's
|
||||
`/metrics`, and nothing else, so the swarm's collector can scrape it.
|
||||
|
||||
⚠️ **This is nginx's port, not Grafana's.** Grafana still claims none —
|
||||
see {option}`services.hyperhive.deploy.grafana.socketDir` for why that
|
||||
matters. A prometheus scrape target is a `host:port`, and it cannot
|
||||
address a unix socket; rather than undo the socket decision, the one
|
||||
endpoint a scraper needs gets a listener of its own.
|
||||
|
||||
Bound to loopback and unauthenticated, which is the same posture every
|
||||
other entry in
|
||||
{option}`services.hyperhive.swarm.otel.scrapeTargets` has: those
|
||||
targets are trusted by *proximity* rather than by credential.
|
||||
Deliberately **not** the published `grafana.<domain>` vhost, which
|
||||
would put an authorization decision in front of a scrape: that vhost
|
||||
answers `/metrics` with 403, because Grafana serves it without
|
||||
authentication.
|
||||
|
||||
The number itself is arbitrary and free today;
|
||||
`state/eval-port-collisions.sh` is what keeps it that way, since a
|
||||
second claim on a port in this shared namespace produces no bind error
|
||||
and nothing in any log.
|
||||
The swarm collector scrapes Grafana's own metrics at
|
||||
`https://<this name>/metrics`, from whichever host it runs on.
|
||||
Grafana serves that endpoint to anyone, so the gateway puts it
|
||||
behind authelia, whose rules admit only the collector's OAuth2
|
||||
client there: see `publishedScrapeTargets` in
|
||||
./swarm-otel-service.nix.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue