Alertmanager
В данном практическом занятии познакомимся с компонентом для организации уведомлений о событиях мониторинга в системе prometheus - alertmanager.
Vagrant
Для работы будем использовать следующий Vagrantfile
:
Vagrant.configure("2") do |config|
config.vm.define "prometheus" do |c|
c.vm.box = "ubuntu/lunar64"
c.vm.hostname = "prometheus"
c.vm.network "forwarded_port", guest: 8888, host: 8888
c.vm.network "forwarded_port", guest: 8889, host: 8889
c.vm.provision "shell", inline: <<-SHELL
apt-get update -q
apt-get install -yq docker.io docker-compose-v2
usermod -a -G docker vagrant
SHELL
end
end
Данная конфигурация установит на виртуальную машину docker и docker compose, с помощью которых в дальнейшем будут развернуты остальные компоненты.
Alertmanager
Для развертывания компонентов опишем compose.yaml
файл:
name: mon
services:
prometheus:
image: prom/prometheus:v2.50.1
ports:
- 8889:9090
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- ./rules.yaml:/etc/prometheus/rules.yaml
- prometheus_data:/prometheus
alertmanager:
image: prom/alertmanager:v0.27.0
ports:
- 8888:9093
node-exporter:
image: prom/node-exporter:v1.7.0
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
volumes:
prometheus_data: {}
Данная конфигурация развернет контейнеры prometheus, node-exporter
и alertmanager.
Также нам понадобится конфигурация prometheus.yml
, в которой мы опишем
получение метрик с node-exporter и подключение алертинга к alertmanager.
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 1m
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
rule_files:
- rules.yaml
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
А также необходим файл с правилами, по которым будут формироваться события -
rules.yaml
:
groups:
- name: example
rules:
- alert: HighFilesystemUsage
expr: node_filesystem_avail_bytes{mountpoint="/"}/node_filesystem_size_bytes < 0.6
for: 1m
labels:
severity: warn
annotations:
summary: Filesystem Usage
После чего запустим docker compose
:
$ docker compose up -d
[+] Running 3/3
✔ Container mon-prometheus-1 Started 0.8s
✔ Container mon-node-exporter-1 Started 0.9s
✔ Container mon-alertmanager-1 Started 0.9s
Нам станут доступны prometheus по адресу localhost:8889 и alertmanager по адресу localhost:8888. На странице status можно увидеть, что prometheus подключен к alertmanager:
А на странице rules наши правила:
Сам же alertmanager сейчас не содержит алертов:
Trigger Alert
Возьмем метрику, для которой мы описали правило - node_filesystem_avail_bytes
Смотреть метрики можно также через http api:
$ curl -s localhost:8889/api/v1/query --data-urlencode 'query=node_filesystem_avail_bytes{mountpoint="/"}/2^30' | jq -c '.data.result[] | [.metric,.value[1]]'
[{"device":"/dev/sda1","fstype":"ext4","instance":"node-exporter:9100","job":"node","mountpoint":"/"},"35.24398422241211"]
Посмотрим на размер корневой файловой системы и заполним его таким образом, чтобы сработало правило алертинга:
$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 39G 3.5G 36G 9% /
$ dd if=/dev/zero of=big_file status=progress bs=1M count=20000
20908605440 bytes (21 GB, 19 GiB) copied, 24 s, 871 MB/s
20000+0 records in
20000+0 records out
20971520000 bytes (21 GB, 20 GiB) copied, 24.0671 s, 871 MB/s
$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 39G 23G 16G 60% /
Убедимся, что в мониторинге отразилось новое значение:
Через некоторое время на странице alerts можно будет
увидеть алерт в состоянии Pending
:
В данное состояние он переходит после попадание под выражение в нашем правиле, а
спустя время, указанное в параметре for
, алерт перейдет в состояние Firing
:
После чего окажется в alertmanager:
Теперь можно удалить файл:
$ rm big_file
После чего спустя некоторое время алерт пропадет:
Route Alert
На текущий момент alertmanager не сконфигурирован для отправки уведомлений ко внешним
получателям. Alertmanager позволяет настроить правила маршрутизации событий к разным
потребителям на основе их атрибутов, а также позволяет задать получателя по-умолчанию.
Зададим конфигурацию с отправкой событий в telegram бота в файле alertmanager.yml
:
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 1m
repeat_interval: 24h
receiver: telegram
receivers:
- name: telegram
telegram_configs:
- bot_token: <token>
chat_id: <chat_id>
Для получения bot_token
можно обратиться к @BotFather,
чтобы создать нового бота или получить токен существующего. А для получения
chat_id
можно написать сообщение боту и сделать запрос из терминала:
$ token=<токен бота>
$ curl https://api.telegram.org/bot${token}/getUpdates
Где в ответе в поле id
будет искомое значение.
После задания конфигурации обновим compose.yaml
:
name: mon
services:
prometheus:
image: prom/prometheus:v2.50.1
ports:
- 8889:9090
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- ./rules.yaml:/etc/prometheus/rules.yaml
- prometheus_data:/prometheus
alertmanager:
image: prom/alertmanager:v0.27.0
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
ports:
- 8888:9093
node-exporter:
image: prom/node-exporter:v1.7.0
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
volumes:
prometheus_data: {}
И перезапустим:
$ docker compose up -d
[+] Running 3/3
✔ Container mon-prometheus-1 Running 0.0s
✔ Container mon-alertmanager-1 Started 0.9s
✔ Container mon-node-exporter-1 Running 0.0s
Попробуем снова спровоцировать алерт:
$ dd if=/dev/zero of=big_file status=progress bs=1M count=20000
20248002560 bytes (20 GB, 19 GiB) copied, 22 s, 920 MB/s
20000+0 records in
20000+0 records out
20971520000 bytes (21 GB, 20 GiB) copied, 22.7681 s, 921 MB/s
Спустя некоторое время в наш бот придет уведомление:
После чего мы можем очистить место и увидеть сообщение о разрешении алерта:
$ rm big_file
Inhibit Alert
На текущий момент наш алерт оповещает нас о нехватке места на файловой системе
с уровнем критичности(severity) - warn
(warning), чтобы мы по возможности обратили на
это внимание. Добавим также правило с критичностью crit
(critical), когда нам
точно необходимо совершить какие-либо действия для устранения проблемы. Для этого
допишем файл rules.yaml
:
groups:
- name: example
rules:
- alert: HighFilesystemUsage
expr: node_filesystem_avail_bytes{mountpoint="/"}/node_filesystem_size_bytes < 0.6
for: 1m
labels:
severity: warn
annotations:
summary: Filesystem Usage
- alert: HighFilesystemUsage
expr: node_filesystem_avail_bytes{mountpoint="/"}/node_filesystem_size_bytes < 0.3
for: 1m
labels:
severity: crit
annotations:
summary: Filesystem Usage
И перезапустим:
$ docker compose up -d --force-recreate
[+] Running 3/3
✔ Container mon-prometheus-1 Started 1.1s
✔ Container mon-alertmanager-1 Started 1.1s
✔ Container mon-node-exporter-1 Started 1.1s
После чего запишем файл еще большего размера, чтобы на файловой системе было мене 30% свободного места:
$ dd if=/dev/zero of=big_file status=progress bs=1M count=30000
30915166208 bytes (31 GB, 29 GiB) copied, 33 s, 937 MB/s
30000+0 records in
30000+0 records out
31457280000 bytes (31 GB, 29 GiB) copied, 33.5849 s, 937 MB/s
Спустя некоторое время придет сообщение от бота:
Как видно в сообщении мы получили сразу два алерта crit
и warn
, так как текущее
состояние метрики подходит под оба правила. Для того, чтобы подавить отправку событий
важности warn
, когда у нас есть события более высокой важности crit
можно
воспользоваться inhibition_rules
в конфигурации alertmanager.
Очистим место на файловой системе и дождемся очистки алертов:
$ rm big_file
$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 39G 3.5G 36G 9% /
После чего добавим в конфигурацию alertmanager.yml
:
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 1m
repeat_interval: 24h
receiver: telegram
inhibit_rules:
- source_matchers: [severity="crit"]
target_matchers: [severity="warn"]
equal: [alertname]
receivers:
- name: telegram
telegram_configs:
- bot_token: 5930109659:AAHcdB9urrAyJOqxoZxIs1qhlNJXu25vsPs
chat_id: 184542544
Перезапустим контейнеры и загрузим файловую систему:
$ curl -s localhost:8889/api/v1/query --data-urlencode 'query=ALERTS'
{"status":"success","data":{"resultType":"vector","result":[]}}
$ docker compose up -d --force-recreate
[+] Running 3/3
✔ Container mon-prometheus-1 Started 1.1s
✔ Container mon-alertmanager-1 Started 1.0s
✔ Container mon-node-exporter-1 Started 1.0s
$ dd if=/dev/zero of=big_file status=progress bs=1M count=30000
31136415744 bytes (31 GB, 29 GiB) copied, 35 s, 890 MB/s
30000+0 records in
30000+0 records out
31457280000 bytes (31 GB, 29 GiB) copied, 35.366 s, 889 MB/s
Через некоторое время получим сообщение от бота:
Теперь мы получили только один алерт важности crit
, который подавил генерацию
события важности warn
.
После чего можем опять очистить файловую систему:
$ rm big_file
Silence Alert
Если в какие-то моменты необходимо временно отключить получение алертов, например
при плановом обслуживании, то можно воспользоваться механизмом
silences, где нажав New Silence
можно создать
правило, под которое попадают алерты и временно их отключить:
Заполним данные, чтобы заглушить алерты важности crit
:
И снова заполним файловую систему:
$ dd if=/dev/zero of=big_file status=progress bs=1M count=30000
30835474432 bytes (31 GB, 29 GiB) copied, 33 s, 934 MB/s
30000+0 records in
30000+0 records out
31457280000 bytes (31 GB, 29 GiB) copied, 33.6948 s, 934 MB/s
Теперь мы не получим уведомления, а спустя некоторое время можем увидеть
в интерфейсе alertmanager наши алерты в inhibited
и silenced
состояниях: