PROM 06: Автоматическое обнаружение целей для мониторинга

Описание:

Всем привет!

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

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

Важные концепты Auto Discovery

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

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

Он говорил promethues о том, что ему необходимо обращаться к адресу http://localhost:9090/metrics для получения метрик с данного сервиса. Как прекрасно видно мы задавали данный параметр вручную.

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

Или же еще один пример - виртуальные машины в облаке - например, hetzner или digital ocean или amazon, или google cloud. Prometheus может обращаться к API облачных ресурсов и запрашивать все виртуальные машины, которые там запущены и после этого начать их мониторить.

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

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

Важно: Итак, давайте подведем промежуточный итог. Prometheus с помощью встроенных механизмов может автоматически обнаруживать цели для мониторинга. Для этого используемый механизм обращается к внешним ресурсам - dns, consul, облакам и запрашивает информацию о запущенных ресурсах, после чего добавляет их в цели для мониторинга. Таким образом вам не нужно будет каждый раз обновлять конфигурацию prometheus для добавления нового сервиса или виртуалки.

Best Practice: Старайтесь сразу настраивать автодискавери на своем инстансе prometheus. В жизни часто бывает ситуация, когда вы подняли новый сервис, но забыли подключить его к мониторингу. И в моменты падений становится особенно больно, потому что данные для разбора инцидента у вас отсутствуют. А при настройке auto discovery вы точно не забудете добавить новый компонент в систему мониторинга.

Давайте теперь посмотрим на основные механизмы обнаружения целей, которые уже встроены в prometheus:

azure_sd_config - получение целей для мониторинга из облака Azure.

consul_sd_config - получение целей для мониторинга из системы хранения конфигураций consul.

digitalocean_sd_config - получение целей для мониторинга из облака digital ocean.

docker_sd_config - получение целей для мониторинга из docker engine, по сути из docker socket.

dockerswarm_sd_config - получение целей для мониторинга из кластера docker swarm. Тут так же используется docker socket.

dns_sd_config - получение информации о целях из DNS.

ec2_sd_config - получение информации о целях из Amazon EC2.

openstack_sd_config - получение информации о целях из Openstack.

file_sd_config - получение информации о целях из внешнего файла.

gce_sd_config - получение информации о целях из google cloud engine.

hetzner_sd_config - получение информации о целях из hetzner cloud.

kubernetes_sd_config - получение информации о целях из Kubernetes API.

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

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

Итак, давайте посмотрим как это все работает на практике.

Автоматический поиск целей через файлы

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

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

- job_name: 'file'
file_sd_configs:
- files:
- '/opt/targets/*.json'
refresh_interval: 10s

В данном случае мы добавляем новую задачу на мониторинг file, но не указываем конкретные цели для сбора - определяем только, что prometheus будет искать все файлы с расширением .json в директории /opt/targets/ и перечитывать их раз в 10 секунд. А внутри этих файлов мы будем хранить информацию о целях для мониторинга. Давайте создадим эту директорию и перезапустим prometheus:

# mkdir -p /opt/targets/
# systemctl restart prometheus

Теперь можно посмотреть все цели для мониторинга у prometheus:

root@prometheus-test:/opt/prometheus# ./promtool query instant http://localhost:9090/ up
up{instance="localhost:9090", job="prometheus"} => 1 @[1622628739.855]
root@prometheus-test:/opt/prometheus#

Как видно - на данный момент у нас мониторится только локальный prometheus, который добавлен вручную через static_configs. Давайте попробуем создать новый файл - /opt/targets/web.json, в котором мы опишем новую цель для мониторинга:

[
{
"targets": [
"10.0.0.1:9100"
],
"labels": {
"env": "prod"
}
}
]

Мы добавили одну новую цель - 10.0.0.1:9100 с тегом env = prod. Как видно из json - вы можете добавить сразу несколько целей, а так же разные labels. Помимо json вы можете так же использовать и yaml формат. Но на самом деле проще именно json, поскольку его удобно генерировать из того же python. Таким образом вы сможете написать скрипт на python, который соберет все нужные цели, сгенерирует json и сохранит его в файл. После чего prometheus прочитает его и добавит все цели в мониторинг.

Кстати, давайте проверим, добавилась ли новая цель для мониторинга в prometheus:

root@prometheus-test:/opt/prometheus# ./promtool query instant http://localhost:9090/ up
up{env="prod", instance="10.0.0.1:9100", job="file"} => 0 @[1622629162.811]
up{instance="localhost:9090", job="prometheus"} => 1 @[1622629162.811]
root@prometheus-test:/opt/prometheus#

Как видно из вывода - у нас добавилась новая цель, которую мы записали в файл. Давайте попробуем расширить список хостов в файле и посмотреть что изменилось:

[
{
"targets": [
"10.0.0.1:9100",
"10.0.0.2:9100"
],
"labels": {
"env": "prod"
}
}
]

И проверяем prometheus:

root@prometheus-test:/opt/prometheus# ./promtool query instant http://localhost:9090/ up
up{env="prod", instance="10.0.0.1:9100", job="file"} => 0 @[1622629237.907]
up{env="prod", instance="10.0.0.2:9100", job="file"} => 0 @[1622629237.907]
up{instance="localhost:9090", job="prometheus"} => 1 @[1622629237.907]

Новый таргет так же появился в списке - отлично! Таким образом вы можете автоматизировать добавление ваших сервисов в prometheus. На этом рассказ про файлы закончим и перейдем к настройке dns based autodiscovery.

Автоматическое обнаружение целей через DNS

Итак, с файлами разобрались - переходим к DNS. На самом деле DNS является отличной штукой для обнаружения сервисов. Очень маловероятно, что имея в инфраструктуре большое количество хостов вы будете использовать IP адреса для работы с ними. Высока вероятность, что вы уже добавляете информацию о системах в DNS. Таким образом можно будет легко подключить все цели для мониторинга с его помощью.

По реализации Prometheus поддерживает обнаружение по dns с тремя типами записей - A, AAAA и SRV. Первые два достаточно просты - к примеру вы можете добавить доменное имя сайта в prometheus и он обнаружит все A / AAAA записи, которые к нему относятся - по сути все адреса web балансировщиков или непосредственно серверов приложений.

С SRV записью все немного интереснее - она позволяет указывать порт для сервиса, а так же его приоритет, вес и имя хоста, к которому нужно обращаться. Таким образом, например, вы можете добавить информацию по внутреннему API в DNS:

_api._tcp.internal-api.dev.rebrainme.com 300 IN 10 50 8080 web1.internal-api.dev.rebrainme.com
_api._tcp.internal-api.dev.rebrainme.com 300 IN 10 50 8080 web2.internal-api.dev.rebrainme.com

Давайте разберем наши SRV записи:

_api - имя сервиса

_tcp - протокол, который используется для подключения к сервису

internal-api.dev.rebrainme.com - доменное имя нашего сервиса

300 - TTL - стандартное поле DNS

IN - класс DNS - всегда IN

10 - приоритет данного сервера

50 - вес данного сервера - используется для серверов с одинаковым приоритетом

8080 - порт по которому доступен данный сервис

web1.internal-api.dev.rebrainme.com - адрес хоста к которому можно подключиться чтобы получить доступ к сервису.

Таким образом вы можете создавать SRV записи в своем DNS, которые будут описывать все ваши сервисы. А в prometheus нужно будет добавить следующую запись:

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

- job_name: 'file'
file_sd_configs:
- files:
- '/opt/targets/*.json'
refresh_interval: 10s

- job_name: 'dns'
dns_sd_configs:
- names:
- _api._tcp.internal-api.dev.rebrainme.com
type: SRV
refresh_interval: 10s

Рестартуем prometheus и проверяем результат:

root@prometheus-test:/opt/prometheus# ./promtool query instant http://localhost:9090/ up
up{env="prod", instance="10.0.0.1:9100", job="file"} => 0 @[1622632584.825]
up{env="prod", instance="10.0.0.2:9100", job="file"} => 0 @[1622632584.825]
up{instance="localhost:9090", job="prometheus"} => 1 @[1622632584.825]
up{instance="web1.internal-api.dev.rebrainme.com:8080", job="dns"} => 0 @[1622632584.825]
up{instance="web2.internal-api.dev.rebrainme.com:8080", job="dns"} => 0 @[1622632584.825]

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

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

- job_name: 'dns'
dns_sd_configs:
- names:
- rebrainme.com
type: A
port: 9090
refresh_interval: 10s

В данном случае мы определяем все IP адреса, которые принадлежат rebrainme.com и подключаемся к ним по порту 9090 для сбора метрик.

Давайте посмотрим на результат:

root@prometheus-test:/opt/prometheus# ./promtool query instant http://localhost:9090/ up
up{env="prod", instance="10.0.0.1:9100", job="file"} => 0 @[1622632749.123]
up{env="prod", instance="10.0.0.2:9100", job="file"} => 0 @[1622632749.123]
up{instance="185.206.165.150:9090", job="dns"} => 0 @[1622632749.123]

Как видно - наша последняя строка как раз относится к rebrainme.com - имя превратилось в IP адрес. Таким образом вы сможете использовать DNS для автоматического обнаружения целей.

Итоги

Итак, сегодня мы с вами разобрали одну из самых ключевых тем по Prometheus - auto discovery. В prometheus уже встроено большое количество механизмов для автоматического обнаружения. Работают они все по одному принципу - prometheus обращается к внешней системе, запрашивает у нее информацию по созданным ресурсам и добавляет их в мониторинг. По такому принципу работает обнаружение машинок в облаках, через dns и через любые другие компоненты.

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

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

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

SRV Запись

DNS SD Config

Prometheus DNS Discovery

Prometheus Kubernetes Discovery

Задание:

В этом задании вам будет необходимо настроить autodiscovery из файлов для автоматического обнаружения сервисов. На подготовленной виртуальной машине уже установлен Prometheus.

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

Prometheus должен считывать все файлы с расширением .json из директории /etc/prom-targets в задаче с именем data.

В файле /etc/prom-targets/dd.json описаны IP адреса двух целей - 192.168.0.100 и 192.168.0.200 на порту 9100. Оба адреса должны иметь тег env со значением dev.

39

5

Проверка задания

Вопросы и ответы

20.06.2023 18:30

на доработке
2

Станислав Ралько

отправлено

20.06.2023 18:30

Запущена автопроверка

Автопроверка

20.06.2023 18:30

Checking /etc/prom-targets: OK

Checking dd.json file exists: OK

Checking dd.json contains info about first target: OK

Checking dd.json contains info about second target: FAILED

Checking env label is set to dev: FAILED

Checking prometheus is configured with autodiscovery: FAILED

20.06.2023 18:31

выполнено
4

Станислав Ралько

отправлено

20.06.2023 18:31

Запущена автопроверка

Автопроверка

20.06.2023 18:31

Checking /etc/prom-targets: OK

Checking dd.json file exists: OK

Checking dd.json contains info about first target: OK

Checking dd.json contains info about second target: OK

Checking env label is set to dev: OK

Checking prometheus is configured with autodiscovery: FAILED

20.06.2023 18:34

выполнено
4

Станислав Ралько

отправлено

20.06.2023 18:34

Запущена автопроверка

Автопроверка

20.06.2023 18:34

Checking /etc/prom-targets: OK

Checking dd.json file exists: OK

Checking dd.json contains info about first target: OK

Checking dd.json contains info about second target: OK

Checking env label is set to dev: OK

Checking prometheus is configured with autodiscovery: FAILED

26.06.2023 20:09

на проверке

Автопроверка

26.06.2023 20:09

Ваше задание проверяется, это займет несколько минут

Начать выполнение

Задать вопрос куратору

Раздел в разработке

Задать вопрос

Связаться с нами

ООО Ребреин
ИНН/КПП: 7727409582/770301001
ОГРН: 1197746106161
Юридический адрес: 123056, г. Москва, муниципальный округ Пресненский вн.тер.г., ул. Большая Грузинская, д.36 А, стр.5А, офис 13

+7 499 113 35 51

[email-masked]

Политика конфиденциальности

Публичная оферта

Согласие на получение рекламных материалов

Пользовательское соглашение

Согласие на обработку персональных данных

Наши партнеры