ADR 004
Collect telemetry with OpenTelemetry into Mimir and Loki
OpenTelemetry Collectors send metrics to Mimir and logs to Loki. Notifications and the dead-man's switch run off-site, so alerts still arrive when the lab is down.
- Status
- Accepted
- Rollout
- 0 of 7 gates
- Related
Accepted, not yet implemented.
Context
One operator runs the platform. Metrics, logs and alerts have to show whether the cluster is healthy, whether an upgrade worked, whether backups are fresh and which component is breaking. They also have to survive one Proxmox host failure, as the rest of the platform does (ADR 007).
Observability stays in the lab. Only the notification endpoint and the dead-man's switch run outside it, on the Oracle Cloud VM, because they must work when the lab is down (ADR 012).
Decision
Collection
Use the OpenTelemetry Collector everywhere. In the cluster, the OpenTelemetry
Operator's Target Allocator reads ServiceMonitor and PodMonitor resources
and spreads the scrape targets across the collector pods. Proxmox sends OTLP
natively. Mimir and Loki accept OTLP, so the collectors send to them directly.
One small Alloy pod runs only mimir.rules.kubernetes and
loki.rules.kubernetes. Its only job is to load rules from the cluster into
the Mimir and Loki rulers. It collects no telemetry.
Metrics
Run Mimir in classic architecture with the mimir-distributed Helm chart:
- Set
ingest_storage.enabled: falseandkafka.enabled: false. - Pin the chart version and follow its documented classic recipe, which also
sets
ingester.push_grpc_method_enabled: true. - Run three ingesters with replication factor 3, so one node can fail.
- Run two replicas of each stateless component and one compactor.
- Keep per-tenant retention in the chart's runtime overrides. The analytics tenant keeps its data longer than the default.
With three ingesters and replication factor 3, every series lives on every ingester. Ingester memory per node is therefore not divided by three. Size each ingester for the full series count. The gain over one Prometheus is that scraping, queries and rule evaluation run in other components, and one node can fail without losing metrics.
Mimir ingest storage is not used. It needs a Kafka-compatible broker. The chart's bundled Kafka is for demonstration and testing only, so production would need a separate Kafka-compatible service to run, upgrade and back up. For one operator that costs more than the classic write path. Classic is still supported. Revisit ingest storage when Grafana announces the deprecation date for classic.
Logs
Run Loki in single-binary mode with three replicas. Traces are out of scope.
Object storage
Mimir and Loki store blocks and chunks in Garage on TrueNAS.
If TrueNAS is down, ingesters keep recent data on their local disks and rules on recent data keep firing. Queries older than the ingester window fail, and the local disks fill up eventually. Size the ingester disks for a supported outage window, decided at build time. A blackbox probe and node metrics watch TrueNAS, and TrueNAS's own alerts send email.
Alerting
Keep rules in Git as PrometheusRule resources. PromQL rules and LogQL rules
use separate selectors, so each ruler loads only its own rules.
Run a standalone Alertmanager with two replicas, defined by a
prometheus-operator Alertmanager resource and AlertmanagerConfig resources.
Receiver URLs come from OpenBao through External Secrets. The Mimir ruler and
the Loki ruler both send to it through their alertmanager_url settings.
The Alertmanager resource takes its global routing from one
AlertmanagerConfig through spec.alertmanagerConfiguration. The operator
adds a namespace matcher to the routes of every namespaced AlertmanagerConfig,
so those routes only match alerts that carry their namespace label. Watchdog
and host alerts don't carry one, so the top-level route must come from
spec.alertmanagerConfiguration.
Turn off Mimir's own Alertmanager and delete terraform/alerting.tf. One
Alertmanager serves both rulers, and its routing is a Kubernetes resource in
Git instead of Terraform state.
Notifications
Send alerts to Discord, and to ntfy on the Oracle Cloud VM for alerts that must be seen. ntfy runs with:
- a persistent message cache;
- a deny-by-default ACL, write-only publisher users and a read-only phone user;
- its
/metricsendpoint scraped by the lab.
Alertmanager posts to ntfy with ?template=alertmanager. Gotify is retired.
Dead-man's switch
Run Uptime Kuma on the Oracle VM. These ping its push monitors:
- the Watchdog alert from Alertmanager;
- the jobs that run outside the cluster: the Docker host Git backup and the daily Terraform state copy.
The Oracle VM joins the Ansible inventory and the docs. The lab checks that the VM itself is alive, because Oracle reclaims idle free-tier VMs.
Not in scope
Traces, profiling, service maps and SLO automation. Each would need its own decision.
Consequences
- Mimir has more components than one Prometheus. In exchange it tolerates a node failure and keeps long-term data in object storage.
- Three-way replication triples ingester memory and disk across the cluster. The capacity rule in ADR 007 has to include it.
- Mimir and Loki depend on TrueNAS for anything older than the ingester window. A long TrueNAS outage fills the ingester disks.
- Alloy stays only for rule sync.
- Mimir and Loki majors are in the manual Renovate set (ADR 011).
Implementation status
Not built. Today Alertmanager routing lives in Mimir's built-in Alertmanager,
managed by Terraform in terraform/alerting.tf with the mimirtool provider.
References
- Mimir Helm chart 5.x to 6.0 migration
- Mimir ingest storage migration
- prometheus-operator AlertmanagerConfig
- ADR 006: Backups and rebuild
- ADR 007: Talos production topology
- ADR 012: What to self-host
Rollout gates
- On staging, Mimir, Loki, the collectors, the rule-sync Alloy pod and the standalone Alertmanager run as production will run them. open
- A Mimir alert, a Loki alert and Watchdog each arrive at their receivers on staging. open
- A staging drill with Garage stopped, including a ruler restart, confirms that a notification arrives. open
- ntfy delivers to the phone with the screen off, on Wi-Fi and on mobile data. open
- The Uptime Kuma push monitors and the lab-side check of the Oracle VM alert when their source stops. open
- The ingester disk size and the outage window it covers are recorded. open
-
The rules and routing run on production's Alertmanager, and
terraform/alerting.tfis deleted. open