Когда Prometheus один, вопросов почти нет. Когда их пять, по одному на кластер, хочется видеть общую картину, но тянуть все сырые метрики в один сервер дорого и бессмысленно. Федерация решает эту задачу: глобальный Prometheus периодически забирает у локальных только нужные серии. Разберём настройку без лишней кардинальности.

Две модели: федерация и remote write

Федерация работает по pull-модели: глобальный сервер сам обращается к эндпоинту /federate каждого локального Prometheus и получает срез метрик в текстовом формате. Remote write работает наоборот: локальный сервер отправляет поток samples в удалённое хранилище. Первый вариант проще в изолированных сетях и не требует открывать приёмник, второй лучше подходит для полного архива и больших объёмов.

Практическое правило: федерация для агрегатов и дежурных панелей, remote write или специализированное хранилище для долгого хранения и детального разбора.

Что именно отдаёт /federate

Эндпоинт принимает один или несколько параметров match[] с селекторами PromQL и возвращает текущие значения подходящих серий. Это не произвольный запрос: функции, агрегация и сортировка там не работают. Поэтому все вычисления нужно делать заранее через recording rules, а федерация лишь забирает готовые ряды.

curl -s 'http://prom-cluster-a:9090/federate?match[]={__name__=~"job:.*"}' | head
curl -s 'http://prom-cluster-a:9090/federate?match[]=up&match[]=node_load1' | head

Если не передать ни одного match[], сервер вернёт ошибку 400. Это защита от случайной выгрузки всей базы.

Подготовка источника: external_labels

Каждый локальный Prometheus должен помечать свои данные именем кластера. Это делается через external_labels в глобальном блоке. Метка добавляется ко всем сериям и помогает потом группировать панели и алерты.

global:
  scrape_interval: 30s
  external_labels:
    cluster: eu-west-1
    environment: production

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

Не путайте external_labels с метками job и instance: первые описывают сам сервер, вторые — цель опроса. Если у вас несколько окружений, добавьте и environment. Тогда один и тот же job в разных кластерах не смешается в графиках.

Recording rules для агрегатов

Федерация хороша тогда, когда отдаёт десятки серий, а не сотни тысяч. Создайте правила, которые считают rate, сумму и квантили на месте, и федерайте только результат.

groups:
  - name: federation-aggregates
    interval: 30s
    rules:
      - record: job:http_requests:rate5m
        expr: sum by (job, cluster) (rate(http_requests_total[5m]))
      - record: job:http_request_duration:p95
        expr: histogram_quantile(0.95,
              sum by (le, job, cluster) (rate(http_request_duration_seconds_bucket[5m])))

Проверьте правила через promtool check rules и убедитесь, что ряды действительно появились в локальном Prometheus. Если выражение возвращает пустоту, федерация тоже ничего не получит, и глобальный сервер будет выглядеть здоровым, но пустым.

Настройка глобального Prometheus

На принимающей стороне достаточно обычного scrape_config с metrics_path /federate и списком match[]. Значение honor_labels: true критично: без него конфликтующая метка cluster превратится в exported_cluster, и разделение по кластерам станет неудобным.

scrape_configs:
  - job_name: federation
    honor_labels: true
    metrics_path: /federate
    scrape_interval: 30s
    scrape_timeout: 20s
    params:
      match[]:
        - '{__name__=~"job:.*"}'
        - '{__name__="up"}'
    static_configs:
      - targets:
          - prom-cluster-a:9090
          - prom-cluster-b:9090
        labels:
          tier: edge

Метка tier из static_configs добавится к сериям, но при honor_labels: true конфликт с меткой источника решится в пользу источника. Это ожидаемое поведение: именно так сохраняются cluster и environment. Если метку нужно перезаписать, выставьте honor_labels: false.

Сколько данных и как не утонуть

Федерация одного и того же набора серий с десяти кластеров умножает кардинальность на десять. Поэтому не федерайте сырые node_* и http_* без необходимости. Начните с малого: up, правила уровня job, несколько ключевых бизнес-метрик. Дальше расширяйте осознанно.

Ограничители защищают сервер:

  • sample_limit обрывает сбор при превышении числа samples;
  • metric_relabel_configs выбрасывает лишние метки;
  • cluster и instance нужны для навигации, их лучше сохранить;
  • высококардинальные метки вроде request_id стоит убрать.
    sample_limit: 50000
    metric_relabel_configs:
      - source_labels: [__name__]
        regex: 'go_.*'
        action: drop

Помните, что federation забирает текущий срез, а не историю. Если локальный сервер недоступен в момент опроса, в глобальном будет разрыв, а up покажет 0. Для дежурства этого достаточно, для аудита — нет.

Проверка и диагностика

Сначала проверьте конфигурацию и перезагрузите сервис. Затем посмотрите на страницу /targets: цель federation должна быть в состоянии UP, а в деталях видно число собранных samples. Если цель DOWN, читайте ошибку в том же интерфейсе и в журнале systemd.

promtool check config /etc/prometheus/prometheus.yml
curl -X POST http://localhost:9090/-/reload
systemctl status prometheus --no-pager
journalctl -u prometheus -n 50 --no-pager

Для проверки данных выполните в глобальном Prometheus запрос count by (cluster) (up{job=»federation»}). Если кластеров меньше, чем ожидалось, ищите расхождение в метках. Пустой результат при рабочей цели чаще всего означает неверный match[] или отсутствие recording rules на источнике.

Ещё одна частая причина — рассинхронизация времени. Prometheus отбрасывает samples, которые слишком сильно отличаются от текущего времени, поэтому на всех узлах должен работать chrony или systemd-timesyncd. Проверьте offset через chronyc tracking и сравните часы на источнике и приёмнике.

Безопасность федерации

Эндпоинт /federate не имеет встроенной авторизации на уровне путей, поэтому не публикуйте Prometheus в интернет. Правильный вариант — отдельная сеть мониторинга, firewall и TLS. Начиная с версии 2.24 Prometheus умеет читать web.config.file с basic auth и TLS, что закрывает вопрос для межкластерной связи.

tls_server_config:
  cert_file: /etc/prometheus/server.crt
  key_file: /etc/prometheus/server.key

basic_auth_users:
  federation: $2y$10$replace_with_bcrypt_hash

Пароль в конфиге источника задаётся в scrape_config через basic_auth или bearer_token_file. Храните его в файле с правами 600 и не коммитьте в git. Если кластеры в разных сетях, настройте маршрутизацию и правила firewall, а не полагайтесь на «сложный» URL.

Итог

Федерация Prometheus — это обмен агрегатами, а не копия всей базы. Пометьте кластеры через external_labels, посчитайте нужные ряды recording rules, включите honor_labels на приёмнике и ограничьте объём через match[] и sample_limit. Проверяйте цель на /targets, следите за временем и не выставляйте Prometheus в интернет. Тогда несколько кластеров действительно помещаются в одно окно.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте