Главная » Хабрахабр » Устройство и механизм работы Prometheus Operator в Kubernetes

Устройство и механизм работы Prometheus Operator в Kubernetes

В основу этой статьи легла наша внутренняя документация для DevOps-инженеров, объясняющая, как работает Prometheus под управлением Prometheus Operator в разворачиваемых и обслуживаемых кластерах Kubernetes.

image

Статья посвящена не столько самому Prometheus, сколько интеграции этой системы с Kubernetes, для чего мы активно используем вспомогательный инструмент под названием Prometheus Operator. С первого взгляда Prometheus может показаться достаточно сложным продуктом, но, как и любая хорошо спроектированная система, она состоит из явно выраженных функциональных компонентов и по сути делает всего три вещи: а) собирает метрики, б) выполняет правила, в) сохраняет результат в базу данных временных рядов (time series). Но начать всё же необходимо с самого Prometheus…

Prometheus: что он делает?

Итак, если подробнее остановиться на двух первых функциях Prometheus, то они работают следующим образом:

  • Для каждой цели мониторинга (target), каждый scrape_interval, выполняется HTTP-запрос к этой цели. В ответ получаются метрики в своём формате, которые сохраняются в базу.
  • Каждый evaluation_interval обрабатываются правила (rules), на основании которых:
    • или отправляются алерты,
    • или записываются (себе же в базу) новые метрики (результат выполнения правила).

Prometheus: как он настраивается?

У сервера Prometheus есть config и rule files (файлы с правилами).

В config имеются следующие секции:

Prometheus: откуда берётся список целей?

Общий алгоритм работы Prometheus выглядит следующим образом:

  1. Prometheus читает секцию конфига scrape_configs, согласно которой настраивает свой внутренний механизм обнаружения сервисов (Service Discovery).
  2. Механизм Service Discovery взаимодействует с Kubernetes API (в основном для получения endpoints).
  3. На основании данных из Kubernetes механизм Service Discovery обновляет Targets (список целей).

В scrape_configs указан список scrape job'ов (это внутреннее понятие Prometheus), каждый из которых определяется следующим образом:

scrape_configs: # Общие настройки
- job_name: kube-prometheus/custom/0 # просто название scrape job'а # показывается в разделе Service Discovery scrape_interval: 30s # как часто собирать данные scrape_timeout: 10s # таймаут на запрос metrics_path: /metrics # path, который запрашивать scheme: http # http или https # Настройки Service Discovery kubernetes_sd_configs: # означает, что targets мы получаем из Kubernetes - api_server: null # использовать адрес API-сервера из переменных # окружения (которые есть в каждом поде) role: endpoints # targets брать из endpoints namespaces: names: # искать endpoints только в этих namespaces - foo - baz # Настройки "фильтрации" (какие enpoints брать, какие — нет) и "релейблинга" # (какие лейблы добавить или удалить — для всех получаемых метрик) relabel_configs: # Фильтр по значению лейбла prometheus_custom_target, # полученного из service, связанного с endpoint - source_labels: [__meta_kubernetes_service_label_prometheus_custom_target] regex: .+ # подходит любой НЕ пустой лейбл action: keep # Фильтр по имени порта - source_labels: [__meta_kubernetes_endpoint_port_name] regex: http-metrics # подходит, если порт называется http-metrics action: keep # Добавляем лейбл job, используем значение лейбла prometheus_custom_target # у service, к которому добавляем префикс "custom-" # # Лейбл job — служебный в Prometheus. Он определяет название группы, # в которой будет показываться target на странице targets, а также он будет # у каждой метрики, полученной у этих targets (чтобы можно было удобно # фильтровать в rules и dashboards) - source_labels: [__meta_kubernetes_service_label_prometheus_custom_target] regex: (.*) target_label: job replacement: custom-$1 action: replace # Добавляем лейбл namespace - source_labels: [__meta_kubernetes_namespace] regex: (.*) target_label: namespace replacement: $1 action: replace # Добавляем лейбл service - source_labels: [__meta_kubernetes_service_name] regex: (.*) target_label: service replacement: $1 action: replace # Добавляем лейбл instance (в нём будет имя пода) - source_labels: [__meta_kubernetes_pod_name] regex: (.*) target_label: instance replacement: $1 action: replace

Таким образом, Prometheus сам отслеживает:

  • добавление и удаление подов (при добавлении/удалении подов Kubernetes изменяет endpoints, а Prometheus это видит и добавляет/удаляет цели);
  • добавление и удаление сервисов (точнее, endpoints) в указанных пространствах имён (namespaces).

Изменение конфига требуется в следующих случаях:

  • нужно добавить новый scrape config (обычно это новый вид сервисов, которые надо мониторить);
  • нужно изменить список пространств имён.

Разобравшись с основами Prometheus, перейдём к его «оператору» — специальному вспомогательному компоненту для Kubernetes, упрощающему развёртывание и эксплуатацию Prometheus в реалиях кластера.

Prometheus Operator: что он делает?

Для пресловутого «упрощения», во-первых, в Prometheus Operator с помощью механизма CRD (Custom Resource Definitions) заданы три ресурса:

  1. prometheus — определяет инсталляцию (кластер) Prometheus;
  2. servicemonitor — определяет, как мониторить набор сервисов (т.е. собирать их метрики);
  3. alertmanager — определяет кластер Alertmanager'ов (мы ими не пользуемся, поскольку отправляем метрики напрямую в свою систему уведомлений, которая принимает, агрегирует и ранжирует данные из множества источников — в том числе, интегрируется со Slack и Telegram).

Во-вторых, оператор следит за ресурсами prometheus и генерирует для каждого из них:

  1. StatefulSet (с самим Prometheus);
  2. Secret с prometheus.yaml (конфиг Prometheus) и configmaps.json (конфиг для prometheus-config-reloader).

Наконец, оператор также следит за ресурсами servicemonitor и за ConfigMaps с правилами, и на их основании обновляет конфиги prometheus.yaml и configmaps.json (они хранятся в секрете).

Что в поде с Prometheus?

Под состоит из двух контейнеров:

  1. prometheus — сам Prometheus;
  2. prometheus-config-reloader — обвязка, которая следит за изменениями prometheus.yaml и при необходимости вызывает reload конфигурации Prometheus (специальным HTTP-запросом — см. подробнее ниже), а также следит за ConfigMaps с правилами (они указаны в configmaps.json — см. подробнее ниже) и по необходимости скачивает их и перезапускает Prometheus.

Под использует три тома (volumes):

  1. config — примонтированный секрет (два файла: prometheus.yaml и configmaps.json). Подключён в оба контейнера;
  2. rulesemptyDir, который наполняет prometheus-config-reloader, а читает prometheus. Подключён в оба контейнера, но в prometheus — в режиме только для чтения;
  3. data — данные Prometheus. Подмонтирован только в prometheus.

Как обрабатываются Service Monitors?

  1. Prometheus Operator читает Service Monitors (а также следит за их добавлением/удалением/изменением). Какие именно Service Monitors — указано в самом ресурсе prometheus (подробнее см. в документации).
  2. Для каждого Service Monitor, если в нём не указан конкретный список namespaces (т.е. указано any: true), Prometheus Operator вычисляет (обращаясь к Kubernetes API) список пространств имён, в которых есть Services, подходящие под лейблы, указанные в Service Monitor.
  3. На основании прочитанных ресурсов servicemonitor (см. документацию) и на основании вычисленных пространств имён, Prometheus Operator генерирует часть конфига (секцию scrape_configs) и сохраняет конфиг в соответствующий секрет.
  4. Штатными средствами самого Kubernetes данные из секрета приходят в под (файл prometheus.yaml обновляется).
  5. Изменение файла замечает prometheus-config-reloader, который по HTTP отправляет запрос в Prometheus на перезагрузку.
  6. Prometheus перечитывает конфиг и видит изменения в scrape_configs, которые обрабатывает уже согласно своей логике работы (см. подробнее выше).

Как обрабатываются ConfigMaps с правилами?

  1. Prometheus Operator следит за ConfigMaps, подходящими под ruleSelector, указанный в ресурсе prometheus.
  2. Если появился новый (или был удален существующий) ConfigMap, Prometheus Operator обновляет prometheus.yaml, после чего срабатывает логика, в точности соответствующая обработке Service Monitors (см. выше).
  3. Как в случае добавления/удаления ConfigMap, так и при изменении содержимого ConfigMap, Prometheus Operator обновляет файл configmaps.json (в нём указан список ConfigMaps и их контрольные суммы).
  4. Штатными средствами самого Kubernetes данные из секрета приходят в под (файл configmaps.json обновляется).
  5. Изменение файла замечает prometheus-config-reloader, который скачивает изменившиеся ConfigMaps в директорию rules (это emptyDir).
  6. Тот же prometheus-config-reloader отправляет по HTTP запрос в Prometheus на перезагрузку.
  7. Prometheus перечитывает конфиг и видит изменившиеся правила.

Вот и всё!

Подробнее о том, как мы используем Prometheus (и не только) для мониторинга в Kubernetes, я планирую рассказать на конференции RootConf 2018, что будет проходить 28 и 29 мая в Москве, — приходите послушать и пообщаться.

P.S.

Читайте также в нашем блоге:


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

История активных сессий в PostgreSQL — новое расширение pgsentinel

Компания pgsentinel выпустила одноимённое расширение pgsentinel (репозиторий github), добавляющее в PostgreSQL представление pg_active_session_history — историю активных сессий (по аналогии с оракловой v$active_session_history). По сути, это просто-напросто ежесекундные снимки из pg_stat_activity, но есть важные моменты: Вся накопленная информация хранится только в ...

[Перевод] Создание мультяшного шейдера воды для веба. Часть 2

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