Prometheus + Grafana + Alertmanager в Docker

Обновлено Обновлено: Опубликовано Опубликовано:

Используемые термины: PrometheusGrafanaDocker.

В данной инструкции мы рассмотрим пример docker-compose файла для организации системы мониторинга на базе Prometheus. Мы получим:

  • Базу данных Prometheus и интерфейс для выполнения PromQL.
  • Визуализацию с помощью Grafana.
  • Сбор метрик через Node Exporter.
  • Мониторинг HTTP с использованием Blackbox.
  • Отправку уведомлений в Telegram с помощью Alertmanager.

Мы будем работать в среде Linux, хотя полученный файл docker-compose можно применять где угодно. Останавливаться подробно на описании docker-compose мы не будем.

Подготовка системы

Выполним предварительные действия.

Настройка среды для docker

Подразумевается, что у нас установлен Docker и docker-compose, в противном случае, можно воспользоваться инструкцией Установка Docker на Linux.

Создаем каталоги, где будем создавать наши файлы:

mkdir -p /opt/prometheus_stack/{prometheus,grafana,alertmanager,blackbox}

Создаем файл:

touch /opt/prometheus_stack/docker-compose.yml

Переходим в каталог prometheus_stack:

cd /opt/prometheus_stack

Дальше будем работать относительно него.

Prometheus + Node Exporter

Открываем файл:

vi docker-compose.yml

services:

  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus/etc:/etc/prometheus/
      - ./prometheus/data:/prometheus
    container_name: prometheus
    hostname: prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
    ports:
      - 9090:9090
    restart: unless-stopped
    environment:
      TZ: "Europe/Moscow"

  node-exporter:
    image: prom/node-exporter
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    container_name: exporter
    hostname: exporter
    command:
      - --path.procfs=/host/proc
      - --path.sysfs=/host/sys
      - --collector.filesystem.ignored-mount-points
      - ^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)
    ports:
      - 9100:9100
    restart: unless-stopped
    environment:
      TZ: "Europe/Moscow"

* в данном примере мы создаем 2 сервиса — prometheus и node-exporter.

Создаем конфигурационный файл для prometheus:

mkdir -p ./prometheus/etc

vi prometheus/prometheus.yml

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

* в данном примере мы прописываем наш node-exporter в качестве таргета.

Заранее создаем каталог с данными и назначаем ему владельца:

mkdir -p ./prometheus/data

chown 65534:65534 ./prometheus/data

Запускаем контейнеры:

docker-compose up -d

Ждем несколько секунд и можно пробовать подключиться. Открываем браузер и переходим по адресу http://<IP-адрес сервера>:9090 — мы должны увидеть страницу Prometheus:

Стартовая страница Prometheus

Переходим по адресу http://<IP-адрес сервера>:9100 — мы должны увидеть страницу Node Exporter:

Веб-сбраница Node Exporter

Мы движемся в правильном направлении. Идем дальше.

Grafana

Добавим к нашему стеку графану.

Открываем файл:

vi docker-compose.yml

Добавляем:

services:
  ...

  grafana:
    image: grafana/grafana
    user: root
    depends_on:
      - prometheus
    ports:
      - 3000:3000
    volumes:
      - ./grafana:/var/lib/grafana
      - ./grafana/provisioning/:/etc/grafana/provisioning/
    container_name: grafana
    hostname: grafana
    restart: unless-stopped
    environment:
      TZ: "Europe/Moscow"

* по аналогии с другими сервисами, мы добавили сервис для графаны.

Перезапустим контейнеры:

docker-compose up -d

Открываем браузер и переходим по адресу http://<IP-адрес сервера>:3000 — мы должны увидеть стартовую страницу Grafana.

Для авторизации вводим admin / admin. После система потребует ввести новый пароль.

Настроим связку с Prometheus. Кликаем по иконке Configuration - Data Sources:

Переходим к добавлению источника данных в Grafana

Переходим к добавлению источника, нажав по Add data source:

Добавляем источник данных в Grafana

Среди списка источников данных находим и выбираем Prometheus, кликнув по Select:

Выбираем Prometheus как источник данных

Задаем параметры для подключения к Prometheus:

Прописываем параметры для подключения к Prometheus

Сохраняем настройки, кликнув по Save & Test:

Сохраняем настройки в Grafana

Добавим дашборд для мониторинга с node exporter. Для этого уже есть готовый вариант.

Кликаем по изображению плюса и выбираем Import:

Переходим к импорту дашборда в графане

Вводим идентификатор дашборда. Для Node Exporter это 1860:

Вводим идентификатор для установки дашборда под node exporter

Кликаем Load — Grafana подгрузит дашборд из своего репозитория — выбираем в разделе Prometheus наш источник данных и кликаем по Import:

Выбираем источник данных для импортируемого дашборда

Мы увидим страницу с настроенными показателями метрик. Можно пользоваться.

Настройка оповещений с AlertManager

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

Для начала подготовим наш бот телеграм. Создадим нового — для этого открываем телеграм и ищем @my_id_bot:

Ищем @my_id_bot в телеграме

Приложение покажет наш идентификатор. Записываем — он нам потребуется позже.

Теперь создаем бота. Ищем @BotFather:

Ищем @BotFather в телеграме

Переходим в чат с найденным BotFather и запускаем бота:

Запускаем BotFather

Создаем бота, последовательно введя команду /newbot и отвечая на запросы мастера:

Создание нового бота в BotFather

* в нашем примере мы создаем бота prometheus_alert с именем учетной записи DmoskPrometheusBot.

Переходим в чат с созданным ботом, кликнув по его названию:

Отображаем список своих телеграм ботов

Запускаем бота:

Стартуем созданного бота

Попробуйте протестировать отправку из командной строки. Для этого нужно сделать запрос типа GET с синтаксисом:

https://api.telegram.org/bot<BotID>/sendMessage?chat_id=<ChannelName>\&text=<Text>

Проще всего, для этого использовать утилиту командной строки curl. Пример команды:

curl 'https://api.telegram.org/bot1234567890:ABCDEFGHIYKLMNOPI8e48SeTHIGfzD8W4E/sendMessage?chat_id=@dmosk_ru\&text=test'

* обратите внимание, что токен передается в формате 'bot' + <token>.

Проверяем сообщение в телеграм канале — мы должны увидеть наше тестовое сообщение.

С ботом мы закончили. Переходим к docker.

Открываем наш файл docker-compose:

vi docker-compose.yml

И добавляем:

services:
  ...

  alertmanager:
    image: prom/alertmanager:v0.31.1
    user: root

    ports:
      - 127.0.0.1:9093:9093
    volumes:
      - ./alertmanager/:/etc/alertmanager/
    container_name: alertmanager
    hostname: alertmanager

    environment:
      TZ: "Europe/Moscow"
    restart: unless-stopped

    command:
      - '--config.file=/etc/alertmanager/config.yml'
      - '--storage.path=/etc/alertmanager/data'

* мы добавили сервис alertmanager (система оповещений в prometheus). Актуальную версию можно посмотреть на странице docker hub.

Теперь открываем конфигурационный файл для prometheus:

vi prometheus/prometheus.yml

И добавим строки:

...

rule_files:
  - 'alert.rules'

alerting:
  alertmanagers:
  - scheme: http
    static_configs:
    - targets:
      - "alertmanager:9093"

* в данном примере мы указали, что наш сервер мониторинга должен использовать в качестве системы оповещения alertmanager, который доступен по адресу alertmanager:9093. Также мы добавили файл alert.rules с описанием правил оповещения.

Создаем файл с правилами оповещения:

vi prometheus/alert.rules

groups: 
- name: InstanceState
  rules:
  - alert: PrometheusTargetMissing
    expr: up == 0
    for: 0m
    labels:
      severity: critical
    annotations:
      summary: "Prometheus target missing (instance {{ $labels.instance }})"
      description: "A Prometheus target has disappeared. An exporter might be crashed. VALUE = {{ $value }}  LABELS: {{ $labels }}"

* в данном примере мы добавили правило, которое будет срабатывать при недоступности узла (node-exporter).

Переходим к конфигурированию alertmanager:

vi alertmanager/config.yml

route:
  receiver: 'telegram-notifications'

receivers:
- name: 'telegram-notifications'
  telegram_configs:
  - bot_token: '1234567890:ABCDEFGHIYKLMNOPI8e48SeTHIGfzD8W4E'
    chat_id: -102030405060708090
    parse_mode: 'HTML'

* данная конфигурация позволяет отправлять оповещения в телеграм. Указываем:

  • bot_token — токен бота.
  • chat_id — идентификатор чата, группы или канала.

Перезапустим все сервисы docker:

docker-compose down && docker-compose up -d

Открываем браузер и переходим по адресу http://<IP-адрес сервера>:9090 — на вкладке Alerts мы должны увидеть нашу настройку:

Настроенное правило alertmanager

Попробуем проверить работу оповещения. Отключаем наш node exporter:

docker stop exporter

На телеграм должно прийти оповещение:

Оповещение на телеграм бота

Отправка уведомлений настроена.

Blackbox exporter

Переходим к настройке мониторинга http сервисов. В нашем примере мы будем проверять работу сайта dmosk.ru.

Открываем наш файл docker-compose:

vi docker-compose.yml

Добавим в него:

services:
  ...

  blackbox:
    image: prom/blackbox-exporter
    container_name: blackbox
    hostname: blackbox
    ports:
      - 9115:9115
    restart: unless-stopped
    command:
      - "--config.file=/etc/blackbox/blackbox.yml"
    volumes:
      - ./blackbox:/etc/blackbox
    environment:
      TZ: "Europe/Moscow"

* сервис blackbox является компонентом Prometheus для мониторинга сетевых сервисов по различным протоколам.

Открываем конфигурационный файл prometheus:

vi prometheus/prometheus.yml

И дописываем:

scrape_configs:
  ...
  - job_name: 'blackbox'
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
        - https://www.dmosk.ru
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox:9115

...

* подобная конфигурация позволит создать дополнительное задание мониторинга сайта https://www.dmosk.ru.

Создаем конфигурационный файл blackbox:

vi blackbox/blackbox.yml

modules:
  http_2xx:
    prober: http
    timeout: 5s
    http:
      valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
      valid_status_codes: [200]
      method: GET
      no_follow_redirects: true
      fail_if_ssl: false
      fail_if_not_ssl: false
      fail_if_body_matches_regexp:
        - "Could not connect to database"
      fail_if_body_not_matches_regexp:
        - "Download the latest version here"
      fail_if_header_matches: # Verifies that no cookies are set
        - header: Set-Cookie
          allow_missing: true
          regexp: '.*'
      fail_if_header_not_matches:
        - header: Access-Control-Allow-Origin
          regexp: '(\*|example\.com)'
      tls_config:
        insecure_skip_verify: false
      preferred_ip_protocol: "ip4"
      ip_protocol_fallback: false

* во многом, данный пример взят с официальной страницы на Github.

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

vi prometheus/alert.rules

Добавим:

  ...

  - alert: BlackboxSlowProbe
    expr: avg_over_time(probe_duration_seconds[1m]) > 5
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: Blackbox slow probe (instance {{ $labels.instance }})
      description: "Blackbox probe took more than 1s to complete\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"

  - alert: BlackboxProbeHttpFailure
    expr: probe_http_status_code <= 199 OR probe_http_status_code >= 400
    for: 0m
    labels:
      severity: critical
    annotations:
      summary: Blackbox probe HTTP failure (instance {{ $labels.instance }})
      description: "HTTP status code is not 200-399\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"

* в данном примере мы создали два правила:

  • BlackboxSlowProbe — предупреждать, если сайт открывается дольше 5 секунд.
  • BlackboxProbeHttpFailure — реагировать, в случае получения кода ответа с ошибкой работы сайта (более 400).

Запускаем добавленный в докер сервис:

docker-compose up -d

Для визуализации мониторинга с помощью blackbox есть готовый дашборд в графане. Снова открываем страницу импорта:

Переходим к импорту дашборда в графане

Вводим идентификатор 7587 и выбираем источник (как делали при добавлении дашборда node exporter).

Обратный прокси Caddy

Для удобства работы мы можем добавить контейнер в веб-сервером Caddy для обратного проксирования.

Открываем файл docker-compose:

vi docker-compose.yml

И дописываем:

services:
  ...
 
  caddy:
    image: caddy:latest
    hostname: caddy
    container_name: caddy
    restart: unless-stopped
    environment:
      TZ: "Europe/Moscow"
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./caddy/data:/data
      - ./caddy/ssl:/etc/caddy/ssl

Создаем конфигурационный файл:

mkdir -p caddy

vi caddy/Caddyfile

prometheus.dmosk.ru {
    reverse_proxy prometheus:9090
}

grafana.dmosk.ru {
    reverse_proxy grafana:3000
}

* в данном варианте подразумевается, что у нас настроен внешний домен. При запуске caddy запросит сертификаты для доменов prometheus.dmosk.ru и grafana.dmosk.ru.

Запускаем добавленный в докер сервис:

docker-compose up -d

# DevOps # Grafana # Linux # Prometheus # Контейнеризация # Мониторинг # Серверы
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет

Дмитрий Моск
— IT-специалист.
Настройка серверов, услуги DevOps.

Заказать настройку мониторинга

Нужна бесплатная консультация?

Мини-инструкции

Использование header_checks для замены заголовков в Postfix

Как установить и выполнить базовую настройку ноды для Ethereum под Linux Ubuntu

Как настроить отказоустойчивого кластер из двух серверов KeyDB

Мониторинг под ключ с docker — Prometheus + Grafana + Alertmanager

Как с помощью Gradle и плагина ospackage собрать пакеты RPM и Deb

Создание снапшотов на ZFS с их просмотром на шаре Samba

Примеры работы с Gitlab CI/CD — написание конвейеров для автоматизации разработки

Другие инструкции

Все статьи

Нужна помощь? Пишите:






Реклама