PROM 02: Подключение системного экспортера

Описание:

Всем привет! Продолжаем знакомиться с Prometheus.

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

Уровни мониторинга или что требуется мониторить в инфраструктуре.

Общая схема работы - как Prometheus собирает метрики с сервисов и приложений.

Настроить получение метрик с операционной системы Linux.

Если продолжить наш кейс c работой в компании, то после первого шага и установки самой системы мониторинга вам требуется подключить к ней все операционные системы, сервисы и приложения, которые у вас есть. В вашей компании есть Linux хосты, на которых крутятся веб-серверы, серверы баз данных, кеширующие Redis сервисы, а так же сами приложения, которые обрабатывают запросы пользователей. И вам требуется начать собирать с них данные, чтобы в будущем вы могли проводить анализ возникающих проблем или настраивать оповещения по смс в случае возникновения аварий.

Конкретно в этом задании мы будем настраивать сбор метрик с операционной системы Linux. В задании вам потребуется повторить наш опыт, дополнив его некоторыми параметрами.

Уровни мониторинга

Но перед тем, как мы начнем обсуждать сбор метрик, нам необходимо понять, какие узлы нашей инфраструктуры мы можем мониторить. Я бы выделил 3 уровня мониторинга:

Системный уровень. На этом уровне мы мониторим все операционные системы, жесткие диски, сетевое оборудование и так далее.

Сервисный уровень. На этом уровне мониторятся все сервисы, которые запускаются в системе и которые написаны не вами (то есть это не ваши приложения). В этот уровень входят: базы данных, веб-серверы, оркестраторы, docker и так далее.

Уровень приложения. На этом уровне мониторятся самописные приложения. Об этом уровне детально поговорим в следующем уроке.

Best Practice: В вашей инфраструктуре точно нужно мониторить абсолютно ВСЕ компоненты - операционные системы, сетевые железки (если они у вас есть), сервисы баз данных, веб-серверы, а также собственные приложения, написанные вашими разработчиками. С каждой системы также нужно собирать МАКСИМАЛЬНОЕ количество данных, которые они могут выдать. Зачем это нужно? В основном для разбора будущих инцидентов - когда произойдут какие-то сбои вам потребуются эти данные, чтобы разобраться с причиной проблемы. Поэтому запомните - собирать надо максимальное количество данных с абсолютно всех компонентов системы, включая даже внешние сервисы, которые вы используете.

Общая схема работы

Давайте вспомним, как выглядит архитектура системы мониторинга Prometheus:

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

Вся суть работы экспортеров сводится к следующему:

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

Экспортер подключается к системе, которую он должен мониторить - например к Redis серверу или к PostgreSQL базе, - и собирает с них все доступные метрики.

Prometheus подключается к экспортеру на порт, который был задан при запуске, и получает все метрики в текстовом формате.

Prometheus сохраняет полученные данные в локальную базу данных (TSDB).

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

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

Получение метрик с операционной системы Linux

Вообще настройка экспортера происходит в несколько этапов:

Скачать архив с экспортером.

Изучить его опции для запуска.

Запустить экспортер и проверить его работоспособность.

Подключить экспортер к Prometheus, чтобы он начал собирать с него данные.

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

1. Скачивание архива с экспортером

Перед тем, как что-то скачивать, нам это что-то необходимо найти. В случае с Prometheus экспортеры можно найти либо через google, либо посмотрев на страницу с основными экспортерами на официальном сайте Prometheus - List of exporters. Через некоторое время работы с Prometheus вы будете знать, какие экспортеры использовать для основных приложений. Для мониторинга операционных систем существует node_exporter - официальный экспортер от команды prometheus.

Итак, давайте попробуем установить node exporter и начать собирать системные метрики:

root@node1:/tmp# cd /opt/
root@node1:/opt# wget https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-amd64.tar.gz
root@node1:/opt# tar zxf node_exporter-1.1.2.linux-amd64.tar.gz
root@node1:/opt# mv node_exporter-1.1.2.linux-amd64 node_exporter

Внутри данной директории находятся три файла:

root@node1:/opt# ls -la node_exporter
total 18756
drwxr-xr-x 2 3434 3434 4096 Mar 5 09:41 .
drwxr-xr-x 7 root root 4096 Apr 7 14:30 ..
-rw-r--r-- 1 3434 3434 11357 Mar 5 09:41 LICENSE
-rw-r--r-- 1 3434 3434 463 Mar 5 09:41 NOTICE
-rwxr-xr-x 1 3434 3434 19178528 Mar 5 09:29 node_exporter
root@node1:/opt#

LICENSE и NOTICE - текстовые файлы с информацией о лицензии и комментариях о работе. node_exporter - бинарный файл нашего экспортера, который мы и будем запускать.

2. Опции запуска

При запуске можно не указывать никаких особых параметров, тогда node_exporter будет слушать порт по умолчанию - 9100, на котором и можно будет получить нужные нам метрики.

node_exporter устроен таким образом, что за каждую часть метрик отвечает собственный коллектор, и вы можете включать или отключать их при старте. К примеру, есть коллектор cpu, который собирает метрики связанные с процессором. Или коллектор filesystem, который собирает информацию о файловых системах.

Список коллекторов - это индивидуальная черта node_exporter, в других экспортерах таких опций может не быть.

Список всех коллекторов можно найти на официальной страничке в GitHub'е. А используя параметры запуска, вы можете включать или отключать разные коллекторы:

root@node1:/opt/node_exporter# ./node_exporter --help 2>&1 | grep collector
... skipped ...
--collector.bcache Enable the bcache collector (default: enabled).
--collector.bonding Enable the bonding collector (default:
--collector.btrfs Enable the btrfs collector (default: enabled).
--collector.buddyinfo Enable the buddyinfo collector (default:
--collector.conntrack Enable the conntrack collector (default:
--collector.cpu Enable the cpu collector (default: enabled).
--collector.cpufreq Enable the cpufreq collector (default:
--collector.diskstats Enable the diskstats collector (default:
--collector.drbd Enable the drbd collector (default: disabled).
--collector.edac Enable the edac collector (default: enabled).
--collector.entropy Enable the entropy collector (default:
--collector.fibrechannel Enable the fibrechannel collector (default:
--collector.filefd Enable the filefd collector (default: enabled).
--collector.filesystem Enable the filesystem collector (default:

... skipped ...

Помимо выбора коллекторов, которые будут отдавать нам разные метрики, мы можем указать следующие параметры для запуска:

--web.listen-address=":9100" - адрес и порт, на котором node_exporter будет ждать входящих подключений;

--web.telemetry-path="/metrics" - URL, по которому будут доступны наши метрики;

--web.max-requests - максимальное количество одновременных запросов на получение метрик на порт, указанный в первом параметре;

--web.config="" - экспериментальная опция, которой можно передать путь к конфигурации web.config, в которой можно задать настройки TLS.

3. Запуск экспортера

Как и в случае с самим Prometheus, node_exporter можно запустить просто из командной строки:

root@node1:/opt/node_exporter# ./node_exporter

level=info ts=2021-04-07T14:31:26.243Z caller=node_exporter.go:178 msg="Starting node_exporter" version="(version=1.1.2, branch=HEAD, revision=b597c1244d7bef49e6f3359c87a56dd7707f6719)"
level=info ts=2021-04-07T14:31:26.244Z caller=node_exporter.go:179 msg="Build context" build_context="(go=go1.15.8, user=root@f07de8ca602a, date=20210305-09:29:10)" level=warn ts=2021-04-07T14:31:26.248Z caller=node_exporter.go:181 msg="Node Exporter is running as root user. This exporter is designed to run as unpriviledged user, root is not
required."
level=info ts=2021-04-07T14:31:26.250Z caller=filesystem_common.go:74 collector=filesystem msg="Parsed flag --collector.filesystem.ignored-mount-points" flag=^/(dev|proc|sys|var/
lib/docker/.+)($|/)
level=info ts=2021-04-07T14:31:26.251Z caller=filesystem_common.go:76 collector=filesystem msg="Parsed flag --collector.filesystem.ignored-fs-types" flag=^(autofs|binfmt_misc|bpf
|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$
level=info ts=2021-04-07T14:31:26.251Z caller=node_exporter.go:106 msg="Enabled collectors"
level=info ts=2021-04-07T14:31:26.251Z caller=node_exporter.go:113 collector=arp
level=info ts=2021-04-07T14:31:26.252Z caller=node_exporter.go:113 collector=bcache
level=info ts=2021-04-07T14:31:26.252Z caller=node_exporter.go:113 collector=bonding
level=info ts=2021-04-07T14:31:26.252Z caller=node_exporter.go:113 collector=btrfs
level=info ts=2021-04-07T14:31:26.253Z caller=node_exporter.go:113 collector=conntrack
level=info ts=2021-04-07T14:31:26.253Z caller=node_exporter.go:113 collector=cpu
level=info ts=2021-04-07T14:31:26.253Z caller=node_exporter.go:113 collector=cpufreq
level=info ts=2021-04-07T14:31:26.253Z caller=node_exporter.go:113 collector=diskstats

... skipped ...

Для удобства вы также можете создать конфигурационный файл systemd для запуска node_exporter через него:

[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=root
Group=root
Type=simple
ExecStart=/opt/node_exporter/node_exporter

[Install]
WantedBy=multi-user.target

BEST PRACTICE: Официальная документация НЕ рекомендует запускать node_exporter в докере, поскольку ему требуется доступ к host системе для получения всех метрик. И вам потребуется монтировать все файловые системы внутрь докер контейнера. Поэтому намного проще запустить его как сервис из примера выше.

Итак, давайте проверим, что наш экспортер работает, и посмотрим, какие метрики он отдает. Для этого подключимся к нему напрямую, как это бы сделал Prometheus:

root@node1:~# curl localhost:9100/metrics

... skipped ...

# HELP node_disk_read_bytes_total The total number of bytes read successfully.
# TYPE node_disk_read_bytes_total counter
node_disk_read_bytes_total{device="vda"} 2.5544758784e+10
# HELP node_disk_read_time_seconds_total The total number of seconds spent by all reads.
# TYPE node_disk_read_time_seconds_total counter
node_disk_read_time_seconds_total{device="vda"} 978.74
# HELP node_disk_reads_completed_total The total number of reads completed successfully.
# TYPE node_disk_reads_completed_total counter
node_disk_reads_completed_total{device="vda"} 657414

... skipped ...

Отлично! Экспортер отдал нам метрики, которые он собрал. Например, можно посмотреть на метрику node_disk_read_bytes_total, которая, судя по названию, показывает количество прочитанных байт с диска. Или же можно обратить внимание на метрику node_disk_reads_completed_total, которая показывает количество чтений с диска.

3.1 Формат метрик

Давайте разберемся с форматом метрики:

metric_name{tag1="key1", tag2="key2"} X

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

Теги могут использоваться для фильтрации метрик в самом Prometheus. К примеру, вы можете добавить тег {env="dev"} для одной метрики и тег {env="prod"} для другой метрики и в будущем фильтровать ваши показатели по dev / prod окружениям. Добавить собственные метрики можно в конфигурационном файле Prometheus - к этому мы перейдем чуть позже. Через пробел после первой части идет X - это текущее значение нашей метрики. Например, количество выполненных команд или количество свободной памяти.

Итак, теперь вы видите и понимаете, как выглядят метрики в формате Prometheus: это простая строка с названием метрики, тегами и текущим значением.

4. Подключения экспортера к Prometheus

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

global:
scrape_interval: 15s

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

- job_name: 'node'
scrape_interval: 5s
static_configs:
- targets: ['localhost:9100']

Наш конфигурационный файл состоит из нескольких секций. В нашем примере первая секция - global, в которой мы задаем глобальные параметры. Мы указали scrape_interval, который задает период опроса экспортеров Prometheus'ом. Во второй секции scrape_configs мы указываем цели, которые необходимо опрашивать.

В нашем случае есть две задачи - Prometheus и node. На самом деле задачи - это всего лишь логическое разделение экспортеров внутри Prometheus. Именно в данной секции задаются настройки автоматического поиска целей или же их статическое описание. В нашем примере мы вручную указываем адрес и порт экспортера, который нужно мониторить:

job_name: prometheus - здесь указан адрес localhost:9090, за который отвечает Prometheus сервер. По сути Prometheus собирает метрики сам с себя.

job_name: node - а здесь указан наш недавно установленный экспортер node_exporter, который слушает порт 9100 - этот блок мы добавили только что. Так же прошу обратить внимание, что мы переопределили параметр scrape_interval для задачи node, и собирать с них метрики Prometheus будет каждые 5 секунд.

Итак, давайте попробуем перезапустить Prometheus и посмотреть на результат:

root@node1:~# systemctl restart prometheus
root@node1:~# ./promtool query instant http://localhost:9090 up

up{instance="localhost:9090", job="prometheus"} => 1 @[1617970111.787]
up{instance="localhost:9100", job="node"} => 1 @[1617970111.787]

Тут мы использовали утилиту promtool: попросили ее подключиться к серверу Prometheus на localhost:9090 и показать нам метрику с именем up - это встроенная метрика для отображения статуса настроенных экспортеров. Мы видим метрику up и ее теги - instance, которые отвечают за адрес самого экспортера, и имя задачи job, которое мы указывали в настройках Prometheus. В конце выводится последнее значение данной метрики и время, когда оно было получено. 1 означает, что экспортер доступен, 0 - что недоступен.

Как мы видим наша задача node с адресом localhost:9100 имеет значение 1 - что означает, что Prometheus успешно подключился к экспортеру и начал собирать с него данные.

4.2 Использование PromQL для получения метрик

Как мы уже говорили ранее, вы можете также фильтровать ваши метрики, используя теги. Сделать это очень просто:

root@node1:~# ./promtool query instant http://localhost:9090 'up{job="node"}'
up{instance="localhost:9100", job="node"} => 1 @[1617970210.143]

Мы просто указываем в фигурных скобках тег и его значение, которое мы хотим получить и Prometheus отдает нам метрики, которые содержат нужный нам тег. В данном случае - job="node". По сути мы сейчас пишем запросы на PromQL - это его базовые функции. Более подробно о нем мы поговорим в следующих заданиях. Итак, давайте возьмем какую-нибудь метрику с node_exporter'а и посмотрим, как она отображается в Prometheus. Пусть это будет, к примеру, node_disk_written_bytes_total:

root@node1:~# ./promtool query instant http://localhost:9090 'node_disk_written_bytes_total'
node_disk_written_bytes_total{device="vda", instance="localhost:9100", job="node"} => 52323148800 @[1617970275.39]

Смотрите! Наша метрика успешно отобразилась. Последнее ее значение - 52323148800.

Обратите внимание на теги. Когда Prometheus забирает метрики с экспортера он добавляет свои внутренние теги - instance (адрес экспортера) и job (указанный в конфигурации). И уже после этого финальная метрика записывается в TSDB.

Давайте попробуем к нашим метрикам добавить тег env, который мы обсуждали ранее. Для этого нам придется отредактировать нашу конфигурацию:

global:
scrape_interval: 15s

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

- job_name: 'node'
scrape_interval: 5s
static_configs:
- targets: ['localhost:9100']
labels:
env: 'dev'

В данном случае мы добавляем тег env равный dev для экспортера, доступного по адресу localhost:9100. Давайте теперь проверим, что наш тег был успешно добавлен:

root@node1:~# ./promtool query instant http://localhost:9090 'node_disk_written_bytes_total'
node_disk_written_bytes_total{device="vda", env="dev", instance="localhost:9100", job="node"} => 52338947072 @[1617970356.777]
node_disk_written_bytes_total{device="vda", instance="localhost:9100", job="node"} => 52332880896 @[1617970356.777]

Как видно из вывода у нас стало две метрики с различными тегами. В первой метрике добавился тег env="dev", во второй метрике данный тег отсутствует. На самом деле вторая метрика - это старая метрика, которую Prometheus получил до переконфигурации. Но он ее не удалил, поскольку срок ее хранения еще не истек. А истечет он через 15 дней, и тогда данная метрика будет удалена. Для Prometheus эти две метрики являются разными, поскольку у них разные теги. Но мы можем вывести только новую метрику, указав тег env:

root@node1:~# ./promtool query instant http://localhost:9090 'node_disk_written_bytes_total{env="dev"}'
node_disk_written_bytes_total{device="vda", env="dev", instance="localhost:9100", job="node"} => 52344873984 @[1617970388.042]

Кстати, вы также можете вывести исторические данные, указав интересующий вас промежуток в квадратных скобках:

root@node1:~# ./promtool query instant http://localhost:9090 'node_disk_written_bytes_total{env="dev"}[1m]'
node_disk_written_bytes_total{device="vda", env="dev", instance="localhost:9100", job="node"} =>
52334302208 @[1617970341.863]
52335244288 @[1617970346.863]
52338947072 @[1617970351.863]
52339631104 @[1617970356.863]
52340298752 @[1617970361.863]
52340917248 @[1617970366.863]
52341429248 @[1617970371.863]
52342309888 @[1617970376.863]
52344099840 @[1617970381.863]
52344873984 @[1617970386.863]
52345299968 @[1617970391.863]
52345926656 @[1617970396.863]

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

Итоги

Итак, давайте резюмировать.

В нашей инфраструктуре запущено множество различных сервисов - операционные системы, базы данных, собственные приложения. Для сбора метрик с операционных систем существует экспортер node_exporter.

После старта, node_exporter начинает собирать данные с операционной системы, используя виртуальные системы /proc, /sys . Также экспортер начинает слушать указанный порт, на котором он будет ждать подключения Prometheus.

В конфигурации Prometheus мы указываем адрес экспортера, по которому можно будет забрать метрики.

Prometheus подключается к экспортеру каждые несколько секунд (которые указаны в scrape_interval) и получает все метрики, которые отдает экспортер.

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

После этого довольный пользователь может запросить нужные метрики через утилиту promtool или веб-интерфейс Prometheus.

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

Prometheus Static Configs

Prometheus first Steps

List of exporters

Задание:

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

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

Установите Prometheus:

1.1. Все файлы сервера Prometheus (включая шаблоны, библиотеки, бинарники и promtool) должны находиться в директории /opt/prometheus.

1.2. Prometheus должен быть запущен на стандартном порту 9090.

1.3. База данных Prometheus должна находиться в директории /var/lib/prometheus/data.

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

1.5. Prometheus сервис должен запускаться из-под отдельного пользователя monitoring.

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

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

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

2.3. Для node_exporter должен быть включен коллектор interrupts, который выдает расширенную информацию по прерываниям.

2.4. node_exporter должен запускаться из-под пользователя monitoring

Настройте Prometheus:

3.1. Prometheus должен собирать все метрики c экспортера node_exporter.