Skip to content

ADR 015 — Logs centralisés : Loki + Grafana Alloy (2026-06-13)

Statut

Accepté (2026-06-13). Issue #75.

Contexte

L'observabilité métriques est en place (#74, ADR 014 : kube-prometheus-stack). Il manque les logs : les métriques disent que ça casse, les logs disent pourquoi. Sans agrégation, kubectl logs ne survit pas à un restart de pod et les logs meurent avec le conteneur.

Mêmes contraintes que #74 : cluster EKS éphémère mono-node, GitOps via ArgoCD (pattern app-of-apps), rétention courte assumée pour le coût.

Décision 1 — Loki en mode SingleBinary (monolithique)

Loki est déployé en SingleBinary (un seul process) plutôt qu'en architecture microservices distribuée (read/write/backend séparés + cache memcached + object store).

Critère SingleBinary Distribué (microservices)
Empreinte Un pod, minimale 6+ pods + memcached + minio/S3
Adapté mono-node éphémère Oui Non (surdimensionné)
Scalabilité Limitée (vertical) Horizontale
Complexité Faible Élevée

Sur un mono-node t3.medium déjà chargé, le mode distribué serait absurde. Le SingleBinary couvre le besoin (ingestion + requête des logs du cluster). On désactive explicitement les caches memcached, le gateway nginx, minio et le canary pour rester léger.

Décision 2 — Stockage filesystem, pas d'object storage

storage.type: filesystem (schéma TSDB v13), pas de PVC (emptyDir). Les logs meurent au teardown, comme les métriques (#74). Une prod permanente utiliserait un bucket S3 (chunks) + PVC ; ce n'est pas le modèle du projet. Rétention 24h, alignée sur Prometheus.

Décision 3 — Grafana Alloy plutôt que Promtail

L'agent de collecte est Grafana Alloy (DaemonSet), pas Promtail.

  • Promtail est en fin de vie : Grafana a figé Promtail (LTS jusqu'en 2026 puis EOL) au profit d'Alloy, le collecteur unifié (logs + métriques + traces, basé sur OpenTelemetry Collector). Démarrer sur Promtail serait partir sur un outil déprécié.
  • Alloy en DaemonSet : un agent par node qui tail les fichiers de log sous /var/log/pods (monté depuis l'hôte) et pousse vers Loki.
  • Collecte fichier (local.file_match + loki.source.file) plutôt que l'API Kubernetes (loki.source.kubernetes) : pattern DaemonSet standard, plus léger pour l'API server, RBAC limité aux métadonnées de pods (pas de pods/log).

Décision 4 — Namespace logging dédié

Loki + Alloy vivent dans un namespace logging, séparé de monitoring (métriques). Séparation des responsabilités lisible (et conventionnelle en entretien). La datasource Loki est déclarée côté Grafana via le sidecar datasources du kube-prometheus-stack : une ConfigMap labellisée grafana_datasource: "1" dans le ns monitoring (là où Grafana la cherche), pointant l'URL cross-namespace http://loki.logging.svc.cluster.local:3100. Aucune NetworkPolicy sur ces namespaces, donc le cross-namespace est gratuit.

Décision 5 — Labels low-cardinality

Les logs ne sont labellisés que par namespace, pod, container (+ un job dérivé namespace/container). Pas de labels à forte cardinalité (pas de pod_uid, pas de labels par requête) : la cardinalité des labels est le premier facteur d'explosion mémoire/index de Loki. Le reste (texte du log) est requêtable via LogQL sans être indexé.

Pièges traités

  • Schéma obligatoire : les charts Loki récents exigent un schemaConfig explicite (TSDB v13) sinon le déploiement échoue. Fourni dans les values.
  • Lecture des logs hôte : /var/log/pods appartient à root. Alloy tourne en runAsUser: 0 (tradeoff standard d'un collecteur de logs), avec le mount varlog. Sur EKS AL2023 (containerd), les fichiers sont réels sous /var/log/pods, pas besoin de monter /var/lib/docker.

Conséquences

  • GitOps pur : 2 Applications ArgoCD (loki sync-wave 1, alloy sync-wave 2 car il pousse vers Loki) dans k8s/platform/argocd-apps/. Pas de modif Ansible.
  • Pas de PVC ni d'ELB : teardown par cascade du root-app, rien d'anti-INC-016.
  • Empreinte : ajoute Loki (1 pod) + Alloy (DaemonSet, 1 pod/node) sur un node déjà chargé (cf. ADR 014). Requests basses. À surveiller au prochain aws-start, conjointement avec kube-prometheus-stack.
  • Corrélation métriques ↔ logs : depuis le dashboard RED, on peut pivoter vers les logs du pod via Grafana Explore (datasource Loki).

Évolution possible

  • Object storage S3 + rétention longue si le cluster devenait permanent.
  • OpenTelemetry : Alloy étant basé sur l'OTel Collector, il pourrait à terme unifier logs + métriques + traces (Tempo). Tracing repoussé Sprint 5 (cf. ADR 014).

Date : 2026-06-13 Sprint : 4 Issue : #75