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

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

    image

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

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


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

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

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


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

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

    • scrape_configs — настройки поиска целей для мониторинга (подробнее см. в следующем разделе);
    • rule_files — список директорий, где лежат правила, которые необходимо загружать:

      rule_files:
      - /etc/prometheus/rules/rules-0/*
      - /etc/prometheus/rules/rules-1/*
    • alerting — настройки поиска Alertmanager'ов, в которые отправляются алерты. Секция очень похожа на scrape_configs с тем отличием, что результатом её работы является список endpoints, в которые Prometheus будет отправлять алерты.

    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.


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

    Флант 228,79
    Специалисты по DevOps и высоким нагрузкам в вебе
    Поделиться публикацией
    Комментарии 0

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

    Самое читаемое