З радістю повідомляю, що підтримка нативних гістограм для метрик Kubernetes переходить у стан бета та є стандартно увімкненою в Kubernetes v1.37!
Нативні гістограми (раніше представлені як альфа у Kubernetes v1.36 за KEP-5808) приносять високоточну, низько кардинальну спостережуваність для метрик Kubernetes. Завдяки впровадженню Prometheus Native Histograms, компоненти Kubernetes тепер експонують метрики затримки та тривалості з набагато більшою точністю, значно зменшуючи обсяг зберігання телеметрії та накладні витрати на збирання даних.
З самого початку розвитку спостережуваності в Kubernetes показники тривалості та затримки (такі як затримки запитів до сервера API або тривалість планування) базувалися на класичних гістограмах Prometheus.
Класичні гістограми вимагають від авторів метрик визначення статичного списку меж кумулятивних інтервалів (міток le), таких як 0,005; 0,01; 0,025; 0,05; 0,1; 0,25; 0,5; 1; 2,5; 5; 10. Хоча цей підхід є звичним, він створює три основні проблеми:
_bucket{le="..."}). Гістограма з 10 інтервалами, що охоплюють кілька міток, збільшує кількість часових рядів у 10 разів, що підвищує споживання пам’яті в Prometheus та збільшує витрати на зберігання в базі даних часових рядів (TSDB, time series database).histogram_quantile() ґрунтується на лінійній інтерполяції між статичними межами сегментів. Коли діапазони сегментів є грубими, обчислення квантилів можуть мати значну похибку оцінювання.Prometheus Native Histograms замінює статичні користувацькі інтервали на динамічні, експоненційні інтервали.
Замість того, щоб експортувати окремий часовий ряд для кожної межі інтервалу, нативна гістограма зберігається як один часовий ряд, що містить розширену схему позитивних та негативних інтервалів, нульових порогів і експоненційних коефіцієнтів масштабування.
У Kubernetes підтримка нативних гістограм реалізована безпосередньо всередині спільної підсистеми метрик (k8s.io/component-base/metrics).
На малюнку 1 показано, як метрики нативних гістограм обробляються та експортуються в компонентах Kubernetes.
Малюнок 1. Обробка метрик нативних гістограм та подвійний потік експозиції в Kubernetes.
Основною вимогою до дизайну KEP-5808 було відсутність порушень для наявних стеків спостереження. Коли ввімкнено функціональну можливість NativeHistograms, компоненти Kubernetes використовують подвійний потік експозиції:
h.Bucket) все ще експортуються разом із нативними відрізками. Наявні сервери Prometheus, панелі моніторингу та правила оповіщення, які покладаються на традиційне текстове сканування або класичні мітки інтервалів, продовжують працювати без змінh.Schema, h.PositiveSpan) включаються в той самий Protobuf-навантаження для колекторів, які розуміють нативні гістограмиКоли ввімкнено функціональну можливість NativeHistograms, пакунок k8s.io/component-base/metrics автоматично застосовує стандартизовані експоненційні опції до всіх метрик гістограм:
BucketFactor: 1.1: Налаштовує експоненційні інтервали, де кожен інтервал не ширший за 10% порівняно з попереднім. Це гарантує математично обмежену відносну похибку у гіршому випадку на рівні ~5% для обчислення квантилів, незалежно від того, чи операція триває 1 мс або 10 с.MaxBucketNumber: 160: Обмежує максимальну кількість інтервалів на гістограму до 160. Відповідно до рекомендацій OpenTelemetry SDK щодо агрегації експоненційних гістограм з основою 2, це обмеження захищає використання пам’яті компонентів навіть при екстремальних розподілах викидів.Оскільки нативні гістограми інтегровані в component-base/metrics, всі основні компоненти контрольної площини та вузлів Kubernetes автоматично успадковують підтримку, зокрема:
kube-apiserver (наприклад, apiserver_request_duration_seconds, метрики автентифікації/авторизації, затримки валідації)kube-scheduler (наприклад, scheduler_plugin_execution_duration_seconds, scheduler_scheduling_algorithm_duration_seconds)kubelet (метрики рівня вузла для контейнерного середовища та життєвого циклу подів)kube-controller-manager та kube-proxyПросте рішення: оновіть Kubernetes до версії v1.37, і все працюватиме.
Оскільки в Kubernetes v1.37 стандартно увімкнено NativeHistograms, ваш кластер уже експортує метрики з подвійним потоком експозиції. Те, як ви налаштовуєте Prometheus для збору нативних гістограм, залежить від версії Prometheus:
Prometheus 3.0+ (Рекомендовано): Використовуйте явну конфігурацію для кожного завдання у вашому scrape_configs замість глобальних прапорців (глобальний прапорець --enable-feature=native-histograms застарів у Prometheus 3.9+):
scrape_configs:
- job_name: 'kubernetes-apiservers'
scrape_native_histograms: true
always_scrape_classic_histograms: true # Recommended during transition
Обов’язково ознайомтеся з застереженням у розділі Міграція панелей і сповіщень у документації щодо нативних гістограм. Підсумок: завжди встановлюйте always_scrape_classic_histograms: true під час перехідного періоду. Без цього налаштування Prometheus буде збирати лише нативний формат і припинить збір класичних серій _bucket, _count та _sum. Встановлення always_scrape_classic_histograms: true гарантує, що існуючі панелі (histogram_quantile(..._bucket...)) і сповіщення продовжують працювати, поки ви мігруєте їх на нативні гістограми.
Prometheus 2.40 – 2.x: Увімкніть нативні гістограми глобально, запустивши Prometheus з відповідним прапорцем:
prometheus --enable-feature=native-histograms
Зверніть увагу, що в Prometheus 2.x це налаштування "все або нічого" для всіх цілей збору.
Стандартне сканування Prometheus у текстовому форматі (application/openmetrics-text або plain text) передає лише класичні інтервали. Коли увімкнено scrape_native_histograms, Prometheus автоматично домовляється про Protobuf формат з точками доступу Kubernetes.
Ви можете перевірити, що компонент Kubernetes експортує нативні гістограми, використовуючи curl з заголовком Accept, що вказує Protobuf. Наприклад:
## ЦЕ НЕБЕЗПЕЧНО. РОБІТЬ ЦЕ ЛИШЕ В ТЕСТОВОМУ КОНТЕКСТІ.
curl --insecure \
-H "Accept: application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited" \
--header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://localhost:6443/metrics
Після декодування повернене MetricFamily для метрик гістограми (наприклад, apiserver_request_duration_seconds) міститиме як традиційні записи bucket, так і заповнені поля schema / positive_span.
Після того як нативні гістограми будуть імпортовані в Prometheus, ви можете запитувати їх, використовуючи стандартні функції гістограм PromQL без необхідності статичних міток le або суфіксів _bucket:
# 1. Розрахунок затримки P99 для однієї цілі:
# Класична гістограма (потрібен суфікс _bucket):
histogram_quantile(0.99, rate(apiserver_request_duration_seconds_bucket[5m]))
# Нативна гістограма (працює безпосередньо з назвою метрики):
histogram_quantile(0.99, rate(apiserver_request_duration_seconds[5m]))
# 2. Агрегація по кількох інстансах (наприклад, усі API сервери):
# Класична гістограма (потрібен sum by (le), щоб зберегти межі інтервалів):
histogram_quantile(0.99, sum by (le) (rate(apiserver_request_duration_seconds_bucket[5m])))
# Нативна гістограма (групування за le не потрібне!):
histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds[5m])))
З нативними гістограмами функції на кшталт histogram_quantile() працюють безпосередньо з динамічними експоненційними інтервалами всередині часових рядів, забезпечуючи високу точність квантилів без помилок інтерполяції статичних бакетів.
Для офіційної документації щодо запитів нативних гістограм у PromQL дивіться:
histogram_quantile documentationhistogram_fraction documentationhistogram_sum documentationhistogram_count documentationhistogram_count documentationhistogram_stddev and histogram_stdvar documentationЩоб безпечно перейти на нативні гістограми у вашій системі моніторингу, не порушуючи існуючі алерти чи дашборди, рекомендую чотирьохетапний порядок міграції:
scrape_native_histograms: true І always_scrape_classic_histograms: true, щоб обидва формати збиралися безпечно під час переходуhistogram_quantile(..._bucket...)) на запити нативних гістограм (histogram_quantile(...)), і замініть посилання на класичні серії _count та _sum на histogram_count(...) та histogram_sum(...)always_scrape_classic_histograms: false. Prometheus припинить збирати статичні часові ряди _bucket, _count та _sum, зменшуючи кількість часових рядів гістограм на 90%!Оскільки нативні гістограми подвійно експонуються, їх використання є повністю опціональним з точки зору колектора:
scrape_native_histograms: false у конфігурації завдання Prometheus. Перезапуск Kubernetes не потрібен, і Prometheus негайно відновить збір лише класичного формату без втрати даних--feature-gates=NativeHistograms=false (потребує перезапуску компоненту)Оскільки нативні гістограми наближаються до загальної доступності (GA) у майбутніх випусках Kubernetes, SIG Instrumentation продовжуватиме оцінювати готовність екосистеми, характеристики продуктивності та довгострокові плани щодо поступової відмови від статичних класичних інтревалів, коли використання нативних гістограм стане поширеним у спільноті моніторингу.
Щира подяка всім учасникам SIG Instrumentation та власникам компонентів, які співпрацювали над дизайном, реалізацією, тестуванням та оглядом нативних гістограм у Kubernetes!