Начнём с самого главного файла icinga2.conf, по сути он содержит ссылки на конфигурационные файлы и описание содержимого этих самых файлов.
Первая ссылка:
include "constants.conf"
включает файл в котором мы будем хранить глобальные константы, глянем на них:
const PluginDir = "/usr/local/libexec/icinga2"
const CustomPluginDir = "/usr/local/libexec/icinga2/my_libexec"
const ManubulonPluginDir = "/usr/lib64/nagios/plugins"
const PluginContribDir = "/usr/lib64/nagios/plugins"
const ZoneName = NodeName
const TicketSalt = ""
Первая константа указывает директорию с плагинами из набора с сайта www.monitoring-plugins.org.
Вторая константа указывает директорию с самописными плагинами.
Третья и четвертая константы дефотные и не используются.
Далее будет видно как можно использовать константы определяющие директории с плагинами. Здесь нужно отметить гибкость конфигурации Icinga2, а именно, имена констант мы можем сами придумывать, можем хоть для каждого плагина создать константу, можем раскидать плагины по файловой системе случайным или весьма обдуманным способом.
Последние две константы используются в кластерной конфигурации, пока на них можно не обращать внимание.
Как видно с определением констант не должно возникнуть сложностей, опять глянем в icinga2.conf:
include "zones.conf"
включается файлик для настройки зоны, кластер пока не рассматриваем и пропускаем этот файл.
include <itl>
include <plugins>
включаем Icinga Template Library (ITL) и основные плагины.
Заходим в /usr/share/icinga2/include и видим файлы с этими именами, посмотрев содержимое станет понятно, что это и как это можно будет использовать. Но на данном этапе проще пропустить это действие и вернуться уже после того как появится хотя бы минимально представление о настройке icinga2.
include "features-enabled/*.conf"
указывает где смотреть включенные фичи, оставляем дефолотным
include_recursive "repository.d"
указываем директорию где будут храниться конфигурации объектов настроенных через командный интерфейс 'icinga2 repository', на данном этапе можно смело пропускать настройку этой опции.
Но стоит отметь оператор который используется, по названию видно, что icinga2 будет шерстить рекурсивно в этой директории, что может быть очень удобным и этим обязательно воспользуемся в следующей опции:
include_recursive "conf.d"
все что будет находиться в этой директории с расширением ".conf" будет использовано как конфигурационный файл.
Рассмотрим содержимое этой директории.
Файл commands.conf изначально почему то содержит конфигурацию команд уведомлений, мы создадим отдельный файл для этой цели и соответствующим названием.
Здесь же будем настраивать команды которые непосредственно используются для проверки состояния объектов мониторинга.
Команда создаётся как объект типа CheckCommand
object CheckCommand "check-name" {
}
check-name - имя команды, в блоке заключенным в фигурные скобки будем использовать следующее:
import "plugin-check-command"
импортируем необходимые методы для работы с командами, будем считать, что является необходимой и обязательной опцией. (Конечно экспериментаторам всё пути доступны).
command = [ PluginDir + "/check_name" ]
здесь определяем путь к исполняемому файлу, используемого при проверке, т.н. плагину, является обязательным.
PluginDir -- имя константы, определенной в constants.conf ;
check_name -- имя самого файла.
Вот для чего и были нужны константы, можно обойтись и без них, просто указать полный путь к файлу.
Следующие две опции не являются обязательными, но вполне удобны для использования:
1) Аргументы, которые принимает плагин, в основном применяется для стандартных плагинов и плагинов где аргументы предаются парами ключ-значение.
Лучше показать на примерах:
arguments = {
"-F" = "$mrtg_log_file$"
"-a" = "$mrtg_type$"
"-w" = "$mrtg_warning$"
"-c" = "$mrtg_critical$"
"-e" = "$mrtg_expire_minutes$"
}
arguments = {
"-H" = "$pop_address$"
"-w" = "$pop_warning$"
"-c" = "$pop_critical$"
}
в левой части указывается флаг/ключ, в правой переменная значение которой и будет передано с соответствующим флагом.
2) Переменные. Нам ведь нужно как то задать значения переменным, которые мы создали выше, например:
vars.pop_address = "$address$"
vars.pop_warning = "1"
vars.pop_critical = "2"
$address$ -- внутрення переменная icinga2, содержит адрес указанный у объекта мониторинга, см. здесь (TODO).
"1" и "2" значения, т.е. плагин будет выполнен так:
/реальный/путь/check_pop -H <реальный_адрес> -w 1 -c 2
Видно, что можно было сразу определить значения аргументов, так что в этом случае можно было бы обойтись без использования переменных.
В случае если плагин примает аргументы без флагов, а просто по порядку, то можно определить их так:
command = [ CustomPluginDir + "/check_snmp_linux", "$address$", "load", "$load_1_w$", "$load_5_w$", "$load_15_w$", "$load_1_c$", "$load_5_c$", "$load_15_c$" ]
и задать значения переменным.
Кому лень заморачиваться переменными, аргументами, могут определить команду сразу, указав необходимы параметры.
Перейдём к следующему файлу, к commands_notifications.conf
В нём создадим команды для уведомлений, типа такой:
object NotificationCommand "mail-host-notification" {
import "plugin-notification-command"
command = [ SysconfDir + "/icinga2/scripts/mail-host-notification.sh" ]
env = {
NOTIFICATIONTYPE = "$notification.type$"
HOSTALIAS = "$host.display_name$"
HOSTADDRESS = "$address$"
HOSTSTATE = "$host.state$"
LONGDATETIME = "$icinga.long_date_time$"
SHORTDATETIME = "$icinga.short_date_time$"
HOSTOUTPUT = "$host.output$"
NOTIFICATIONAUTHORNAME = "$notification.author$"
NOTIFICATIONCOMMENT = "$notification.comment$"
HOSTDISPLAYNAME = "$host.display_name$"
USEREMAIL = "$user.email$"
}
}
Особых отличий от настройки команды немного, для уведомлений есть свой тип объекта и методы, импортируемые во второй строке.
Исполняемый файл задается аналогично команде, даже используется тот же самый оператор.
Заглядываем в mail-host-notification.sh и понимаем, как просто русифицировать текст сообщений уведомления и как можно писать любые плагины для отправки уведомлений различными способами (netsend, jabber, etc):
#!/bin/sh
case "$NOTIFICATIONTYPE" in
"RECOVERY" ) NOTIFICATIONTYPE="ПЕРЕХОД НА НОРМАЛЬНЫЙ РЕЖИМ" ;;
"PROBLEM" ) NOTIFICATIONTYPE="ПРОБЛЕМА" ;;
esac
case "$HOSTSTATE" in
"UP" ) HOSTSTATE="ДОСТУПЕН ПО СЕТИ" ;;
"DOWN" ) HOSTSTATE="НЕ ДОСТУПЕН ПО СЕТИ" ;;
esac
template=`cat <<TEMPLATE
***** Система мониторинга *****
Тип уведомления: $NOTIFICATIONTYPE
Узел: $HOSTALIAS
Адрес: $HOSTADDRESS
Состояние: $HOSTSTATE
Дата/Время: $SHORTDATETIME
Дополнительная информация: $HOSTOUTPUT
Комментарии: [$NOTIFICATIONAUTHORNAME] $NOTIFICATIONCOMMENT
TEMPLATE
`
/usr/bin/printf "%b" "$template" | mail -s "$NOTIFICATIONTYPE - $HOSTDISPLAYNAME is $HOSTSTATE" $USEREMAIL
В блоке env мы производим передачу значений из перменных системы мониторинга в переменные плагина уведомления.
Описание всех доступных переменных можно посмотреть в документации или здесь (TODO).
Следующий файл downtimes.conf
Пропускаем.
У меня следующим идёт functions.conf
Пропускаем и его, т.к. используется для функций которые вызываются другими конфигами, эту возможность рассмотрим позже.
Файл groups.conf определяет группы:
object HostGroup "name" {
display_name = "Алиас"
}
Файл hosts.conf содержит настройку локального узла, логичнее его перенести в место хранение группы к которой принадлежит данный узел.
Как настраиваются объекты мониторинга, в частности узлы, будет рассмотрено здесь (TODO).
Далее в файле notifications.conf определяется кому, как и при каких условия слать уведомления.
apply Notification "mail-icingaadmin" to Host {
import "mail-host-notification"
user_groups = [ "icingaadmins" ]
interval = 0
assign where host.address
}
Уведомления уже не создаются, а применяются, т.е. нам нужно дать уведомлению имя, в данном случае "mail-icingaadmin", выбрать к узлу (to Host) или к сервису (to Service) применяется это уведомление.
Импортировать необходимые методы, определить группу пользователей (см. ниже), параметр user_groups и назначить некие условия, по которым определяются узлы или сервисы к которым должно примениться это уведомление.
В рассматриваемом примере уведомление применяется ко всем узлам имеющим адрес:
assign where host.address
Конечно более подробные описания приведены в официальной документации (TODO), а здесь я приведу пару примеров для наглядности:
ignore where service.name == "TRAP"
assign where host.vars.os in [ "Windows", "Linux" ]
С такими простыми условиями не должно возникнуть сложностей, условия можно писать в несколько строк если их больше чем одно, а также можно объединять логическими операциями (TODO).
interval = 0 отключает повторную отправку уведомления.
Так же в блоке применения уведомления можно попробовать определить некое условие и при его истинности выполнить некие действия, например:
if (service.name == "load") {
times.begin = 15m
}
Использование условных операторов, циклов и функций делает очень гибкими и весьма удобными конфигурационные файлы, попробуем разобраться с ними здесь (TODO).
Следующий файл satellite.conf пропускаем.
services.conf пропускаем и использовать не будем, сервисы будем настраивать здесь (TODO).
Далее идёт файл шаблонов templates.conf.
template Host "generic-host" {
max_check_attempts = 3
check_interval = 1m
retry_interval = 30s
check_command = "hostalive"
}
Создаем шаблон для узла с именем "generic-host", проверяем узел каждую минуту, в случае неудачной проверки производим повторную проверку через 30 секунд и максимальное таких перепроверок 3 штуки.
Для проверки используется команда hostalive , выше мы встречали include <plugins> в основном конфигурационном файле, что и даёт нам возможность использовать эту команду (см. /usr/share/icinga2/include/plugins).
Шаблон для сервиса:
template Service "generic-service" {
max_check_attempts = 5
check_interval = 1m
retry_interval = 30s
}
Для пользователя:
template User "generic-user" {
}
По умолчанию он пустой.
И шаблон для уведомлений:
template Notification "mail-host-notification" {
command = "mail-host-notification"
states = [ Up, Down ]
types = [ Problem, Acknowledgement, Recovery, Custom,
FlappingStart, FlappingEnd,
DowntimeStart, DowntimeEnd, DowntimeRemoved ]
period = "24x7"
}
В принципе всё просто, указан тип шаблона, его имя, команда. Выбраны состояния на которые реагировать и типы изменений.
Период выбран, а настраивается он в следующем файле timeperiods.conf.
object TimePeriod "24x7" {
import "legacy-timeperiod"
display_name = "Icinga 2 24x7 TimePeriod"
ranges = {
"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"
}
}
Там же есть дефолтные периоды "9to5" и "never", для начала их должно хватить, ну или можно изменить часы рабочего времени.
Последний файл с пользователями и группами users.conf:
object User "icingaadmin" {
import "generic-user"
display_name = "Icinga 2 Admin"
groups = [ "icingaadmins" ]
email = "address@mail.local"
vars.jabber = "nickname@jabba.local"
}
Создаём оъект пользователь, присваиваем ему имя, импортируем необходимые методы, указываем имя которое будет отображаться в web-интерфейсе, закидываем в группу.
Указываем значения внутренней переменной email и созданной нами vars.jabber.
Группу тоже необходимо создать:
object UserGroup "icingaadmins" {
display_name = "Группа админов"
}
И так, основные конфигурационные файлы бегло рассмотрели, осталось разобраться с настройкой узлов и сервисов и с теми моментами которые были пропущены. В какой то момент времени и это появится здесь.
Да прибудет с тобой icinga ;)
Первая ссылка:
include "constants.conf"
включает файл в котором мы будем хранить глобальные константы, глянем на них:
const PluginDir = "/usr/local/libexec/icinga2"
const CustomPluginDir = "/usr/local/libexec/icinga2/my_libexec"
const ManubulonPluginDir = "/usr/lib64/nagios/plugins"
const PluginContribDir = "/usr/lib64/nagios/plugins"
const ZoneName = NodeName
const TicketSalt = ""
Первая константа указывает директорию с плагинами из набора с сайта www.monitoring-plugins.org.
Вторая константа указывает директорию с самописными плагинами.
Третья и четвертая константы дефотные и не используются.
Далее будет видно как можно использовать константы определяющие директории с плагинами. Здесь нужно отметить гибкость конфигурации Icinga2, а именно, имена констант мы можем сами придумывать, можем хоть для каждого плагина создать константу, можем раскидать плагины по файловой системе случайным или весьма обдуманным способом.
Последние две константы используются в кластерной конфигурации, пока на них можно не обращать внимание.
Как видно с определением констант не должно возникнуть сложностей, опять глянем в icinga2.conf:
include "zones.conf"
включается файлик для настройки зоны, кластер пока не рассматриваем и пропускаем этот файл.
include <itl>
include <plugins>
включаем Icinga Template Library (ITL) и основные плагины.
Заходим в /usr/share/icinga2/include и видим файлы с этими именами, посмотрев содержимое станет понятно, что это и как это можно будет использовать. Но на данном этапе проще пропустить это действие и вернуться уже после того как появится хотя бы минимально представление о настройке icinga2.
include "features-enabled/*.conf"
указывает где смотреть включенные фичи, оставляем дефолотным
include_recursive "repository.d"
указываем директорию где будут храниться конфигурации объектов настроенных через командный интерфейс 'icinga2 repository', на данном этапе можно смело пропускать настройку этой опции.
Но стоит отметь оператор который используется, по названию видно, что icinga2 будет шерстить рекурсивно в этой директории, что может быть очень удобным и этим обязательно воспользуемся в следующей опции:
include_recursive "conf.d"
все что будет находиться в этой директории с расширением ".conf" будет использовано как конфигурационный файл.
Рассмотрим содержимое этой директории.
Файл commands.conf изначально почему то содержит конфигурацию команд уведомлений, мы создадим отдельный файл для этой цели и соответствующим названием.
Здесь же будем настраивать команды которые непосредственно используются для проверки состояния объектов мониторинга.
Команда создаётся как объект типа CheckCommand
object CheckCommand "check-name" {
}
check-name - имя команды, в блоке заключенным в фигурные скобки будем использовать следующее:
import "plugin-check-command"
импортируем необходимые методы для работы с командами, будем считать, что является необходимой и обязательной опцией. (Конечно экспериментаторам всё пути доступны).
command = [ PluginDir + "/check_name" ]
здесь определяем путь к исполняемому файлу, используемого при проверке, т.н. плагину, является обязательным.
PluginDir -- имя константы, определенной в constants.conf ;
check_name -- имя самого файла.
Вот для чего и были нужны константы, можно обойтись и без них, просто указать полный путь к файлу.
Следующие две опции не являются обязательными, но вполне удобны для использования:
1) Аргументы, которые принимает плагин, в основном применяется для стандартных плагинов и плагинов где аргументы предаются парами ключ-значение.
Лучше показать на примерах:
arguments = {
"-F" = "$mrtg_log_file$"
"-a" = "$mrtg_type$"
"-w" = "$mrtg_warning$"
"-c" = "$mrtg_critical$"
"-e" = "$mrtg_expire_minutes$"
}
arguments = {
"-H" = "$pop_address$"
"-w" = "$pop_warning$"
"-c" = "$pop_critical$"
}
в левой части указывается флаг/ключ, в правой переменная значение которой и будет передано с соответствующим флагом.
2) Переменные. Нам ведь нужно как то задать значения переменным, которые мы создали выше, например:
vars.pop_address = "$address$"
vars.pop_warning = "1"
vars.pop_critical = "2"
$address$ -- внутрення переменная icinga2, содержит адрес указанный у объекта мониторинга, см. здесь (TODO).
"1" и "2" значения, т.е. плагин будет выполнен так:
/реальный/путь/check_pop -H <реальный_адрес> -w 1 -c 2
Видно, что можно было сразу определить значения аргументов, так что в этом случае можно было бы обойтись без использования переменных.
В случае если плагин примает аргументы без флагов, а просто по порядку, то можно определить их так:
command = [ CustomPluginDir + "/check_snmp_linux", "$address$", "load", "$load_1_w$", "$load_5_w$", "$load_15_w$", "$load_1_c$", "$load_5_c$", "$load_15_c$" ]
и задать значения переменным.
Кому лень заморачиваться переменными, аргументами, могут определить команду сразу, указав необходимы параметры.
Перейдём к следующему файлу, к commands_notifications.conf
В нём создадим команды для уведомлений, типа такой:
object NotificationCommand "mail-host-notification" {
import "plugin-notification-command"
command = [ SysconfDir + "/icinga2/scripts/mail-host-notification.sh" ]
env = {
NOTIFICATIONTYPE = "$notification.type$"
HOSTALIAS = "$host.display_name$"
HOSTADDRESS = "$address$"
HOSTSTATE = "$host.state$"
LONGDATETIME = "$icinga.long_date_time$"
SHORTDATETIME = "$icinga.short_date_time$"
HOSTOUTPUT = "$host.output$"
NOTIFICATIONAUTHORNAME = "$notification.author$"
NOTIFICATIONCOMMENT = "$notification.comment$"
HOSTDISPLAYNAME = "$host.display_name$"
USEREMAIL = "$user.email$"
}
}
Особых отличий от настройки команды немного, для уведомлений есть свой тип объекта и методы, импортируемые во второй строке.
Исполняемый файл задается аналогично команде, даже используется тот же самый оператор.
Заглядываем в mail-host-notification.sh и понимаем, как просто русифицировать текст сообщений уведомления и как можно писать любые плагины для отправки уведомлений различными способами (netsend, jabber, etc):
#!/bin/sh
case "$NOTIFICATIONTYPE" in
"RECOVERY" ) NOTIFICATIONTYPE="ПЕРЕХОД НА НОРМАЛЬНЫЙ РЕЖИМ" ;;
"PROBLEM" ) NOTIFICATIONTYPE="ПРОБЛЕМА" ;;
esac
case "$HOSTSTATE" in
"UP" ) HOSTSTATE="ДОСТУПЕН ПО СЕТИ" ;;
"DOWN" ) HOSTSTATE="НЕ ДОСТУПЕН ПО СЕТИ" ;;
esac
template=`cat <<TEMPLATE
***** Система мониторинга *****
Тип уведомления: $NOTIFICATIONTYPE
Узел: $HOSTALIAS
Адрес: $HOSTADDRESS
Состояние: $HOSTSTATE
Дата/Время: $SHORTDATETIME
Дополнительная информация: $HOSTOUTPUT
Комментарии: [$NOTIFICATIONAUTHORNAME] $NOTIFICATIONCOMMENT
TEMPLATE
`
/usr/bin/printf "%b" "$template" | mail -s "$NOTIFICATIONTYPE - $HOSTDISPLAYNAME is $HOSTSTATE" $USEREMAIL
В блоке env мы производим передачу значений из перменных системы мониторинга в переменные плагина уведомления.
Описание всех доступных переменных можно посмотреть в документации или здесь (TODO).
Следующий файл downtimes.conf
Пропускаем.
У меня следующим идёт functions.conf
Пропускаем и его, т.к. используется для функций которые вызываются другими конфигами, эту возможность рассмотрим позже.
Файл groups.conf определяет группы:
object HostGroup "name" {
display_name = "Алиас"
}
Файл hosts.conf содержит настройку локального узла, логичнее его перенести в место хранение группы к которой принадлежит данный узел.
Как настраиваются объекты мониторинга, в частности узлы, будет рассмотрено здесь (TODO).
Далее в файле notifications.conf определяется кому, как и при каких условия слать уведомления.
apply Notification "mail-icingaadmin" to Host {
import "mail-host-notification"
user_groups = [ "icingaadmins" ]
interval = 0
assign where host.address
}
Уведомления уже не создаются, а применяются, т.е. нам нужно дать уведомлению имя, в данном случае "mail-icingaadmin", выбрать к узлу (to Host) или к сервису (to Service) применяется это уведомление.
Импортировать необходимые методы, определить группу пользователей (см. ниже), параметр user_groups и назначить некие условия, по которым определяются узлы или сервисы к которым должно примениться это уведомление.
В рассматриваемом примере уведомление применяется ко всем узлам имеющим адрес:
assign where host.address
Конечно более подробные описания приведены в официальной документации (TODO), а здесь я приведу пару примеров для наглядности:
ignore where service.name == "TRAP"
assign where host.vars.os in [ "Windows", "Linux" ]
С такими простыми условиями не должно возникнуть сложностей, условия можно писать в несколько строк если их больше чем одно, а также можно объединять логическими операциями (TODO).
interval = 0 отключает повторную отправку уведомления.
Так же в блоке применения уведомления можно попробовать определить некое условие и при его истинности выполнить некие действия, например:
if (service.name == "load") {
times.begin = 15m
}
Использование условных операторов, циклов и функций делает очень гибкими и весьма удобными конфигурационные файлы, попробуем разобраться с ними здесь (TODO).
Следующий файл satellite.conf пропускаем.
services.conf пропускаем и использовать не будем, сервисы будем настраивать здесь (TODO).
Далее идёт файл шаблонов templates.conf.
template Host "generic-host" {
max_check_attempts = 3
check_interval = 1m
retry_interval = 30s
check_command = "hostalive"
}
Создаем шаблон для узла с именем "generic-host", проверяем узел каждую минуту, в случае неудачной проверки производим повторную проверку через 30 секунд и максимальное таких перепроверок 3 штуки.
Для проверки используется команда hostalive , выше мы встречали include <plugins> в основном конфигурационном файле, что и даёт нам возможность использовать эту команду (см. /usr/share/icinga2/include/plugins).
Шаблон для сервиса:
template Service "generic-service" {
max_check_attempts = 5
check_interval = 1m
retry_interval = 30s
}
Для пользователя:
template User "generic-user" {
}
По умолчанию он пустой.
И шаблон для уведомлений:
template Notification "mail-host-notification" {
command = "mail-host-notification"
states = [ Up, Down ]
types = [ Problem, Acknowledgement, Recovery, Custom,
FlappingStart, FlappingEnd,
DowntimeStart, DowntimeEnd, DowntimeRemoved ]
period = "24x7"
}
В принципе всё просто, указан тип шаблона, его имя, команда. Выбраны состояния на которые реагировать и типы изменений.
Период выбран, а настраивается он в следующем файле timeperiods.conf.
object TimePeriod "24x7" {
import "legacy-timeperiod"
display_name = "Icinga 2 24x7 TimePeriod"
ranges = {
"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"
}
}
Там же есть дефолтные периоды "9to5" и "never", для начала их должно хватить, ну или можно изменить часы рабочего времени.
Последний файл с пользователями и группами users.conf:
object User "icingaadmin" {
import "generic-user"
display_name = "Icinga 2 Admin"
groups = [ "icingaadmins" ]
email = "address@mail.local"
vars.jabber = "nickname@jabba.local"
}
Создаём оъект пользователь, присваиваем ему имя, импортируем необходимые методы, указываем имя которое будет отображаться в web-интерфейсе, закидываем в группу.
Указываем значения внутренней переменной email и созданной нами vars.jabber.
Группу тоже необходимо создать:
object UserGroup "icingaadmins" {
display_name = "Группа админов"
}
И так, основные конфигурационные файлы бегло рассмотрели, осталось разобраться с настройкой узлов и сервисов и с теми моментами которые были пропущены. В какой то момент времени и это появится здесь.
Да прибудет с тобой icinga ;)