Nagios - установка и настройка
Материал из Belgorod Linux User Group - Белгород.
Nagios - система мониторинга.
- Позволяет мониторить как локальные, так и сетевые ресурсы в реальном времени
- Отображение статуса в трехцветной форме (светофор) - зеленый (ok), желтый (warning), красный (error), с описанием причины ошибки
- Может уведомлять пользователя (по почте, sms, jabber)
- Имеет тактический монитор (позволяющий оперативно определить все возможные проблемы и их приоритет)
- Строит всевозможные сводные таблицы и графики
- Приятной особенностью является то, что отображаемые данные не обязательно должны быть системными или сетевыми параметрами - это могут быть любые количественные и качественные данные (например количество пользователей в базе, температура воздуха на улице, процент ошибок персонала и т.п.). Достигается это за счет простого написания скриптов для nagios (писать можно на любом языке: C, C++, bash, perl, php и т.п.).
Содержание |
[править] Установка
Ставим nagios своим пакетным менеджером. Я буду описывать на примере Gentoo Linux.
Для начала посмотрим что мы имеем:
emerge -pv nagios
Затем выставим все нужные нам флаги (встроенные плагины к nagios устанавливаются посредством USE-флагов):
echo "net-analyzer/nagios-core apache2" >> /etc/portage/package.use echo "net-analyzer/nagios-plugins mysql nagios-ntp nagios-ping nagios-ssh ups snmp" >> /etc/portage/package.use
Ставим сам пакет.
emerge nagios
[править] Настройка
Настройка nagios производится посредством редактирования файлов конфигурации. Система работает автономно и может мониторить и уведомлять в режиме демона. Web-фронтэнд ей не обязателен. Но нам нужен :)
[править] Web frontend
Создаем файл виртуального хоста для apache:
/etc/apache2/vhosts.d/nagios.conf
<VirtualHost *:80>
ServerName monitoring.lan
DocumentRoot /usr/share/nagios/
Alias /nagios/ /usr/share/nagios/htdocs/
<Directory "/usr/share/nagios">
Options None
AllowOverride AuthConfig
Order allow,deny
Allow from all
</Directory>
ScriptAlias /nagios/cgi-bin/ /usr/lib/nagios/cgi-bin/
<Directory "/usr/lib/nagios/cgi-bin">
AllowOverride AuthConfig
Options +ExecCGI
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Теперь создадим файл авторизации пользователя.
/usr/lib/nagios/cgi-bin/.htaccess
AuthName "Nagios Access" AuthType Basic AuthUserFile /usr/share/nagios/htpasswd.users require valid-user
Создаем сам пароль:
htpasswd -c /usr/share/nagios/htpasswd.users admin
Даем права нашему админу:
cd /etc/nagios/ sed "s/nagiosadmin/admin/gi" cgi.cfg > cgi.cfg
Перезапускаем apache
/etc/init.d/apache reload
[править] Добавление серверов
Для этого удобнее создать для них отдельную директорию:
mkdir /etc/nagios/servers
И подключить эту директорию в файле nagios.cfg, просто раскоментировав строку
cfg_dir=/etc/nagios/servers
Теперь сами сервера. К примеру у нас 3 сервера для myweb (пусть имена у них srv_www, srv_db, srv_pool).
[править] Группа серверов
Создаем файл к примеру /etc/nagios/servers/group-myweb.cfg
define hostgroup{
hostgroup_name myweb ; имя группы
alias Web Servers ; описание
members srv_www, srv_db, srv_pool ; перечень серверов
}
[править] Хосты
- Внимание: В nagios, в принципе, не имеет значения в каком вы файле что пишите. Главное, чтобы он или его директория подключались из главного конфигурационного файла nagios.cfg. По этому как называть файлы и что в них писать - решать вам. Как вам будет удобнее.
Удобнее для каждого хоста создать отдельный файл, в котором указать его имя, ip, и необходимые сервисы (которые будут мониториться). Создаем файл к примеру /etc/nagios/servers/myweb-srv_www.cfg
######
# HOST
define host{
use linux-server
host_name srv_www ; имя
address 192.168.0.12 ; IP
}
######
# SERVICE
define service{
use local-service
host_name srv_www ; имя сервера
service_description PING
check_command check_ping!100.0,20%!500.0,60%
}
define service{
use local-service
host_name srv_www ; имя сервера
service_description SSH
check_command check_ssh
notifications_enabled 0
}
define service{
use local-service
host_name srv_www ; имя сервера
service_description HTTP
check_command check_http
notifications_enabled 0
}
Для остальных хостов в группе делаем подобные файлы. Доступные команды описаны в файле /etc/nagios/objects/commands.cfg
[править] Группа сервисов
Для объединения логически связанных сервисов из разных хостов существуют группы сервисов (servicegroup). Они видны на отдельной закладке и позволяют судить о здоровье сервиса в целом по заданным характеристикам. Для этого необходимо выделить важные сервисы из хостов и описать их по формату: имя_сервера,имя_его_сервиса,имя_сервера,имя_его_сервиса
define servicegroup {
servicegroup_name www
alias My www hosting
members srv_www,Users,srv_www,Load Average,srv_db,Postgres Request Count,srv-db,Load Average,srv-db2,Load Average,srv-db3,Load Average
}
[править] Запуск
/etc/init.d/nagios start rc-update add nagios default
[править] Построение графиков
Графики в nagios не являются основным. Для этого лучше использовать наверное Cacti. Но все же графики можно прирутить. Плагином например. php4nagios или nagiosgpaph
[править] pnp4nagios
[править] Установка
Для построения графиков будем использовать пакет pnp4nagios
Для начала выставим нужный флаг (будет нужен для rrdtool)
echo "x11-libs/cairo svg" >> /etc/portage/package.use emerge -1 cairo
далее, для корректной отрисовки (проблемы с кодировкой) графиков в php4nagios потребуется пакет corefonts (ebuild почему-то не тянет его зависимостью):
emerge -1 corefonts
Ставим сам пакет:
emerge pnp4nagios
Добавляем алиас для него в apache:
/etc/apache2/vhosts.d/nagios.conf
Alias /nagios/pnp /usr/share/pnp/
<Directory /usr/share/pnp>
AllowOverride AuthConfig
Order allow,deny
Allow from all
</Directory>
(до описания Alias /nagios/ )
[править] Настройка
Чтобы собирались графики надо выставить значение
process_performance_data=1
Это можно поменять либо для всех ( в файле /etc/nagios/nagios.cfg )
Либо для каждого сервиса отдельно, в файлах сервисов ( /etc/nagios/servers ). Делается это там же, в описании сервисов. К примеру:
define service{
use local-service
host_name www
service_description PING
check_command check_ping!100.0,20%!500.0,60%
process_perf_data 1
}
будет означать, что надо собирать данные по ping-у
Так же в файле /etc/nagios/nagios.cfg раскоментируем:
host_perfdata_command=process-host-perfdata service_perfdata_command=process-service-perfdata
Теперь надо добавить сами команды в файл /etc/nagios/objects/commands.cfg, закоментировав их предыдущее определение
define command {
command_name process-service-perfdata
command_line /usr/bin/perl /usr/libexec/process_perfdata.pl
}
define command {
command_name process-host-perfdata
command_line /usr/bin/perl /usr/libexec/process_perfdata.pl -d HOSTPERFDATA
}
Чтобы появились ссылки на графики, в описание хостов ( файлах, расположенных в /etc/nagios/servers/ ) добавляем строку
action_url /nagios/pnp/index.php?host=$HOSTNAME$
Пример:
define host{
use linux-server
host_name www
address 192.178.0.12
action_url /nagios/pnp/index.php?host=$HOSTNAME$
}
Либо если хотим для всех хостов, то тобавляем в их шаблон ( /etc/nagios/objects/templates.cfg )
define host{
name linux-server
use generic-host
......
action_url /nagios/pnp/index.php?host=$HOSTNAME$
}
/etc/init.d/nagios reload
У вашего хоста рядом появится уже "клякса", которая будет ссылкой на графики.
[править] Создание собственного сервиса и графика к нему
Создаем скрипт, который будет в одну строку возвращать нужные нам данные в формате
"статус | имя=значение имя2=значение2 ..."
К примеру такой скрипт использования памяти :
#!/bin/bash
OID_TOTAL=".1.3.6.1.4.1.2021.336.4.1.2.7.102.114.101.101.77.101.109.1"
OID_CACHED=".1.3.6.1.4.1.2021.336.4.1.2.7.102.114.101.101.77.101.109.2"
OID_USED=".1.3.6.1.4.1.2021.336.4.1.2.7.102.114.101.101.77.101.109.3"
HOST=$1
COMMUNITY=$2
RES=0
function my_snmp_get () {
RES=$(/usr/bin/snmpget -t 1 -r 5 -m -v 1 -c$COMMUNITY $HOST $1 | sed 's/[^"]*"\(.*\)"/\1/gi')
}
my_snmp_get $OID_TOTAL
TOTAL=$RES
my_snmp_get $OID_CACHED
CACHED=$RES
my_snmp_get $OID_USED
USED=$RES
MU=$(echo "$USED/1024" | bc)
MT=$(echo "$TOTAL/1024" | bc)
echo "OK - used ${MU}M of ${MT}M | total=$TOTAL cached=$CACHED used=$USED"
exit 0
Как видно - наш плагин является просто bash-скриптом. Это может быть любой исполняемый файл. Главное чтобы он возвращал статус (принято OK / WARNING / CRITICAL) и нужные нам значения переменных через пробел в формате имя=значение. В данном случаи скрипт принимает на вход первым параметром адрес опрашиваемого по SNMP хоста, а вторым - snmp community. Так же мы возвращаем код ошибки (по exit) 0-это OK, 1-WARNING, 2-CRITICAL, 3-UNKNOWN, 4-DEPENDENT
Сохраняем его в директории с плагинами Nagios: /usr/lib/nagios/plugins/check_my_mem и даем ему право на запуск:
chmod +x /usr/lib/nagios/plugins/check_my_mem
Далее описываем команду для запуска этого скрипта в файле команд: /etc/nagios/objects/commands.cfg
define command{
command_name check_my_mem
command_line $USER1$/check_my_mem $HOSTADDRESS$ $ARG1$
}
тут мы указали имя скрипта и передали нужные параметры: имя хоста и community. Community мы передадим из сервиса в качестве параметра $ARG1$, т.к. он может быть разный для каждого хоста.
Теперь описываем сервис (в шаблоне хостов или в самом хосте ):
define service {
use local-service
host_name web
service_description My Memory Usage
check_command check_my_mem!public
}
Как видно мы вызвали нашу описанную выше команду с параметром коммьюнити. Как правило остальными параметрами (разделяются через знак !) передаются пределы значений для WARNING и CRITICAL, которые будут обрабатываться скриптом / плагином и возвращать соответствующий статус.
Теперь можно перечитать настройки nagios и через некоторое время посмотреть - создался ли файл данных для нашего нового сервиса:
/etc/init.d/nagios reload less /var/nagios/perfdata/www/My_Memory_Usage.xml
[править] Шаблоны pnp4nagios
Теперь наши данные собираются и уже их видно в мониторинге. Осталось нарисовать график.
Если вы знакомы с rrdtools, то шаблоны pnp4nagios не будут для вас препятствием. Если не знакомы - ничего страшного.
Создаем шаблон с именем нашего сервиса:
vim /usr/share/pnp/templates/check_my_mem.php
И пишем туда следующее:
<?php $opt[1] = "--alt-autoscale-max --lower-limit=0 "; $def[1] .= "DEF:a1=$rrdfile:$DS[1]:AVERAGE "; $def[1] .= "DEF:a2=$rrdfile:$DS[2]:AVERAGE "; $def[1] .= "DEF:a3=$rrdfile:$DS[3]:AVERAGE "; $def[1] .= "CDEF:var1=a1,1024,* "; $def[1] .= "CDEF:var2=a2,1024,* "; $def[1] .= "CDEF:var3=a3,1024,* "; $def[1] .= "AREA:var1#002A97:$NAME[1] "; $def[1] .= "AREA:var2#FFAB00:$NAME[2] "; $def[1] .= "AREA:var3#FF0000:$NAME[3] "; $def[1] .= 'COMMENT:" \n" '; $def[1] .= "GPRINT:var1:AVERAGE:\"%8.2lf %s $NAME[1] \" "; $def[1] .= "GPRINT:var2:AVERAGE:\"%8.2lf %s $NAME[2] \" "; $def[1] .= "GPRINT:var3:AVERAGE:\"%8.2lf %s $NAME[3] \" "; ?>
Это по сути формирование командной строки для rrdtool. Тут я использую переменные $DS, $NAME и прочие. С ними можно ознакомиться, посмотрев xml-файл, созданный pnp4nagios-ом при опросе.
less /var/nagios/perfdata/www/My_Memory_Usage.xml
Видим, что NAME - это имя. А индекс в массиве - это номер записи. $rrdfile - файл, $DS - имя (номер) источника данных. Там еще много может быть переменных - это и максимальные и критические значения и пр. Но мы пока это опустим. Для нас главное, это то, что переменная для отрисовки определяется как DEF:a1=$rrdfile:$DS[1]:AVERAGE, а индекс [1] - это номер значения. Если своим скриптом мы возвращали одно имя=значение, то достаточно $DS[1], а если несколько, то появятся и 2 и 3, как у меня в примере.
Далее. Формат описания для rrdtool довольно прост.
* DEF - определение переменной, * CDEF - применение функции к переменной (в данном случаи я умножаю на 1024) * AREA / LINE - отрисовка переменной * COMMENT - строка коментария * GPRINT - печать переменной заданным шаблоном
Теперь можно смотреть графики. Если график не отрисовался - не переживайте, кликните на "битую" картинку, и pnp4nagios покажет свой debug и скажет в чем вы ошиблись.
[править] nagiosgraph
Еще один плагин для отрисовки графиков - nagiosgraph
[править] Установка
В портах ebuild-а я его не нашел, но установка у него достаточно проста. Скачиваем с их сайта http://nagiosgraph.sourceforge.net/ пакет, распаковываем и следуем указаниям в INSTALL.
[править] Настройка
В файл /etc/nagios/nagios.cfg добавляем строки:
process_performance_data=1 service_perfdata_file=/var/log/nagios/perfdata.log service_perfdata_file_template=$LASTSERVICECHECK$||$HOSTNAME$||$SERVICEDESC$||$SERVICEOUTPUT$||$SERVICEPERFDATA$ service_perfdata_file_mode=a service_perfdata_file_processing_interval=30 service_perfdata_file_processing_command=process-service-perfdata
в файл /etc/nagios/objects/commands.cfg строки:
define command{
command_name process-service-perfdata
command_line /usr/lib/nagios/insert.pl "$LASTSERVICECHECK$||$HOSTNAME$||$SERVICEDESC$||$SERVICEOUTPUT$||$SERVICEPERFDATA$"
}
в файл шаблона /etc/nagios/objects/templates.cfg или в файлы шаблонов хостов /etc/nagios/servers добавляем строки:
notes_url /nagiosgraph/show.cgi?host=$HOSTNAME$&service=$SERVICEDESC$ icon_image graph.gif icon_image_alt View graphs
[править] Шаблонизация
Nagios представляет собой очень гибкую систему. Одна из ее полезных черт - удобная шаблонизация.
- Свои шаблоны удобнее хранить в отдельном файле. Заведите себе где-нибудь файл my-templates.cfg, и пропишите строку
cfg_file=/etc/nagios/objects/my_templates.cfg
в файле nageios.cfg
Рассмотрим шаблонизацию на примере плагина мониторинга места http://nagios.manubulon.com/snmp_storage.html
Скачиваем плагин, помещаем его в /usr/lib/nagios/plugins/ и даем права на запуск. Смотрим параметры. Формируем свою строку из этих параметров. У меня получилось что-то вроде этого:
./check_snmp_storage.pl -H 192.168.0.52 -C public -w 80 -c 90 -f -m /var
Флаг -f (в некоторых плагинах -F) - обязателен для нас, т.к. мы будем строить графики, а этот флаг отвечает за вывод данных в формате имя=значение, для сбора их в perfparse.
[править] Команда
Описываем команду:
# storage usage
define command {
command_name check_snmp_storage
command_line $USER1$/check_snmp_storage.pl -H $HOSTADDRESS$ -C $ARG1$ -w $ARG2$ -c $ARG3$ -f -m $ARG4$
}
Тут я описал нашу командную строку, составленную выше. Как видим передаю имя хоста, а затем коммьюнити - первым параметром, warning-вторым (проценты заполнения), critical - третьим, а само имя storage буду передавать четвертым. В принципе, в системе уже можно использовать эту команду примерно так:
define service {
service_description Storage Usage
check_snmp_storage!public!80!90!/var
host_name www
}
Но мы будем все упрощать и шаблонизировать!
[править] Хост
Создаем свой шаблон хостов:
define host {
name my-linux-server
use linux-server
_COMMUNITY public
register 0
}
- register 0 указывает на то, что данное описание является шаблоном и в системе не регистрируется как отдельный сервис или хост.
Тут я использовал переменную (макрос) _COMMUNITY для задания snmp-коммьюнити своих хостов. Это макрос хоста. Он будет доступен как $_HOSTvar, т.е. в нашем случаи как $_HOSTCOMMUNITY. Эту переменную я и буду использовать в шаблоне сервисов. По этому если наш хост будет использовать эту коммьюнити, я смогу написать просто use my-linux-server, а могу переназначить его так:
define host {
use my-linux-server
_COMMUNITY S4js3D
....
}
[править] Сервис
Шаблонизируем сервис. Описываем шаблон сервиса:
# storage usage
define service {
use local-service
name snmp-storage
service_description Storage Usage
_WARNING 80
_CRITICAL 90
_STORAGE / -r
check_command check_snmp_storage!$_HOSTCOMMUNITY$!$_SERVICEWARNING!$_SERVICECRITICAL!$_SERVICESTORAGE$
register 0
}
Тут я описал нашу команду и задал свои макросы. К примеру я ввел такие переменные как _WARNING, _CRITICAL, _STORAGE и выставил их по-умолчанию. В хосте их можно будет переназначить. Вот пример использования это сервиса внутри хоста:
define service {
use snmp-storage
_STORAGE /var
service_description /var Usage
host_name www
}
Тут я переназначил значение переменной _STORAGE, и она попадет в команду (check_command) под именем $_SERVICECOMMAND. То есть эти переменные (макросы) я ввел специально, чтобы их можно было переназначить в конечном сервисе, если это будет необходимо (допустим изменить порог _WARNING именно для этого хоста).
- http://nagios.sourceforge.net/docs/3_0/macros.html - подробнее о макросах.
[править] Суперсервис
Красивый пример шаблонизации - шаблонизация уже шаблонизированного :) Вот сервис Swap, который мониторит использования свопа, базируясь на нашем вышеописанном шаблоне сервиса snmp-storage:
define service {
use snmp-storage
name swap
_STORAGE Swap
service_description Swap Usage
register 0
}
Как видно тут я использую свой же шаблон snmp-storage и просто переопределил переменную _STORAGE, получив новый сервис - мониторинга свопа. Использовать в хосте его можно будет очень просто. Так:
define service {
use swap
host_name www
}
Просто. Не правда-ли?
Более того! У нас уже собираются данные, а значит и могут рисоваться графики. Создадим шаблон графика для pnp4nagios:
[править] График
Вот мой файл для этого скрипта:
/usr/share/pnp/templates/check_snmp_storage.php
<?php $opt[1] = "--imgformat=PNG "; $opt[1] .= "--rigid "; $opt[1] .= "--base=1000 "; $opt[1] .= "--height=120 "; $opt[1] .= "--width=500 "; $opt[1] .= "--alt-autoscale-max "; $opt[1] .= "--lower-limit=0 "; $opt[1] .= "--slope-mode "; $opt[1] .= "--font TITLE:12: "; $opt[1] .= "--font AXIS:8: "; $opt[1] .= "--font LEGEND:10: "; $opt[1] .= "--font UNIT:8: "; $opt[1] .= return "--title=\"$text $hostname - $servicedesc\" "; $opt[1] .= "--vertical-label=MB "; $def[1] = "DEF:var1=$rrdfile:$DS[1]:AVERAGE "; $def[1] .= "AREA:$MAX[1]#002A97: "; $def[1] .= "AREA:var1#FF0000: "; $def[1] .= "HRULE:$MAX[1]#003300:\"Size $MAX[1] MB\" "; $def[1] .= "HRULE:$WARN[1]#ffff00:\"Warning on $WARN[1] MB \" "; $def[1] .= "HRULE:$CRIT[1]#ff0000:\"Critical on $CRIT[1] MB \\n\" "; $def[1] .= "GPRINT:var1:LAST:\"%8.2lf MB of $MAX[1] MB used \\n\" "; $def[1] .= "GPRINT:var1:MAX:\"%8.2lf MB max used \\n\" "; $def[1] .= "GPRINT:var1:AVERAGE:\"%8.2lf MB avg used\" "; ?>
Все. Данные и графики для свопа и места на любых носителях готовы.
[править] Совет
Шаблонизируйте все! Описывая любой свой сервис - используйте шаблон. Пусть даже пустой. Создайте метасервис. Пример: Хотим описать много сервисов.
Создаем сначала заглушку - метасервис:
# metaservice
define service {
use local-service
name my-local-service
}
Затем, описываем сами сервисы, наследуя от метасервиса. К примеру для SSH
# SSH
define service{
use my-local-service
name ssh
service_description SSH
check_command check_ssh
register 0
}
Теперь использовать этот сервис для хоста будем так:
define service {
use ssh
host_name www-srv
}
Удобно. И таких сервисов будет много. НО! Тут мы захотели к примеру добавить уведомления для всех сервисов. Для этого придется либо в каждом конечном сервисе, либо в каждом шаблоне добавлять строки. А мы добавим всего в родительском мета-сервисе:
# metaservice
define service {
use local-service
name my-local-service
contact_groups www-admins
notification_period workhours
register 0
}
[править] Уведомления
nagios умеет по крайней мере 2 вида уведомлений - уведомления хоста (host_notification) и уведомления сервиса ( service_notification). Уведомления хоста приходят в случаи проблем с хостом (хост недоступен), уведомления сервиса приходят от сервисов (когда превышен порог или сервис недоступен). Типы оповещений тоже настраиваются. Уведомления приходят на соответствующую группу контактов (contact_groups). По этому все это надо описать.
[править] Контакт
[править] Шаблон
Для начала создадим шаблон контактов. Описать его можно к примеру в вашем файле шаблонов
define contact {
use generic-contact
name my-www-contact
host_notification_commands notify-host-by-email,host-notify-by-jabber
host_notification_options d,u,r
service_notification_commands notify-by-jabber
service_notification_options w,u,c,r
register 0
}
Тут мы создали шаблон контакта. Которому как мы видим от хоста сообщения будут идти и на почту и на jabber. А уведомления от сервиса - только в jabber. Так же мы выставили, события, по которым будут идти уведомления.
d - down, u - unknown, r - recovery, w - warning, c - critical, f - flapping, s - sheduled
[править] Группа
Опишем группу котактов
define contactgroup {
contactgroup_name www-admins
alias my www hosting
members me, cosysop
}
[править] Пользователь
Теперь опишем конечных пользователей, используя наш шаблон:
define contact {
use my-www-contact
contact_name me
alias Alex P. Burlutsky
}
Заметим, используется шаблон my-www-contact. Вот так мы описали пользователя с логином me, который состоит в группе www-admins.
[править] Хост
Теперь надо указать, что этой группе (www-admins) должны приходить оповещения от хоста. Для этого в описании хоста (а лучше шаблона хоста) нужно вписать contact_groups:
define host{
use my-linux-server
host_name www-srv
contact_groups www-admins
....
По умолчанию проверка хоста идет по icmp (по ping), если у вас на хосте закрыт ping (firewall-ом например), то nagios будет показывать, что host down. Для изменения типа проверки в хосте следует указать параметр check_command. Вот пример для проверки по http:
define host{
use my-linux-server
host_name web-srv
contact_groups www-admins
check_command check_http
...
[править] Сервис
Чтобы ходили уведомления от сервиса - надо в самом сервисе (или в его шаблоне) так же вписать группу контактов:
define service {
use local-service
name snmp-lavr
service_description Load Average
contact_groups www-admins
....
[править] Команды
[править] Jabber
В рассмотренном выше примере идет уведомление nagios на jabber. В стандатрной поставке такого скрипта нет, по этому расскажу как это сделать. Скачиваем сам скрипт тут:
http://nagios.sourceforge.net/download/contrib/notifications/notify_via_jabber
Для gmail аккаунтов хороший скрипт:
http://www.gridpp.ac.uk/wiki/Nagios_jabber_notification
(только надо заменить tls на ssl и порт на 5223)
и кладем его в /usr/lib/nagios/plugins, ставим на него права запуска
chmod +x notify_via_jabber
редактируем, выставляя логин, пароль от которогу будут идти уведомления.
* Внимание! Необходимо предварительно зарегистрировать этот адрес, и желательно добавить этого пользователя в свои ростеры.
ставим CPAN модуль для работы Perl с джаббер:
emerge Net-Jabber
Описываем командуы:
# ---- NOTIFY ---
# 'host-notify-by-jabber' command definition
define command{
command_name host-notify-by-jabber
command_line $USER1$/notify_via_jabber $CONTACTPAGER$ "Host '$HOSTALIAS$' is $HOSTSTATE$ - Info: $HOSTOUTPUT$"
}
# 'notify-by-jabber' command definition
define command{
command_name notify-by-jabber
command_line $USER1$/notify_via_jabber $CONTACTPAGER$ "$NOTIFICATIONTYPE$ $HOSTNAME$ $SERVICEDESC$ $SERVICESTATE$ $SERVICEOUTPUT$ $LONGDATETIME$"
}
[править] SMS
Уведомлять по SMS тоже можно несколькими способами. Можно подключить модем, а вот пример через сервис smstraffic:
vim /usr/lib/nagios/plugins/notify_via_sms
#/bin/bash
LOG="/tmp/sms.log"
tel="$1"
msg="$2"
form="0"
login="mylogin"
pass="mypassword"
orig="Nagios"
msg_cx=`echo $msg|wc -c`
if [ $msg_cx -gt 128 ]; then
echo "Message is too long"
exit 2
fi
dat=$(date +"%Y-%m-%d %H:%M:59")
host="http://smsmail.ru/corp/multi.php"
curl -F "login=$login" -F "password=$pass" -F "originator=$orig" -F "phones=$tel" -F "message=$msg" -F "start_date=$dat" -F "rus=$form" $host > $LOG 2> $LOG
Описываем команду:
define command{
command_name host-notify-by-sms
command_line $USER1$/notify_via_sms $CONTACTADDRESS1$ "'$HOSTALIAS$' is $HOSTSTATE$ - $HOSTOUTPUT$"
}
Добавляем вызов команды оповещения к примеру в шаблоне контакта:
define contact {
use generic-contact
name my-contact
host_notification_commands notify-host-by-email,host-notify-by-jabber,host-notify-by-sms
service_notification_commands notify-by-jabber
service_notification_options w,c
register 0
}
[править] Карта
Чтобы увидеть пользовательскую карту, необходимо в меню выбрать Map -> User-supplied coords -> Update. Но перед этим эти координаты надо задать. Я для карты завел отдельный файл, чтобы все координаты были в нем. Описываются они в hostextinfo параметры:
* icon_image - имя иконки, отображаемой рядом с хостом и во всплывающих подсказках. Иконки находятся тут: /usr/share/nagios/htdocs/images/logos/ * statusmap_image - имя иконки, которая будет отображена на карте * 2d_coords - координаты x,y - от левой верхней точки.
Вот пример моего файла:
# Шаблон по умолчанию
define hostextinfo {
name my-he
register 0
icon_image gentoo.png
statusmap_image gentoo.gd2
}
define hostextinfo{
use my-he
host_name www-vm
2d_coords 50,100
}
define hostextinfo{
use my-he
host_name www-svn
2d_coords 150,100
}
define hostextinfo{
use my-he
host_name www-srv
2d_coords 250,100
...
define hostextinfo{
use my-he
host_name my-router
2d_coords 200,200
}
...
define hostextinfo{
use my-he
host_name my-other
icon_image suse.jpg
statusmap_image suse.jpg
2d_coords 200,400
}
[править] Примеры
На закуску вот еще шаблоны для некоторых встроенных и плагинов с http://nagios.manubulon.com/
[править] Команды
# load average
define command {
command_name check_snmp_load
command_line $USER1$/check_snmp_load.pl -H $HOSTADDRESS$ -C $ARG1$ -w $ARG2$ -c $ARG3$ -T netsl -f
}
# process count
define command {
command_name check_snmp_process
command_line $USER1$/check_snmp_process.pl -H $HOSTADDRESS$ -C $ARG1$ -F -w $ARG2$ -c $ARG3$ -n $ARG4$
}
# interface statistic
define command {
command_name check_snmp_int
command_line $USER1$/check_snmp_int.pl -H $HOSTADDRESS$ -C $ARG1$ -n $ARG2$ -f -q
}
[править] Сервисы
# Ping
define service{
use local-service
name ping
service_description PING
_WARNING 200.0,20%
_CRITICAL 500.0,60%
check_command check_ping!$_SERVICEWARNING!$_SERVICECRITICAL
register 0
}
# SSH
define service{
use local-service
name ssh
service_description SSH
check_command check_ssh
register 0
}
# load average
define service {
use local-service
name snmp-lavr
service_description Load Average
_WARNING 3,3,2
_CRITICAL 4,4,5
check_command check_snmp_load!$_HOSTCOMMUNITY$!$_SERVICEWARNING!$_SERVICECRITICAL
register 0
}
# process count
define service {
use local-service
name snmp-process
service_description Processes
_WARNING 3,8
_CRITICAL 0,20
_PROCESS postmaster
check_command check_snmp_process!$_HOSTCOMMUNITY$!$_SERVICEWARNING$!$_SERVICECRITICAL!$_SERVICEPROCESS
register 0
}
# http availability
define service {
use local-service
name http
service_description HTTP
check_command check_http
register 0
}
# interface traffice
define service {
use local-service
name traffic
service_description Traffic
_INTERFACE eth0
check_command check_snmp_int!$_HOSTCOMMUNITY$!$_SERVICEINTERFACE!
}
[править] Хост
Их использование в хосте будет примерно таким:
define host{
use my-linux-server
host_name www
address 192.168.0.52
}
define service {
use ping
host_name www
}
define service {
use ssh
host_name www
}
define service {
use snmp-lavr
host_name www
}
define service {
use swap
host_name www
}
define service {
use traffic
_INTERFACE eth1
host_name www
}
Удобно не правда-ли?
[править] Графики
Вот мои шаблоны графиков:
- Load average
/usr/share/pnp/templates/check_snmp_load.php
<?php
require_once ("/usr/share/pnp/my/_my.php");
$opt[1] = m_base();
$opt[1] .= m_title();
$def[1] = "DEF:var1=$rrdfile:$DS[1]:AVERAGE " ;
$def[1] .= "DEF:var2=$rrdfile:$DS[2]:AVERAGE " ;
$def[1] .= "DEF:var3=$rrdfile:$DS[3]:AVERAGE " ;
$def[1] .= "HRULE:$WARN[1]#FFFF00 ";
$def[1] .= "HRULE:$CRIT[1]#FF0000 ";
$def[1] .= "AREA:var3#FF0000:\"Load 15\" " ;
$def[1] .= "GPRINT:var3:LAST:\"%6.2lf last\" " ;
$def[1] .= "GPRINT:var3:AVERAGE:\"%6.2lf avg\" " ;
$def[1] .= "GPRINT:var3:MAX:\"%6.2lf max\\n\" " ;
$def[1] .= "AREA:var2#EA8F00:\"Load 5 \" " ;
$def[1] .= "GPRINT:var2:LAST:\"%6.2lf last\" " ;
$def[1] .= "GPRINT:var2:AVERAGE:\"%6.2lf avg\" " ;
$def[1] .= "GPRINT:var2:MAX:\"%6.2lf max\\n\" " ;
$def[1] .= "AREA:var1#EACC00:\"load 1 \" " ;
$def[1] .= "LINE1:var1#000000FF: ";
$def[1] .= "GPRINT:var1:LAST:\"%6.2lf last\" " ;
$def[1] .= "GPRINT:var1:AVERAGE:\"%6.2lf avg\" " ;
$def[1] .= "GPRINT:var1:MAX:\"%6.2lf max\\n\" ";
?>
- Traffic
/usr/share/pnp/templates/check_snmp_int.php
<?php
require_once ("/usr/share/pnp/my/_my.php");
$opt[1] = m_base();
$opt[1] .= m_title("Interface Traffic for");
$opt[1] .= m_vlabel("Traffic");
$opt[1] .= "-b 1024 ";
$def[1] .= "DEF:a=$rrdfile:$DS[1]:AVERAGE ";
$def[1] .= "DEF:b=$rrdfile:$DS[1]:MAX ";
$def[1] .= "DEF:c=$rrdfile:$DS[2]:AVERAGE ";
$def[1] .= "DEF:d=$rrdfile:$DS[2]:MAX ";
$def[1] .= "CDEF:cdefa=TIME,$NAGIOS_EVENTSTARTTIME,GT,a,a,UN,0,a,IF,IF,TIME,$NAGIOS_EVENTSTARTTIME,GT,c,c,UN,0,c,IF,IF,+ ";
$def[1] .= "AREA:a#96E78AFF:\"Inbound\" ";
$def[1] .= "GPRINT:a:LAST:\"Current\:%6.2lf %s\" ";
$def[1] .= "GPRINT:a:AVERAGE:\"Average\:%6.2lf %s\" ";
$def[1] .= "GPRINT:b:MAX:\"Maximum\:%6.2lf %s\\n\" ";
$def[1] .= "COMMENT:\"Total In\: 0 bytes\\n\" ";
$def[1] .= "AREA:c#FFC73BFF:Outbound ";
$def[1] .= "GPRINT:c:LAST:\"Current\:%6.2lf %s\" ";
$def[1] .= "GPRINT:c:AVERAGE:\"Average\:%6.2lf %s\" ";
$def[1] .= "GPRINT:d:MAX:\"Maximum\:%6.2lf %s\" ";
$def[1] .= "COMMENT:\"Total Out\: 0 bytes\" ";
$def[1] .= "LINE1:c#2175D9FF: ";
$def[1] .= "LINE1:a#2175D9FF: ";
$def[1] .= "GPRINT:cdefa:LAST:\"Summ\:%6.2lf %s\" ";
$def[1] .= "LINE1:cdefa#000000FF: ";
?>
- Storage
/usr/share/pnp/templates/check_snmp_storage.php
<?php
require_once ("/usr/share/pnp/my/_my.php");
$opt[1] = m_base ();
$opt[1] .= m_title ();
$opt[1] .= m_vlabel ("MB");
$def[1] = "DEF:var1=$rrdfile:$DS[1]:AVERAGE ";
$def[1] .= "AREA:$MAX[1]#002A97: ";
$def[1] .= "AREA:var1#FF0000: ";
$def[1] .= "HRULE:$MAX[1]#003300:\"Size $MAX[1] MB\" ";
$def[1] .= "HRULE:$WARN[1]#ffff00:\"Warning on $WARN[1] MB \" ";
$def[1] .= "HRULE:$CRIT[1]#ff0000:\"Critical on $CRIT[1] MB \\n\" ";
$def[1] .= "GPRINT:var1:LAST:\"%8.2lf MB of $MAX[1] MB used \\n\" ";
$def[1] .= "GPRINT:var1:MAX:\"%8.2lf MB max used \\n\" ";
$def[1] .= "GPRINT:var1:AVERAGE:\"%8.2lf MB avg used\" ";
?>
- общий файл
/usr/share/pnp/my/_my.php
<?php
function m_base () {
$res = "--imgformat=PNG ";
$res .= "--rigid ";
$res .= "--base=1000 ";
$res .= "--height=120 ";
$res .= "--width=500 ";
$res .= "--alt-autoscale-max ";
$res .= "--lower-limit=0 ";
$res .= "--slope-mode ";
$res .= "--font TITLE:12: ";
$res .= "--font AXIS:8: ";
$res .= "--font LEGEND:10: ";
$res .= "--font UNIT:8: ";
return $res;
}
function m_title($text) {
global $hostname, $servicedesc;
return "--title=\"$text $hostname - $servicedesc\" ";
}
function m_vlabel($text) {
return "--vertical-label=\"$text\" ";
}
?>
[править] Добавление градиента
Очень симпатично смотрятся графики с градиентом (см. графики PING). Для этого в шаблон по умолчанию
vim /usr/share/pnp/templates.dist/default.php
вносим изменения:
#define("_AREA", '#EACC00');
define("_AREA", '#EA7400');
...
$def[$i] .= "AREA:var1" . _AREA . ":\"$NAME[$i] \" ";
// gradient
$def[$i] .= "CDEF:sp1=var1,100,/,12,* " ;
$def[$i] .= "CDEF:sp2=var1,100,/,30,* " ;
$def[$i] .= "CDEF:sp3=var1,100,/,50,* " ;
$def[$i] .= "CDEF:sp4=var1,100,/,70,* " ;
$def[$i] .= "AREA:sp4#EA8A00: " ;
$def[$i] .= "AREA:sp3#EAB000: " ;
$def[$i] .= "AREA:sp2#EACC00: " ;
$def[$i] .= "AREA:sp1#E2EA00: " ;
//
$def[$i] .= "LINE1:var1" . _LINE . ":\"\" ";
[править] Мониторинг через SSH
Частным случаем мониторинга может служить мониторинг через SSH. Обычно применяется, когда на сервере нет возможности поставить или открыть SNMP.
Так же подходит для случая, когда сервера находятся за DMZ, и их можно мониторить только через шлюз по SSH.
Для этого используется плагин check_by_ssh, который авторизуется на сервере по SSH и выполняет там команду. Для простоты будем сервер мониторинга с Nagios называть просто сервер (server), а клиентские машины, которые необходимо мониторить - клиент (client).
[править] Авторизация
Сервер должен авторизоваться на клиенте по ключу. Для этого генерируем пару ключей RSA на сервере, и выкладываем окрытый ключ на клиента:
server# sudo su - nagios nagios@server$ mkdir .ssh nagios@server$ chmod 700 .ssh nagios@server$ ssh-keygen -t rsa nagios@server$ scp .ssh/id_rsa.pub user@client.ip:/home/user
На клиенте создаем пользователя, от которого будут исполняться скрипты мониторинга и помещаем только что созданный публичный ключ, как ключ для авторизации:
client# useradd -c Nagios.Monitoring.By.SSH -m nagios client# mkdir /home/nagios/.ssh client# mv /home/user/id_rsa.pub /home/nagios/.ssh/authorized_keys client# chown -R nagios:users /home/nagios/.ssh/ client# chmod 700 /home/nagios/.ssh/ client# chmod 600 /home/nagios/.ssh/authorized_keys
Проверяем коннект с сервера по ключу с сервера:
nagios@server$ ssh -v nagios@client.ip
Должно законнектиться без запроса пароля.
[править] Плагины
Проверки будут выполняться путем исполнения плагинов nagios на клиенте. Для этого их надо перелить с сервера на клиента:
nagios@server$ scp /usr/lib/nagios/plugins/* nagios@client.ip:/home/nagios/
Проверяем с сервера:
nagios@server$ ssh nagios@client.ip "/home/nagios/check_load -w 1,1,1 -c 3,3,3"
Должен выдать загрузку клиента:
OK - load average: 0.01, 0.04, 0.11|load1=0.010;1.000;3.000;0; load5=0.040;1.000;3.000;0; load15=0.110;1.000;3.000;0;
Теперь тоже самое через плагин:
/usr/lib/nagios/plugins/check_by_ssh -H tzselektra.ru -C "/home/nagios/check_load -w 1,1,1 -c 3,3,3"
получаем:
OK - load average: 0.06, 0.05, 0.10|load1=0.060;1.000;3.000;0; load5=0.050;1.000;3.000;0; load15=0.100;1.000;3.000;0;
Работает.
[править] Команда
Теперь мы можем описать команду опроса через ssh:
define command {
command_name check_ssh_load
command_line $USER1$/check_by_ssh -H $HOSTADDRESS$ -C "/home/hagios/check_load -w $ARG1$ -c $ARG2$"
}
[править] Сервис
и соответствующий ей сервис:
define service {
use local-service ; check current load on machine
service_description Current Load
check_command check_ssh_load!1,1,1!2,2,2
}
Все. Можно добавлять сервис в хосты (см. описание выше).
[править] DMZ
Что делать если сервер находится за DMZ? Делаем все тоже, что и выше, только появляется сервер, который виден только за клиентом, назовем его client2.
[править] Авторизация
Разрешим клиенту, на котором уже может авторизоваться наш сервер - авторизовываться на client2. Для этого так же генерируем пару ключей и переливаем публичный ключ на client2
client# sudo su - nagios nagios@client$ ssh-keygen -t rsa nagios@client$ scp .ssh/id_rsa.pub user@client2:/home/user/
далее уже на client2 (на который мы можем зайти только с client) - создаем пользователя nagios и отдаем ему этот ключ:
client2# useradd -c Nagios.Monitoring.By.SSH -m nagios client2# mkdir /home/nagios/.ssh client2# mv /home/user/id_rsa.pub /home/nagios/.ssh/authorized_keys client2# chown -R nagios:users /home/nagios/.ssh/ client2# chmod 700 /home/nagios/.ssh/ client2# chmod 600 /home/nagios/.ssh/authorized_keys
Пробуем залогиниться по ключу с client на client2:
nagios@client$ ssh client2
должно залогиниться без запроса пароля:
nagios@client$ ssh client2 nagios@client2$ nagios@client2$ exit nagios@client$
[править] Плагины
Заливаем плагины на client2:
nagios@client$ scp /home/nagios/check* client2:/home/nagios/
Проверяем с клиента:
nagios@server$ ssh nagios@client.ip "/home/nagios/check_load -w 1,1,1 -c 3,3,3"
Должно ответить:
WARNING - load average: 1.25, 1.90, 2.47|load1=1.250;1.000;3.000;0; load5=1.900;1.000;3.000;0; load15=2.470;1.000;3.000;0;
А теперь фокус! Проверяем с сервера через 2 ssh да еще и через плагин! Сразу client2, которого напрямую не видно с сервера:
nagios@server$ /usr/lib/nagios/plugins/check_by_ssh -H client.ip -C "ssh client2 /home/nagios/check_load -w 1,1,1 -c 3,3,3"
Отвечает:
WARNING - load average: 1.60, 1.88, 2.38|load1=1.600;1.000;3.000;0; load5=1.880;1.000;3.000;0; load15=2.380;1.000;3.000;0;
Если все ок - можно добавлять остальных клиентов, находящихся за client.ip.
[править] Команда
Создаем команды, для опроса серверов за DMZ.
define command {
command_name check_dmz_load
command_line $USER1$/check_by_ssh -H $ARG1$ -C "ssh $HOSTADDRESS$ /home/nagios/check_load -w $ARG2$ -c $ARG3$"
}
Тут мы указываем первым параметром наш client, а уже на нем выполняем команду ssh с указанием адреса client2 и запуска уже на client2 скрипта check_load.
define command {
command_name check_dmz_ssh
command_line $USER1$/check_by_ssh -H $ARG1$ -C "/home/nagios/check_ssh $HOSTADDRESS$"
}
А тут мы просто проверяем доступность ssh на client2 с client
[править] Сервис
И описываем сервис:
define service {
use local-service
name dmz-lavr
service_description Load Average
_WARNING 3,3,2
_CRITICAL 4,4,5
check_command check_dmz_load!$_HOSTDMZ$!$_SERVICEWARNING!$_SERVICECRITICAL
register 0
}
Ну и для check_dmz_ssh:
define service {
use local-service
name dmz-ssh
service_description SSH
check_command check_dmz_ssh!$_HOSTDMZ$
register 0
}
[править] Хост
Регистрируем сам хост client2:
define host{
use linux-server
host_name my-client2 # просто имя, которое будет видно в nagios
_DMZ client.ip # адрес клиента, доступного с сервера сбора (за которым находится client2),
# так называемый пограничный сервер DMZ
address client2 # адрес client2, видный только из client
check_command check_dmz_ssh!client.ip # проверяем хост по доступности по ssh с client
}
# Load Average
define service {
use dmz-lavr # а это наш сервис
host_name my-client2
}
# SSH
define service {
use dmz-ssh
host_name my-client2
}
[править] Пассивные проверки
Возможность nagios-а не инициировать проверку данных, а просто получать их от клиента (инициируется на стороне клиента) называется passive check.
Пассивные проверки делаются через дополнительный модуль: NSCA (Nagios Service Check Acceptor).
Сервер слушает - клиент когда надо отсылает.
[править] Сервер
В nagios.cfg проверяем стоят ли параметры
"check_external_commands=1"; "accept_passive_service_checks=1";
[править] ПО
ставим на сервере NSCA с суперсервером к нему:
emerge net-analyzer/nagios-nsca xinetd
Убедимся, что в файле /etc/nagios/nagios.cfg
есть строка:
command_file=/var/nagios/rw/nagios.cmd
Также эта строка должна быть в /etc/nagios/nsca.conf в этом же файле можно установить метод шифрования и пароль (должны совпадать с клиентом).
Настраиваем xinetd. Для этого создаем файл с описанием сервиса NSCA:
cat > /etc/xinetd.d/nsca <<EOF
service nsca
{
flags = REUSE
type = UNLISTED
port = 5667
socket_type = stream
wait = no
server = /usr/bin/nsca
server_args = -c /etc/nagios/nsca.cfg --inetd
user = nagios
group = nagios
log_on_failure += USERID
disable = no
}
EOF
echo "nsca 5667/tcp" >> /etc/services echo "nsca 5667/udp" >> /etc/services /etc/init.d/xinetd start rc-update add xinetd default netstat -alnp | grep xinet
[править] Настройки
в my_commands.cfg добавляем пустую команду
# dummy command for passive service
define command{
command_name check_dummy
command_line $USER1$/check_dummy $ARG1$
}
в my_templates описываем пассивный сервис
# passive service
define service {
use my-local-service
name passive-service
active_checks_enabled 0
passive_checks_enabled 1
max_check_attempts 1
check_command check_dummy!0
register 0
}
Теперь можно хосту добавить сервис на базе этого шаблона такого типа:
define service {
use passive-service
service_description test-passive
host_name my-dev
}
[править] Клиент
На клиенте ставим nsca клиент:
emerge net-analyzer/nagios-nsca
Теперь можно проверить правильно ли работает сервис, отправив ему сообщение через send_nsca в таком формате:
<hostname>[tab]<service_name>[tab]<return_code>[tab]<output>[\n]
Пример:
printf "%s\t%s\t%d\t%s\n" "my-dev" "test-passive" 0 "All Ok" | /usr/lib/nagios/plugins/send_nsca -H mon.lan -c /etc/nagios/send_nsca.cfg
- ! Обязательно добавить пользователя, от которого будет рассылаться - в группу nagios !
[править] Скрипт
Скрипт как понятно из определения сервиса - будет выполняться на клиенте к примеру по крону, и отправлять данные по необходимости. Вот пример:
NSCA_SERVER=mon.lan
NSCA_SERVICE="Postgres Connect Error"
NSCA_HOST="my-dev"
if [ ! -z "$1" ]; then
NSCA_HOST="$1"
fi
function nsca () {
printf "%s\t%s\t%d\t%s\n" "$NSCA_HOST" "$NSCA_SERVICE" "$ERROR" "$MSG" | /usr/lib/nagios/plugins/send_nsca -H $NSCA_SERVER -c /etc/nagios/send1
}
...
# warning here
MSG="WARNING: Try $COUNT times | res=$RES count=$COUNT"
ERROR=1
nsca
echo $MSG
exit $ERROR
...
# error here
MSG="CRITICAL: Try $COUNT times | res=$RES count=$COUNT"
ERROR=2
nsca
echo $MSG
exit $ERROR
[править] Ссылки
- http://ru.wikipedia.org/wiki/Nagios - о Nagios
- http://www.nagios.org - официальный сайт Nagios
- http://www.nagios.org/about/screenshots.php - скриншоты Nagios
- http://nagios.manubulon.com/ - некоторые плагины к Nagios
- http://blogs.techrepublic.com.com/opensource/?p=321 - удаленный мониторинг через SSH


