PROM 11: Prometheus Federation

Описание:

Всем привет!

Итак, по факту мы уже разобрали практически все, что касается prometheus - научились подключать экспортеры, собирать метрики, фильтровать их, применять различные функции, отображать их на графиках, а так же настраивать правила алертинга и нотификации. Оставшиеся четыре задачи будут скорее о дополнительных функциях prometheus - о безопасности, федерации, резервировании и работе с большими нагрузками. Сегодня мы разберемся с тем, что такое федерация, где и когда ее стоит использовать, посмотрим на правила агрегаций, а так же настроим федерацию на центральном prometheus сервере.

Если смотреть на реальный кейс, то тут лучше всего подходит пример с несколькими дата центрами. Если ваше приложение геораспределенное, то есть смысл в каждом регионе поставить свой локальный prometheus сервер, который будет собирать метрики со всех рядом стоящих сервисов. А в одном регионе поставить один центральный prometheus, который сможет собирать данные со всех локальных prometheus хостов и сохранять их в своей базе. Таким образом вы сможете анализировать метрики по всем сервисам на едином сервере.

Итак, давайте начнем наш рассказ с самого главного - что такое федерация и как она работает.

Для чего нужна федерация

Федерация - это возможность prometheus забирать метрики с другого prometheus сервера. То есть вы можете настроить сбор метрик не с какого-то экспортера, а с отдельного prometheus сервера. Это позволяет решить вам две основные задачи.

Первая - это иерархичная агрегация. К примеру, у вас есть 3 датацентра. В каждом из них установлен prometheus, который собирает данные со своего датацентра - нагрузка, использование cpu, памяти и так далее. Вы можете настроить на локальных prometheus агрегирование метрик и дальше отдавать их на центральный prometheus, который будет содержать только агрегированные данные.

Второй вариант - это кросс сервисная федерация. В реальной жизни часто бывает, что вы ставите несколько prometheus хостов, каждый из которых отвечает за свой набор метрик. Один за системные показатели - cpu / mem / etc..., второй за сервисные метрики - postgres/mysql/redis/application/.... Настроив центральный сервер, вы сможете объединять метрики, относящиеся в приложению на одном сервере.

В любом из этих вариантов по факту вы создаете единое хранилище метрик, по которому вы сможете прогонять аналитические запросы, настраивать алерты по глобальным показателям и видеть всю инфраструктуру на верхнем уровне.

Здесь же стоит оговориться и сразу указать на моменты, для чего не следует использовать федерацию. Федерацию не стоит использовать для того, чтобы собирать вообще все метрики на едином сервере и там настраивать правила алертинга. Этого не стоит делать по нескольким причинам. Первая - это нагрузка и масштабируемость. Навряд ли ваш prometheus сервер выдержит все детальные метрики со всех датацентров. Или же придется ставить очень большую и жирную машинку. Вторая причина - это надежность. Добавляя новый центральный сервер, по сути вы добавляете новую точку отказа - если раньше вы могли потерять алерты только из-за недоступности локального prometheus, то теперь вы можете потерять их из-за отказа еще и центрального сервера.

Так что лучше используйте федерацию именно для сбора агрегированных метрик или всех метрик по одному сервису. Тогда все будет работать как и задумано!

Итак, перед настройкой федерации давайте сначала разберемся с recording rules.

Создание новых метрик через recording rules

Давайте посмотрим на простой пример. Для начала настроим правила агрегации на локальном prometheus хосте. Мы не разбирали с вами правила агрегирования, но на самом деле они очень похожи на правила алертинга - они будут выполняться раз в заданный интервал и по сути генерировать новую метрику по вашему запросу. Таким образом вы сможете создавать новые метрики, которые будут храниться в prometheus.

Итак, у нас есть локальный prometheus, который собирает данные со всех узлов в датацентре через простой node_exporter. Давайте посмотрим на его конфигурацию:

global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
datacenter: dc1

rule_files:
- "rules.yml"

scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']

- job_name: 'node'
static_configs:
- targets: ['localhost:9100']

Данный пример вы наверняка видели уже много раз, но у нас добавился новый интересный параметр - external_labels - это внешние теги, которые prometheus будет добавлять всем метрикам, когда он взаимодействует с внешней системой - например когда другой prometheus будет забирать с него метрики через федерацию или когда prometheus передает алерты в alertmanager или же когда он записывает данные во внешнюю систему (разберем в следующем задании). Помимо external_labels мы указали файл с правилами - rules.yml. По сути мы уже так делали, когда добавляли правила алертинга, но сейчас мы будем добавлять правила создания новых метрик. Итак, давайте посмотрим на rules.yml:

groups:
- name: globaldc
interval: 5s
rules:
- record: job:node_memory_MemTotal_bytes:sum
expr: sum without(instance)(node_memory_MemTotal_bytes{job="node"})

В данном случае, по аналогии с правилами алертинга, мы создали группу globaldc, внутри которой задали интервал выполнения запросов - interval: 5s. То есть prometheus будет выполнять запросы из этой группы каждые 5 секунд. Далее мы определяем правила (rules). В нашем примере правила всего лишь одно. Оно будет выполнять запрос sum without(instance)(node_memory_MemTotal{job="node"}) и записывать результат выполнения в новую метрику job:node_memory_MemTotal:sum. По сути здесь мы суммируем всю используемую память со всех узлов и сохраняем ее в новую переменную. Как вы могли заметить, созданная нами метрика по виду отличается от обычных. Правила записи должны иметь общую форму: level:metric:operations, где level представляет собой уровень агрегирования, metric - это имя метрики, которое должно оставаться неизменным, а operations - это список действий, применимых к метрике; подробнее об этом вы можете прочитать в документации.

Давайте проверим нашу конфигурацию и перезапустим prometheus:

root@prom-test:/opt/prometheus# ./promtool check config ./prometheus.yml
Checking ./prometheus.yml
SUCCESS: 1 rule files found

Checking rules.yml
SUCCESS: 1 rules found

root@prom-test:/opt/prometheus# systemctl restart prometheus
root@prom-test:/opt/prometheus#

Отлично, теперь осталось проверить нашу новую метрику:

root@prom-test:/opt/prometheus# ./promtool query instant http://localhost:9090/ 'job:node_memory_MemTotal_bytes:sum'
job:node_memory_MemTotal_bytes:sum{job="node"} => 2084401152 @[1623754205.923]
root@prom-test:/opt/prometheus#

Смотрите - у нас появилась новая метрика! Давайте сравним ее с нашим promql запросом:

root@prom-test:/opt/prometheus# ./promtool query instant http://localhost:9090/ 'sum without(instance)(node_memory_MemTotal_bytes{job="node"})'
{job="node"} => 2084401152 @[1623754249.646]
job:node_memory_MemTotal_bytes:sum{job="node"} => 2084401152 @[1623754251.243]
root@prom-test:/opt/prometheus#

Как видно метрики совпадают. Собственно таким нехитрым образом вы сможете создавать новые метрики, основываясь на ваших запросах.

Теперь, когда у нас есть агрегированная метрика пришло время начать забирать ее на новый сервер.

Настройка федерации в prometheus.

Теперь все настройки мы будем производить на центральном сервере. Создадим конфигурацию для prometheus:

global:
scrape_interval: 15s
evaluation_interval: 15s

scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']

- job_name: federation
honor_labels: true
metrics_path: /federate
params:
match[]:
- '{__name__=~"^job:.*"}'
static_configs:
- targets:
- 167.172.104.138:9090

Мы добавили новую задачу - federation, у которой указали некоторые параметры. Первый - honor_labels: true - с ним мы уже сталкивались, когда настраивали pushgateway. Этот параметр заставляет prometheus сохранять исходные теги instance и job, которые ему отдаст экспортер (в нашем случае другой prometheus сервер). Второй параметр - metrics_path - он указывает по какому пути стоит забирать метрики. По умолчанию используется /metrics, но prometheus отдает все метрики через endpoint federate. Следующий параметр - это params, в котором описываются фильтры для метрик. В нашем случае мы фильтруем все метрики по специальному тегу __name__, то есть по имени метрики. И вытаскиваем все метрики, которые начинаются со слова job. Таким образом мы сможем забрать нашу агрегированную метрику, которую мы создали на первом этапе. Ну и в заключении идет static_configs, в котором мы описываем наш локальный prometheus сервер.

Итак, пробуем перезапуститься и вытащить нашу новую метрику с центрального сервера;

root@prom-central:/opt/prometheus# systemctl restart prometheus
root@prom-central:/opt/prometheus# ./promtool query instant http://localhost:9090/ 'job:node_memory_MemTotal_bytes:sum'
job:node_memory_MemTotal_bytes:sum{datacenter="dc1", job="node"} => 2084401152 @[1623755579.34]
root@prom-central:/opt/prometheus#

Супер! Все появилось - наша метрика была успешно собрана с другого prometheus сервера. Так же прошу обратить внимание, что к ней добавился новый тег datacenter=dc1, который мы указали в external_labels нашего локального prometheus сервера.

Итоги

Итак, сегодня мы с вами познакомились с очень удобной функцией prometheus - федерацией. Благодаря ей вы сможете собирать агрегированные метрики на центральном сервере и видеть общую картину всей вашей инфраструктуры на едином хосте. Кстати, grafana позволяет использовать несколько data source на одном дашбоарде. То есть вы можете опрашивать сразу несколько prometheus серверов и выводить все метрики на один график. Стоит отметить, что не стоит использовать федерацию для скачивания всех метрик со всех внешних prometheus хостов из-за причин описанных в самом начале.

В следующий раз мы поговорим про долгосрочное хранение метрик в promethues.

Полезные ссылки:

When to use federation

Prometheus Federation

Recording rules

Recording rules best practices

Задание:

В этом задании вам потребуется настроить федерацию в prometheus. Вам выдано две машины с уже установленным prometheus сервером.

Критерии оценки выполнения задания:

Установите экспортер node_exporter на prom-node1:

2.1. Исполняемый файл экспортера node_exporter должен находиться внутри отдельной директории /opt/node_exporter.

2.2. Экспортер node_exporter должен быть запущен как сервис c помощью systemd и быть описан в файле /etc/systemd/system/node_exporter.service.

Настройте Prometheus на prom-node1:

2.1. В Prometheus подключены recording rules из файла /opt/prometheus/rules.yml.

2.2. В файле /opt/prometheus/rules.yml описано простое правила job:total_avail_disk_space, которое сохраняет суммарно свободное место на диске по всем нодам (метрика node_filesystem_avail_bytes)

2.3. Prometheus добавляет внешний тег type=external для всех метрик.

Настройка Prometheus на prom-node2:

3.1. В Prometheus настроен забор метрики с prom-node1 с именем job:total_avail_disk_space