Полный мониторинг системы при помощи Nagios 4
9 сентября 2015
Когда в системе что-то ломается или начинает вести себя необычным образом, пользователи дружно страдают. Следовательно, в этом случае нужно как можно скорее уведомить кого-нибудь о поломке. А еще лучше было бы предвидеть возникновение проблем заранее. В данной заметке будет описана установка и настройка Nagios, который позволяет вполне успешно решить такие задачи.
Инварианты
В большинстве систем есть ряд инвариантов, которые никогда не должны нарушаться. Вот некоторые примеры возможных нарушений:
- Load average на одной из машин стал больше X;
- Свободной памяти на одной из машин осталось меньше X;
- Свободного места на диске у одной из машин осталось меньше X;
- Слишком много открытых файловых дескрипторов на машине X;
- Сильно греется проц, скоро развалится диск, малый заряд UPS;
- Высокий сетевой трафик, disk io, кончается своп, ну и так далее;
- Один из хостов не пингуется или пингуется со слишком большим RTT;
- Что-то перестало резолвиться по DNS;
- Доступны более новые версии установленных пакетов;
- На одну из машин залогинилось подозрительно много юзеров;
- Есть критические ошибки в логах за последние X минут;
- Число некритичных ошибок за последние X минут превысило Y;
- Лежит или медленно отвечает PostgreSQL, Redis, RabbitMQ, …;
- SSL-сертификат скоро истекает;
- 99-ый процентиль времени ответа сервиса сильно больше обычного;
- Не ходит почта, SMS, пуши, …;
- Нужно пополнить баланс в стороннем сервисе (AWS, Logentries, …);
- Подозрительно большие расходы в стороннем сервисе;
- В тестовом окружении не удалось восстановиться из бэкапа с прода;
- Сервис стал недоступен из Зеленограда и ЮАР;
- По внутренним хелсчекам сервиса мы уперлись в один из трэдпулов;
Как видите, практически в любом сервисе можно без труда найти два десятка инвариантов, а то и больше, которые никогда не должны нарушаться, и которые довольно легко мониторить автоматически. Если что-то сломалось, начинаем рассылать письма админам, SMS начальству, звонить на телефоны кодерам.
Установка Nagios
Нас интересует новый Nagios, который версии 4. Готового deb-пакета для него почему-то нет, придется собирать все из исходных кодов. Поэтому разворачивать сервер Nagios’а имеет смысл в контейнере вроде Vagrant или Docker. Также далее подразумевается, что вы помните о необходимости ограничить доступ к серверу при помощи фаервола, шифровать HTTP-трафик, используя для этого прокси-сервер вроде Nginx, и так далее. Эти вопросы мы уже рассматривали ранее, поэтому сейчас не будет останавливаться на них снова.
Следует отметить, что в реальных условиях вам обязательно нужно как минимум два сервера с Nagios. Потому что кто-то должен мониторить мониторинг. Иначе при его падении вы не получите никаких алертов и будете думать, что все хорошо и что все работает.
Ставим Apache и PHP:
sudo a2dissite 000-default
sudo service apache2 reload
sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt
Какая-либо СУБД для работы Nagios не требуется.
Создаем пользователя и группу:
sudo groupadd nagcmd
sudo usermod -a -G nagcmd nagios
Тянем зависимости:
sudo apt-get install build-essential libgd2-xpm-dev openssl \
libssl-dev xinetd apache2-utils
Ставим последний стабильный Nagios (на момент написания поста — 4.0.8):
tar -xvzf nagios-4.0.8.tar.gz
cd nagios-4.0.8/
./configure --with-nagios-group=nagios --with-command-group=nagcmd
make all
sudo make install
sudo make install-commandmode
sudo make install-init
sudo make install-config
sudo /usr/bin/install -c -m 644 sample-config/httpd.conf \
/etc/apache2/sites-available/nagios.conf
Добавляем пользователя www-data в группу nagcmd:
Ставим последнюю стабильную версию плагинов:
wget http://nagios-plugins.org/download/nagios-plugins-2.1.1.tar.gz
tar -xvzf nagios-plugins-2.1.1.tar.gz
cd nagios-plugins-2.1.1/
./configure --with-nagios-user=nagios --with-nagios-group=nagios \
--with-openssl
make
sudo make install
Далее:
sudo a2enmod cgi
sudo ln -s /etc/apache2/sites-available/nagios.conf \
/etc/apache2/sites-enabled/
Создаем пользователя для доступа к Nagios:
Пользователя должны звать именно nagiosadmin. Иначе вы сможете зайти в веб-интерфейс, но будете видеть повсюду ошибку «It appears as though you do not have permission to view information for any of the hosts you requested».
Прописываем Nagios на автозагрузку:
Далее:
sudo service apache2 restart
Можно зайти в http://example.ru/nagios/ под созданным ранее пользователем. Если вы увидите там алерты на своп, которого на машине попросту нет, не пугайтесь. Эту проблему мы скоро устраним.
Примеры конфигурации
Открываем /usr/local/nagios/etc/nagios.cfg. Это главный файл конфигурации. Комментируем все строки с cfg_file и cfg_dir, добавляем:
cfg_dir=/usr/local/nagios/etc/monitoring-configs/conf/
Также проверяем, что есть следующие строчки (у меня были):
interval_length=60
accept_passive_service_checks=1
accept_passive_host_checks=1
… и правим notification_timeout:
Дэфолтный таймаут в 30 секунд может быть слишком мал для некоторых нотификации, например, звонков на мобильный телефон и посылки SMS.
Заводим новый Git-репозиторий, в котором мы будем хранить настройки Nagios. Репозиторий будет содержать примерно следующие файлы:
+-- commands
| +-- commands.cfg
+-- contactgroups
| +-- contactgroups.cfg
+-- contacts
| +-- contact1.cfg
| +-- generic.cfg
+-- hostgroups
| +-- hostgroups.cfg
+-- hosts
| +-- cassandra.cfg
| +-- couchbase.cfg
| +-- generic.cfg
+-- servicegroups
| +-- .gitkeep
+-- services
| +-- backends.cfg
| +-- generic.cfg
+-- timeperiods
+-- timeperiods.cfg
Конфиги мы положим не в корне репозитория, чтобы рядом с конфигами можно было держать и какие-то утилиты, например, необходимые для посылки уведомлений.
Файл conf/hosts/generic.cfg:
name generic-host
register 0
# Как часто проводить проверку в минутах
check_interval 1
# Сколько минут подождать перед проверкой, не поднялся ли уже хост
retry_interval 1
# Сколько проверок должен завалить хост, чтобы считаться упавшим
max_check_attempts 2
# Слать нотификации не чаще одного раза в N минут
notification_interval 30
# Какие типы нотификаций посылать
# d - down
# u - unreachable
notification_options d,u
check_command check-host-alive
}
Чтобы поменьше писать, мы вводим специальный generic-хост, содержащий свойства, одинаковые для всех хостов в системе. Этот хост не будет отображаться в мониторинге, о чем свидетельствует строчка register 0
.
Пример описания конкретных хостов (cassandra.cfg):
use generic-host
host_name cassandra-1
address 172.31.11.22
contact_groups devs_email
}
define host {
use generic-host
host_name cassandra-2
address 172.31.33.44
contact_groups devs_email
}
Как видите, мы здесь «наследуем» свойства generic-хоста.
Файл conf/hostgroups/hostgroups.cfg позволяет для удобства объединять хосты в группы:
hostgroup_name linux-boxes
# группа может включать как другие группы...
hostgroup_members monitoring,cassandra
# ... так и отдельные хосты
members metrics
}
define hostgroup {
hostgroup_name cassandra
members cassandra-1,cassandra-2
}
# ...
Определение групп контактов (файл contactgroups.cfg):
contactgroup_name devs_email
}
define contactgroup {
contactgroup_name nobody
}
Помимо прочего, здесь мы вводим специальную группу nobody, в которой не будет ни одного человека.
В файле conf/contacts/generic.cfg описываем generic-контакт по аналогии с тем, как делали это для хостов:
name generic-contact
register 0
host_notifications_enabled 1
service_notifications_enabled 1
# d - down
# u - unreachable
# r - recovery
# f - flapping
host_notification_options d,u,r,f
# w - warning
# u - unknown
# c - critical
# r - recovery (OK)
# f - flapping
service_notification_options w,u,c,r,f
host_notification_period 24x7
service_notification_period 24x7
}
В файле conf/timeperiods/timeperiods.cfg описываем период 24x7:
timeperiod_name 24x7
alias 24x7
monday 00:00-24:00
tuesday 00:00-24:00
wednesday 00:00-24:00
thursday 00:00-24:00
friday 00:00-24:00
saturday 00:00-24:00
sunday 00:00-24:00
}
Теперь на основе generic-контакта можно создать и реальный контакт:
use generic-contact
contact_name afiskon_email
email afiskon@example.ru
contactgroups devs_email
host_notification_commands notify-host-by-email-aws
service_notification_commands notify-service-by-email-aws
}
Если планируется уведомлять о проблемах не только по email, можно завести аналогичные контакты afiskon_sms, afiskon_call, и другие, а также группы devs_sms, devs_slack, и так далее. У хостов в параметре contact_groups группы можно указывать через запятую.
Определение команд notify-* находятся в файле commands.cfg и являются немного переделанными командами notify-* из файла …/objects/commands.cfg на сервере Nagios. Вместо утилиты /bin/mail в наших командах используется небольшая программа на Scala, посылающая письмо через SMTP-сервер, предоставляемый Amazon SES. Также в файле …/objects/commands.cfg есть определение использованной ранее команды check-host-alive, которая просто шлет ping заданному хосту. При редактировании файла nagios.cfg мы оставили в нем строчку:
… что позволяет использовать check-host-alive и другие команды из этого файла в наших конфигах.
Наконец, сервисы. Сначала generic, по аналогии с хостами и контактами:
name generic-service
register 0
check_interval 1
retry_interval 1
max_check_attempts 2
check_period 24x7
notification_period 24x7
notification_options w,c,u
}
Примеры реальных сервисов:
use generic-service
hostgroup_name monitoring
service_description ssh
check_command check_ssh
contact_groups devs_email
}
define service {
use generic-service
hostgroup_name monitoring
service_description apache
check_command check_http
contact_groups devs_email
}
define service {
use generic-service
hostgroup_name cassandra
service_description cassandra
check_command check_tcp!9042
contact_groups devs_email
}
Вместо hostgroup_name можно указывать и конкретный хост, воспользовавшись параметром host_name.
Наконец, на машине, где крутится Nagios, говорим ssh-keygen
, прописываем получившийся ключ для доступа к репозиторию с конфигами.
Далее (здесь ubuntu — имя пользователя сисадмина):
sudo chown -R ubuntu:nagios etc
cd etc
git clone git@bitbucket.org:afiskon/monitoring-configs.git
Проверяем конфиги:
/usr/local/nagios/etc/nagios.cfg
Если нет ошибок, говорим:
В каталоге /usr/local/nagios/libexec/ вы найдете больше команд для проверки различных сервисов. Их не помешает отлаживать в консоли перед правкой конфигов. Делается это как-то так:
-u https://example.ru/pix.gif
Внимательные читатели в этом месте могли заметить, что чего-то не хватает. Как думаете, чего?
NRPE — Nagios Remote Plugin Executor
Хотелось бы не только проверять, что такие-то сервисы отвечают по HTTP, но и, например, сколько свободной памяти осталось на всех наших машинах. Есть команда check_by_ssh, с помощью которой можно этого добиться. Но иметь одну машину, с которой можно сходить по SSH на любую другую, даже с минимальными правами, очень небезопасно, сами понимаете. Поэтому придумали NRPE. Если простыми словами, то это демон, который позволяет удаленно выполнять только заранее заданное множество команд.
Проблема с NRPE заключается в том, что, как и Nagios, его надо бы везде собирать из исходников. Но делать это на всех машинах руками очень неприятно. Решать эту проблему можно разными способами (Ansible, checkinstall, …). Как вариант, для уже существующих машин можно воспользоваться моим готовым скриптом, а новые машины создавать из образов (типа которые в Amazon называются AMI). Упомянутый скрипт вам может захотеться допилить немного под себя. Например, если у вас свой ДЦ, если вы используете IaaS отличный от AWS, или если используете другой Linux, не Ubuntu.
После того, как NRPE везде развернут, в commands.cfg добавляем:
command_name check_nrpe
command_line [skipped]/libexec/check_nrpe -H $HOSTADDRESS$ -c $ARG1$
}
В services.cfg как-то так добавляем проверку load average на всех хостах с Linux:
use generic-service
hostgroup_name linux-boxes
service_description load
check_command check_nrpe!check_load
contact_groups devs_email
}
По аналогии добавляем check_mem, check_disk, check_users, check_zombie_procs и check_total_procs.
Заключение
Многие интересные вопросы, к сожалению, остались за кадром. Например, Nagios умеет агрегировать данные с других Nagios’ов. Он может пытаться сам чинить упавший сервис. Также он поддерживает иерархические зависимости между сервисами и хостами. Благодаря последнему при смерти какого-нибудь роутера вы получаете алерт только на смерть этого роутера, а не всех хостов, которые за ним находятся. В качестве источника дополнительной информации я всячески рекомендую книгу Learning Nagios 4.
Кстати, благодаря знакомству с Nagios, я стал намного лучше понимать людей, выступающих за ручное шардирование и ручной фейловер. Но это, пожалуй, тема для отдельной заметки.
А чем вы мониторите вашу систему?
Дополнение: Устанавливаем связку из Prometheus и Grafana
Метки: Linux.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.