Установка и настройка системы мониторинга Monit

Monit — это легковесная система мониторинга серверов, имеющая открытый исходный код. Monit устанавливается на сервер и обеспечивает возможность отправки уведомлений в случае обнаружения проблем. Кроме того, Monit может автономно выполнять определенное действие в качестве реакции на заданные события.


Monit имеет следующий функционал:

  • Отслеживание состояния серверов (доступность, потребление ресурсов).
  • Мониторинг демонов (состояние, потребляемые ресурсы, количество child-process и многое другое).
  • Мониторинг сетевых сервисов (возможность подключения и корректность ответа).
  • Выполнение встроенных или собственных (с помощью скриптов) действий при достижении определенных событий.
  • Отправка уведомлений на Email или в централизованный сервис M\Monit.
  • Поддерживаются ОС GNU\Linux, FreeBSD, OpenBSD, NetBSD, Solaris, Mac OS X, AIX.
  • M\Monit — это коммерческая надстройка над Monit, средство централизованного мониторинга, с помощью которого можно отслеживать состояние нескольких серверов с одного графического интерфейса.

    Установка и базовая настройка.

    Исходные данные: Debian 8.9 Jessie (amd64)

    Установка:

    apt-get install monit

    К сожалению в репозитарии Debian 8.9 Jessie находится довольно старая версия Monit (v5.9), а на официальном сайте уже давно есть v5.23, поэтому если Вы хотите использовать самую свежую версию, то придется её устанавливать из репозитария sid или скачать и установить с официального сайта.

    Я предпочитаю скачивать с официального сайта, а для упрощения обновления написал небольшой скрипт на shell (monit-upgrade.sh):

    wget https://raw.githubusercontent.com/CHERTS/linux-scripts/master/monit/monit-upgrade.sh
    chmod a+x monit-upgrade.sh
    

    Скрипт автоматически определит текущую установленную у Вас версию Monit, а так же последнюю свежую версию на официальном сайте. Если Вам хочется установить не самую последнюю версию или откатиться на предыдущую, то в скрипте необходимо убрать комментарий у строк:
    monit_latest_ver — задает версию monit, которую будем скачивать;
    monit_platform — задает платформу ОС (linux-x64 или linux-x86);

    Логика скрипт довольно простая, помимо всевозможных проверок на текущую версию linux-дистрибутива, наличие программ wget и tar, скрипт так же проверяет текущую установленную у Вас версию Monit, далее он проверяет последнюю свежую версию на официальном сайте и скачивает её, далее распаковывает архив в /tmp, останавливает monit, копирует бинарник новой версии и запускает monit.

    Далее запускаем скрипт:

    ./monit-upgrade.sh

    Вывод процесса обновления:

    # ./monit-upgrade.sh
    Downloading new monit version (v5.24.0)... Done
    Checking archive size... Done
    Unpacking archive... Done
    Stoping current monit... Done
    Delete older version monit... Done
    Copy the new version of monit... Done
    Starting new monit... Done
    

    И проверяем обновленную версию monit:

    # monit -V
    This is Monit version 5.24.0
    Built with ssl, with ipv6, with compression, with pam and with large files
    Copyright (C) 2001-2017 Tildeslash Ltd. All Rights Reserved.
    

    Теперь у нас есть самая свежая версия monit и можно приступить к его настройке.

    Все настройки Monit находятся в файле /etc/monit/monitrc, а так же в каталоге /etc/monit/conf.d

    Рассмотрим файл /etc/monit/monitrc и основные настройки которые устанавливаю я на своих серверах:

    Подробнее о каждом параметре можно и нужно почитать на официальной странице.

    # Интервал проверки сервисов (каждые 2 минуты)
    set daemon 60
    # Лог-файл, файл не очищается автоматически, поэтому нужно
    # обеспечить его ротацию через logrotate.
    # Так же можно отправлять логи на syslog-сервер
    set log /var/log/monit.log
    # Файл с уникальным идентификатором вашего monit
    set idfile /var/lib/monit/id
    # Файл для хранения статуса проверки сервисов, необходим при
    # рестарте для возобновления проверки с последнего места
    set statefile /var/lib/monit/state
    # Настройки почтового сервера через который monit будет отправлять оповещения
    set mailserver localhost
        with timeout 15 seconds
    # Параметр, определяющий размер очереди оповещений.
    # Если почтовый сервер вдруг будет недоступен, то в этот каталог
    # будут складываться оповещения, как только почтовый сервер вновь
    # будет доступен эти оповещения будут доставлены получателям.
    set eventqueue 
        basedir /var/lib/monit/events
        slots 100
    # Формат отправляемых оповещений, он достаточно хорошо кастомизируется
    # под свои нужны. Подробнее можно почитать в документации.
    # У себя я выставляю нужное поле reply-to, from и subject чтобы по теме
    # сообщения было сразу понятно что за сервис дал сбой.
    # У меня тема будет выглядеть так: programs74.ru-ping ICMP failed at Fri, 29 Sep 2017 11:38:51
    set mail-format {
       from: Server <[email protected]>;
       reply-to: [email protected]
       subject: $SERVICE $EVENT at $DATE
    }
    # На какой адрес будем отправлять оповещения.
    # Параметр поддерживает множество дополнительных настроек, к примеру можно
    # отправлять определенные типы оповещений на определенные адреса, что довольно
    # удобно в случае разделения полномочий между сотрудниками.
    # Например:
    # set alert [email protected] { timeout, resource, icmp, connection }
    # set alert [email protected] on { checksum, permission, uid, gid }
    # set alert [email protected]
    # Таким образом:
    # все события смены состояния соединений, изменения ресурсов (к примеру loadavg,
    # memory usage, cpu usage), пропадание ping (например: if failed icmp type echo)
    # или изменения статуса соединения с сервисами (например: 
    # if failed port 53 use type udp protocol dns) будут отправлены в отдел ИТ
    # на [email protected]
    # все события смены контрольных сумм, прав доступа, владельца файлов на сервере
    # мы отправляем отдел безопасности на [email protected]
    # все остальные события отправляем на [email protected]
    # У меня все события отправляются на 1 адрес.
    set alert [email protected]
    # Настройки встроенного web-интерфейса, через который можно посмотреть
    # состояние сервисов. Web-интерфейс Monit достаточно простой, но информативный.
    # Для небольшой компании с небольшим количеством серверов заходить на каждый сервер
    # для визуального контроля будет удобно, но когда количество серверов с monit
    # более 5 лучше приобрести платный коллектор событий M/Monit, помимо удобного
    # сбора, консолидации и анализа событий со всех серверов monit он так же обладает
    # дополнительными удобными механизмами оповещения на email и jabber.
    # Для минимальной работы без https достаточно таких опций:
    # set httpd port 2812
    #     allow username:password
    # У меня настройки чуть сложнее, я включаю https, а так же устанавливаю
    # ограничения на подключение к monit только с определенных ip адресов и
    # только под определенным логином и паролем.
    # Так же я привязал monit к определенному интерфейсу сервера, см. use address
    # Обратите внимание на allow XX.XX.XX.XX, вы должны обязательно разрешить
    # соединятся с monit с адреса из use address XX.XX.XX.XX, иначе при попытке
    # вывести статус сервисов командой monit status Вы получите ошибку.
    # Так же обратите внимание на строку allow monit:XXXXX в ней вместо XXXXX необходимо
    # придумать и указать пароль для пользователя monit, если это не сделать, то
    # при попытке вывести статус сервисов консольной командой monit status Вы получите
    # ошибку "You are not authorized to access monit"
    # Обратите внимание на параметр with ssl, в нем мы указываем параметры ssl-сертификата
    # и шифров, чуть ниже я приведу пример скрипта на bash для создания самоподписного
    # ssl-сертификата monit.pem
    set httpd port 2812 and
       ssl enable
       with ssl {
            pemfile: /etc/monit/ssl/monit.pem
            ciphers: "ALL:!DES:!3DES:!RC4:!aNULL:!LOW:!EXP:!IDEA:!MD5:@STRENGTH"
       }
       use address XX.XX.XX.XX
       allow ZZZ.ZZZ.ZZZ.ZZZ/24
       allow XX.XX.XX.XX
       allow YY.YY.YY.YY
       allow localhost
       allow monit:XXXXX
       allow @monitadmin
    # Глобальные настройки проверки ssl соединений:
    # 1. Обязательная проверка SSL сертификатов на всех ssl соединениях;
    # 2. Разрешаем самоподписные ssl-сертификаты (по умолчанию это запрещено);
    # Если вдруг нам захочется проверить какой-то удаленный сервис без
    # обязательной проверки ssl-сертификата, то это можно сделать указав
    # опцию {verify: disable}, подробнее об этом написано в документации.
    set ssl options {
        verify: enable
        selfsigned: allow
    }
    # Каталог для подключения дополнительных файлов конфигурации monit
    include /etc/monit/conf.d/*
    

    В настройках monit выше мы указали доступ к Web-интерфейсу для локальной группы monitadmin на нашем сервере, создадим эту группу:

    addgroup monitadmin

    И добавляем в неё пользователя cherts:

    usermod -a -G monitadmin cherts

    Так же нам необходимо создать самоподписной ssl-сертификат, для упрощения этой задачи я написал простой bash-скрипт, скачиваем его, редактируем и запускаем:

    mkdir -p /etc/monit/ssl
    wget https://raw.githubusercontent.com/CHERTS/linux-scripts/master/monit/ssl/monit-create-ssl.sh -O /etc/monit/ssl/monit-create-ssl.sh
    wget https://raw.githubusercontent.com/CHERTS/linux-scripts/master/monit/ssl/monit.cnf -O /etc/monit/ssl/monit.cnf
    chmod a+x /etc/monit/ssl/monit-create-ssl.sh
    

    Теперь отредактируйте в файле /etc/monit/ssl/monit-create-ssl.sh параметры:

    cert_cn="127.0.0.1"
    cert_o="MyCompany Ltd."
    cert_l="Moscow"
    cert_c="RU"
    

    И запустите скрипт:

    /etc/monit/ssl/monit-create-ssl.sh

    В ответ он сгенерирует самоподписной ssl-сертификат и выдаст его содержимое для проверки.

    Теперь можно проверить синтаксис monit командой:

    monit -t

    И перезапустить monit:

    /etc/init.d/monit restart

    Теперь локальный linux пользователь cherts сможет авторизоваться в Web-интерфейсе monit по адресу из опции use address на порт 2812: https://XX.XX.XX.XX:2812

    Пример страницы мониторинга сервера:

    Теперь давайте рассмотрим файлы конфигурации из каталога /etc/monit/conf.d

    Я рассмотрю несколько файлов для мониторинга сервера, а остальные файлы я выложил в своем репозитарий на GitHub.

    Файл /etc/monit/conf.d/server для мониторинга основных параметров сервера:

    # Мониторинг нашего сервера mycompany.ru
    check system mycompany.ru
        group system
        group server
        if loadavg (1min) > 4 then alert
        if loadavg (5min) > 2 then alert
        if memory usage > 75% then alert
        if swap usage > 25% then alert
        if cpu usage (user) > 70% then alert
        if cpu usage (system) > 30% then alert
        if cpu usage (wait) > 20% then alert
    
    # Проверяем параметры корневой ФС
    check device rootfs with path /
        group system
        group server
        if failed permission 755 then alert
        if space usage > 90% for 5 times within 10 cycles then alert
        if space usage > 99% then stop
        if inode usage > 30% for 5 times within 10 cycles then alert
        if inode usage > 50% then stop
    
    # Проверяем параметры ФС /var
    check device varfs with path /var
        group system
        group server
        if failed permission 0755 then alert
        if space usage > 90% for 5 times within 10 cycles then alert
        if space usage > 99% then stop
        if inode usage > 30% for 5 times within 10 cycles then alert
        if inode usage > 50% then stop
    

    В разделе check system мы проверяем основные параметры системы.
    Загрузку системы loadavg за 1 минуту — loadavg (1min) и за 5 минут — loadavg (5min)
    Использование памяти — memory usage
    Использование свопа — swap usage
    Использование процессора — cpu usage (user)(system)(wait)

    Более детально о них можно почитать на странице официальной документации.

    Рассмотрим общий принцип написания условий проверки:

    IF <test> THEN <action> [ELSE IF SUCCEEDED THEN <action>]

    В данном случае если условие будет истина (TRUE), то будет выполнено действие
    Действие при ELSE IF SUCCEEDED THEN является не обязательным, если оно не указано, то при смене условия на FALSE буде отправлено уведомление.

    Например простое условие:

    if space usage > 90% then alert

    В данном случае, если параметр space usage (использование диска) превысит 90% то будет отправлено оповещение на почту. В этом условии — это alert.
    В monit доступно несколько видов (действий):
    ALERT — отправка оповещения на почту при смене состояния условия;
    RESTART — перезапуск сервиса, для этого должны быть указаны опции start program и stop program и отправка оповещения на почту;
    START — запуск сервиса, для этого должны быть указана опция start program и отправка оповещения на почту;
    STOP — остановка сервиса, для этого должны быть указана опция stop program и отправка оповещения на почту;
    EXEC — выполнение внешней программы и отправка оповещения на почту;
    UNMONITOR — остановка мониторинга сервиса (в дальнейшем он не будет проверяться) и отправка оповещения на почту;

    Зачастую первая проверка условия может вызвать ошибку и для правильной интерпритации состояния нужно сделать несколько подходов по проверки, для этих целей в monit есть конструкция FOR CYCLES …

    Пример FOR CYCLES:

    if space usage > 90% for 2 cycles then alert

    Таким образом проверка условия if space usage > 90% будет выполнена 2 раз и если условие будет подтверждено все 2 раза подряд то будет отправлено оповещение.

    Но и тут есть тонкость, если условие будет срабатывать в такой последовательности 1-0-1-0-1-0-…, то оповещение никогда не будет отправлено. На этот случай нужно использовать конструкцию:
    [TIMES WITHIN] CYCLES …

    Данная конструкция и используется у нас:

    if space usage > 90% for 5 times within 10 cycles then alert

    В 2-ух разделах check device мы проверяем параметры примонтированных файловых систем:
    Права на права на ФС — failed permission 0755
    Использование дискового пространства — space usage
    Использование inode — inode usage

    Более детально о них можно почитать на странице официальной документации. принцип написания условий проверки у них такой же как и для check system.

    Так же параметрами group system и group server мы сгруппировали 3 раздела в 2 группы.
    Использование групп — это очень удобная функция monit, о ней мы поговорим позже когда будем работать с просмотром результатов мониторинга из консоли.

    Рассмотрим файл /etc/monit/conf.d/mysql для мониторинга работы БД MySQL:

    check process mysqld with pidfile /var/run/mysqld/mysqld.pid
       group database
       group mysql
       start program = "/etc/init.d/mysql start"
       stop  program = "/etc/init.d/mysql stop"
       if failed host localhost port 3306 protocol mysql with timeout 15 seconds for 3 times within 4 cycles then restart
       if failed unixsocket /var/run/mysqld/mysqld.sock protocol mysql for 3 times within 4 cycles then restart
       if 5 restarts with 5 cycles then unmonitor
       depend mysql_bin
       depend mysql_rc
    
    check file mysql_bin with path /usr/sbin/mysqld
       group mysql
       include /etc/monit/templates/rootbin
    
    check file mysql_rc with path /etc/init.d/mysql
       group mysql
       include /etc/monit/templates/rootbin
    

    Здесь мы используем возможность Monit осуществлять мониторинг процессов и файлов.

    Здесь мы будем проверять процесс mysqld по PID файлу /var/run/mysqld/mysqld.pid
    Так же определим опции start program и stop program для запуска и остановки MySQL.
    Определим условия проверки через подключение к tcp порту 3306 на localhost — if failed host localhost port 3306 protocol mysql with… и через подключение к unix сокету — if failed unixsocket /var/run/mysqld/mysqld.sock protocol mysql…, если произошла ошибка подключения, то выполним перезапуск сервиса mysqld.
    Так же определим условие перехода мониторинга сервиса в режим unmonitor
    Далее check file мы проверяем файлы с помощью стандартного набора условий из /etc/monit/templates/rootbin
    Опции depend mysql_bin и depend mysql_rc указывают, что monit перед каждым действием start, stop, monitoring и unmonitoring будет выполнять проверки check file mysql_bin и check file mysql_rc, в случае провала этих проверок основная проверка check process будет приостановлена.

    Мы рассмотрели пример конфигурации для мониторинга 2-х сервисов, но этим работа с monit не ограничивается, в своем репозитарии я подготовил готовые наборы для мониторинга сервисов asterisk, clamav, dovecot, fail2ban, memcached, bind, nginx, ntpd, openfire, openssh и других.

    Теперь давайте рассмотрим работу с monit из командной строки.

    Я перечислю основные команды, которые могут быть полезны на начальном этапе освоения monit, с остальными можно познакомиться из документации.

    Проверка конфигурации monit:

    monit -t

    или

    /etc/init.d/monit syntax

    Перезагрузка конфигурации monit:

    monit reload

    или

    /etc/init.d/monit reload

    Перезапуск monit:

    /etc/init.d/monit restart

    Просмотр состояния всех сервисов на мониторинге:

    monit status

    Просмотр состояния сервисов в группе system:

    monit -g system status

    Просмотр состояния отдельного сервиса mysqld:

    monit status mysqld

    Пример вывода состояния сервиса:

    # monit status mysqld
    Monit 5.24.0 uptime: 6h 9m
    
    Process 'mysqld'
      status                       OK
      monitoring status            Monitored
      monitoring mode              active
      on reboot                    start
      pid                          7481
      parent pid                   6516
      uid                          112
      effective uid                112
      gid                          120
      uptime                       26d 2h 31m
      threads                      47
      children                     0
      cpu                          0.5%
      cpu total                    0.5%
      memory                       8.3% [1.3 GB]
      memory total                 8.3% [1.3 GB]
      disk read                    0 B/s [1.4 TB total]
      disk write                   0 B/s [915.5 GB total]
      port response time           0.934 ms to localhost:3306 type TCP/IP protocol MYSQL
      unix socket response time    0.479 ms to /var/run/mysqld/mysqld.sock type TCP protocol MYSQL
      data collected               Fri, 29 Sep 2017 23:37:53
    

    Включить мониторинг сервиса mysqld:

    monit monitor mysqld

    Посмотреть краткую информацию о состоянии всех сервисов:

    monit summary

    Посмотреть краткую информацию о состоянии сервиса mysqld:

    monit summary mysqld

    Посмотреть краткую информацию о состоянии в группе system:

    monit -g system summary

    И в заключении статьи я хочу написать несколько предостережений по работе с monit:

    1. Если Вы обновляете какой-либо сервис который находится на мониторинге в monit или хотите перезапустить этот сервис, например Вы обновляете БД mysql, элементарно выполнив apt-get upgrade, или хотите перезапустить mysql командой /etc/init.d/mysql restart, то обязательно останавливайте мониторинг этого сервиса командой:

    monit unmonitor mysqld

    и обязательно дождитесь перехода этого сервиса в состояние «Not monitored» и только после этого приступайте к обновлению или перезапуску сервиса.

    Пример снятия с мониторинга сервиса mysqld:

    # monit unmonitor mysqld

    Проверяем состояние:

    # monit summary mysqld
    Monit 5.24.0 uptime: 6h 25m
    ┌─────────────────────────────────┬────────────────────────────┬───────────────┐
    │ Service Name                    │ Status                     │ Type          │
    ├─────────────────────────────────┼────────────────────────────┼───────────────┤
    │ mysqld                          │ OK - unmonitor pending     │ Process       │
    └─────────────────────────────────┴────────────────────────────┴───────────────┘
    

    Видим, что состояние unmonitor pending, ждем несколько секунд…

    Повторно проверяем состояние:

    # monit summary mysqld
    Monit 5.24.0 uptime: 6h 27m
    ┌─────────────────────────────────┬────────────────────────────┬───────────────┐
    │ Service Name                    │ Status                     │ Type          │
    ├─────────────────────────────────┼────────────────────────────┼───────────────┤
    │ mysqld                          │ Not monitored              │ Process       │
    └─────────────────────────────────┴────────────────────────────┴───────────────┘
    

    Видим что сервис mysqld снят с мониторинга, теперь можно приступить к обновлению БД или её перезапуску.

    Вы спросите: Зачем такие сложности?
    Ответ: При использовании конструкций вида:

    ...
       start program = "/etc/init.d/mysql start"
       stop  program = "/etc/init.d/mysql stop"
       if failed host localhost port 3306 protocol mysql with timeout 15 seconds for 3 times within 4 cycles then restart
    ...
    

    Мы осуществляем мониторинг сервиса путем тестового подключения к нему, если через заданное количество попыток подключение провалиться, то мы осуществляем перезапуск сервиса. А теперь представьте, что проверка настигнет Вас в момент когда БД будет в процессе перезапуска, что будет тогда? Ничего хорошего. Monit не сможет подключиться к БД и попробует её перезапустить.

    2. Если вы используете конструкции вида

    ...
       start program = "/etc/init.d/mysql start"
       stop  program = "/etc/init.d/mysql stop"
       if failed host localhost port 3306 protocol mysql with timeout 15 seconds for 3 times within 4 cycles then restart
    ...
    

    то есть вы доверяете Monit перезапуск сервисов, то обратите внимание на время которое требуется для остановки и запуска вашего сервиса.

    По умолчанию monit ждет 30 сек. чтобы остановить сервис и потом запустить его, эти лимиты указаны тут. Если у Вас большая база данных или высоконагруженный проект на nginx, то Вы можете попросту не уложиться в эти 30 секунд, поэтому имеет смысл увеличить эти лимиты, например так:

    ...
       start program = "/etc/init.d/mysql start" with timeout 120 seconds
       stop  program = "/etc/init.d/mysql stop" with timeout 60 seconds
       if failed host localhost port 3306 protocol mysql with timeout 15 seconds for 3 times within 4 cycles then restart
    ...
    

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


    4
    Оставить комментарий

    avatar
    1000
    4 Цепочка комментария
    0 Ответы по цепочке
    0 Последователи
     
    Популярнейший комментарий
    Цепочка актуального комментария
    2 Авторы комментариев
    Михаилpetrozavodsky Авторы недавних комментариев

    Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

      Подписаться  
    Уведомление о
    petrozavodsky
    Гость

    Подробно объяснено спасибо в свое время долго искал эту инфу

    petrozavodsky
    Гость

    А можно ссылочку на коллектор ? На сколько он платный и что умеет, никак не нагуглю он нем достаточно информации

    petrozavodsky
    Гость

    Если быть точным хочу прикрутить отправку оповещений в месенджеры