Ce qui se passe
Le support des histogrammes natifs passe en bêta dans Kubernetes v1.37
et il est activé par défaut. Introduit en alpha dans la v1.36 sous
KEP-5808, il est implémenté
directement dans le sous-système de métriques partagé
(k8s.io/component-base/metrics), ce qui le fait hériter automatiquement à tous
les composants : kube-apiserver, kube-scheduler, kubelet,
kube-controller-manager, kube-proxy.
Pourquoi ça compte
Depuis toujours, les métriques de durée de Kubernetes reposent sur des
histogrammes Prometheus classiques, dont l'auteur doit fixer les paliers à
l'avance — les étiquettes le : 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10. Trois problèmes en découlent.
D'abord, il faut connaître la distribution avant de l'observer : si les latences
glissent vers la microseconde ou au-delà du dernier palier, l'histogramme devient
aveugle. Ensuite, chaque palier est exporté comme une série distincte
(_bucket{le="..."}) : dix paliers multiplient par dix le nombre de séries, donc
la mémoire de Prometheus et le stockage de la base. Enfin, histogram_quantile()
interpole linéairement entre deux bornes — plus le palier est large, plus le
centile est faux.
L'histogramme natif remplace cela par des paliers exponentiels dynamiques, stockés dans une seule série avec ses spans positifs et négatifs. Le blog annonce jusqu'à 90 % de séries en moins, une résolution qui s'adapte de la nanoseconde à l'heure, et des centiles à l'erreur bornée.
Kubernetes impose deux réglages à toutes ses métriques : BucketFactor: 1.1
— chaque palier est au plus 10 % plus large que le précédent, ce qui garantit une
erreur relative d'environ 5 % au pire sur les centiles, qu'une opération
prenne 1 ms ou 10 s — et MaxBucketNumber: 160, qui plafonne le nombre de
paliers pour protéger la mémoire des composants même en cas de valeurs extrêmes.
Comment s'y prendre
La bonne nouvelle, c'est la double exposition, exigence de conception du
KEP : quand le feature gate NativeHistograms est actif, les composants émettent
les paliers classiques et les spans natifs dans la même charge Protobuf. Les
tableaux de bord et alertes existants continuent de fonctionner sans
modification.
Le piège est côté collecteur. Sur Prometheus 3.0+, la configuration se fait
par job — le flag global --enable-feature=native-histograms est déprécié depuis
la 3.9 :
scrape_configs:
- job_name: 'kubernetes-apiservers'
scrape_native_histograms: true
always_scrape_classic_histograms: true # à garder pendant la transitionSans always_scrape_classic_histograms: true, Prometheus n'ingère plus que le
format natif et cesse d'alimenter les séries _bucket, _count et _sum.
Ce ne sont pas les métriques qui tombent, ce sont vos alertes de latence et vos
histogram_quantile(..._bucket...).
Sur Prometheus 2.40 à 2.x, il n'y a pas de réglage par job : le démarrage
avec --enable-feature=native-histograms active tout ou rien.
Dernier point, la négociation : le scraping en texte brut ne transporte que les
paliers classiques. Prometheus bascule automatiquement en Protobuf quand
scrape_native_histograms est activé.
Source : blog Kubernetes.