Ce qu'un pod a dit lui survit — Loki et Alloy, sous plafond (#38) #40
+80
-6
@@ -30,6 +30,20 @@ alloy:
|
|||||||
# structurante — un agent par nœud, donc trois fois le coût mémoire.
|
# structurante — un agent par nœud, donc trois fois le coût mémoire.
|
||||||
type: daemonset
|
type: daemonset
|
||||||
|
|
||||||
|
# Le volume que consomme le montage `alloy.mounts.extra` ci-dessous : la
|
||||||
|
# racine Docker de ces machines, où aboutissent les liens de /var/log/pods.
|
||||||
|
volumes:
|
||||||
|
extra:
|
||||||
|
- name: docker-containers
|
||||||
|
hostPath:
|
||||||
|
path: /mnt/arcodange/docker/containers
|
||||||
|
# `Directory` (et non `DirectoryOrCreate`) EXPRÈS : si un jour un
|
||||||
|
# nœud n'a pas ce chemin, on veut que son agent refuse de démarrer
|
||||||
|
# et le DISE, plutôt que de monter un dossier vide et de rapporter
|
||||||
|
# zéro journal en se déclarant sain — le défaut exact qu'on vient
|
||||||
|
# de traverser.
|
||||||
|
type: Directory
|
||||||
|
|
||||||
alloy:
|
alloy:
|
||||||
# -- Le montage de /var/log : c'est par là que l'agent lit les journaux.
|
# -- Le montage de /var/log : c'est par là que l'agent lit les journaux.
|
||||||
# On tail des FICHIERS plutôt que d'interroger l'API du kubelet : sur trois
|
# On tail des FICHIERS plutôt que d'interroger l'API du kubelet : sur trois
|
||||||
@@ -37,9 +51,37 @@ alloy:
|
|||||||
# serveur d'API une charge qu'il n'a pas à porter.
|
# serveur d'API une charge qu'il n'a pas à porter.
|
||||||
mounts:
|
mounts:
|
||||||
varlog: true
|
varlog: true
|
||||||
# k3s utilise containerd, pas Docker : ce montage-là ne servirait à rien.
|
# ⚠⚠ CE CLUSTER TOURNE SOUS DOCKER, PAS SOUS CONTAINERD — et son magasin
|
||||||
|
# d'images n'est pas là où le chart le cherche. Les deux faits ensemble
|
||||||
|
# rendent ce drapeau inutilisable.
|
||||||
|
#
|
||||||
|
# Mesuré le 2026-09-07 (`kubectl get nodes -o …containerRuntimeVersion`) :
|
||||||
|
# pi1 docker://29.1.3
|
||||||
|
# pi2 docker://28.4.0
|
||||||
|
# pi3 docker://27.4.0
|
||||||
|
#
|
||||||
|
# Et sous /var/log/pods, les journaux ne sont PAS des fichiers : ce sont
|
||||||
|
# des liens symboliques vers la racine Docker, DÉPLACÉE sur un disque
|
||||||
|
# externe (identique sur pi1 et pi3, vérifié pod par pod) :
|
||||||
|
#
|
||||||
|
# /var/log/pods/<ns>_<pod>_<uid>/<conteneur>/0.log
|
||||||
|
# -> /mnt/arcodange/docker/containers/<id>/<id>-json.log
|
||||||
|
#
|
||||||
|
# `dockercontainers: true` monterait `/var/lib/docker/containers`, qui
|
||||||
|
# n'existe pas ici. On monte donc la vraie racine, plus bas, en `extra`.
|
||||||
dockercontainers: false
|
dockercontainers: false
|
||||||
|
|
||||||
|
# ⚠ SANS CE MONTAGE, LA COLLECTE EST SILENCIEUSEMENT VIDE — et c'est le
|
||||||
|
# mode d'échec le plus traître de ce lot, parce que TOUT A L'AIR SAIN :
|
||||||
|
# les six composants d'Alloy se déclarent `healthy`, aucune erreur de
|
||||||
|
# poussée, Loki répond `ready`. Le seul relevé qui le dit est
|
||||||
|
# `loki_source_file_files_active_total = 0`, et l'export vide de
|
||||||
|
# `local.file_match`. `ls` montre les liens, `stat` échoue sur la cible.
|
||||||
|
extra:
|
||||||
|
- name: docker-containers
|
||||||
|
mountPath: /mnt/arcodange/docker/containers
|
||||||
|
readOnly: true
|
||||||
|
|
||||||
# ⚠ LA MÉMOIRE EST LA RESSOURCE RARE, ET UN DAEMONSET LA PREND TROIS FOIS.
|
# ⚠ LA MÉMOIRE EST LA RESSOURCE RARE, ET UN DAEMONSET LA PREND TROIS FOIS.
|
||||||
# Mesuré le 2026-09-07 avant tout déploiement : pi1 79 %, pi2 109 %,
|
# Mesuré le 2026-09-07 avant tout déploiement : pi1 79 %, pi2 109 %,
|
||||||
# pi3 58 % de leur mémoire ALLOUABLE. pi2 est en surengagement — c'est
|
# pi3 58 % de leur mémoire ALLOUABLE. pi2 est en surengagement — c'est
|
||||||
@@ -140,12 +182,17 @@ alloy:
|
|||||||
forward_to = [loki.process.journaux_de_pods.receiver]
|
forward_to = [loki.process.journaux_de_pods.receiver]
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⚠ containerd n'écrit PAS du JSON de Docker : chaque ligne est
|
// ⚠⚠ `stage.docker`, PAS `stage.cri` — ces nœuds tournent sous Docker
|
||||||
// « <horodatage> <flux> <F|P> <message> ». Sans `stage.cri`, l'horodatage
|
// (mesuré : docker://29.1.3, 28.4.0, 27.4.0), donc chaque ligne est un
|
||||||
// stocké serait celui de la LECTURE et non celui de l'écriture — ce qui
|
// objet JSON {"log":…,"stream":…,"time":…} et non le format CRI
|
||||||
// ruinerait précisément l'usage qui motive ce lot : dater une panne.
|
// « <horodatage> <flux> <F|P> <message> ».
|
||||||
|
//
|
||||||
|
// Ce n'est pas cosmétique : sans le bon décodeur, l'horodatage stocké
|
||||||
|
// serait celui de la LECTURE et non celui de l'écriture, et les lignes
|
||||||
|
// arriveraient encore encapsulées dans leur JSON. Or dater une panne à
|
||||||
|
// la minute est PRÉCISÉMENT l'usage qui motive ce lot (tools#36).
|
||||||
loki.process "journaux_de_pods" {
|
loki.process "journaux_de_pods" {
|
||||||
stage.cri {}
|
stage.docker {}
|
||||||
|
|
||||||
forward_to = [loki.write.loki.receiver]
|
forward_to = [loki.write.loki.receiver]
|
||||||
}
|
}
|
||||||
@@ -173,3 +220,30 @@ alloy:
|
|||||||
|
|
||||||
ingress:
|
ingress:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
|
# ⚠⚠ LE MÊME PIÈGE QUE LE SIDE-CAR DE LOKI, DEUXIÈME OCCURRENCE — et celle-ci
|
||||||
|
# est plus sournoise, parce qu'elle RESSEMBLE à un plafond.
|
||||||
|
#
|
||||||
|
# Le chart ajoute au pod un second conteneur, `config-reloader`, qui recharge
|
||||||
|
# Alloy quand sa ConfigMap change. Mesuré sur le premier déploiement, ses
|
||||||
|
# ressources amont sont :
|
||||||
|
#
|
||||||
|
# resources:
|
||||||
|
# requests: { cpu: 10m, memory: 50Mi }
|
||||||
|
# ← et RIEN d'autre
|
||||||
|
#
|
||||||
|
# Une requête SANS limite n'est pas un plafond : c'est une réservation. Le
|
||||||
|
# conteneur peut croître jusqu'à épuiser le nœud, et comme il partage le
|
||||||
|
# cgroup du pod, il emporte Alloy avec lui. Sur un DaemonSet, cela vaut sur
|
||||||
|
# les TROIS nœuds — pi2 compris, mesuré à 108 % de son allouable.
|
||||||
|
#
|
||||||
|
# ⚠ On ne peut pas l'éteindre : sans lui, un changement de configuration
|
||||||
|
# n'atteindrait l'agent qu'au prochain redémarrage du pod. On le PLAFONNE.
|
||||||
|
configReloader:
|
||||||
|
enabled: true
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 64Mi
|
||||||
|
|||||||
Reference in New Issue
Block a user