Опять статья Кропачева Артемия (aka neon), сентябрь 2006.
Думаю будет полезна администраторам, ибо часто нужно знать что творится у вас в сети и при ходе из строя сервером можно заметить, где обрыв и когда произошел.
Мониторинг интерфейсов сети с помощью netmond и rrdtool
Введение
С ростом размера компьютерной сети, увеличением количества работающих серверов и сервисов, увеличением числа обслуживаемых клиентов и пользователей, а так же увеличением их критичности всё более актуальной задачей является необходимость своевременного устранения сбоев, а, следовательно, своевременного их нахождения, другими словами - мониторинг сети.
На мой взгляд, наиболее часто встречающимися задачами мониторинга локальной сети являются:
- определение доступности/недоступности оборудования, серверов и сервисов
- проверка каналов передачи данных (доступность, загруженность)
- сохранение и просмотр статистики на интерфейсах коммутаторов и серверов (байты, пакеты и ошибки)
- сохранение и просмотр различных параметров сервисов и объектов (например, загрузка CPU маршрутизаторов, размер свободного дискового пространства на файловых серверах, количество подключённых модемных пользователей на Cisco и другие).
Существует большое количество уже готовых систем мониторинга: nagios, mrtg, zabbix,cacti. Настройка "полной" системы мониторинга является достаточно сложной задачей и выходит за рамки данной статьи.
Любой системный администратор рано или поздно и ввиду различных задач сталкивается с необходимостью анализа закономерностей сетевого трафика в течении часов, суток, месяцев и т.п. Пожалуй, наиболее удобным способом является просмотр графиков пакетных и байтовых нагрузок на каналах.
Данная статья ставит своей задачей донести до читателя мой личный опыт по отображению статистики на интерфейсах серверов и оборудования в наглядном виде (графики). Эта проблема может быть решена большим количеством способов (например cacti, mrtg), но я реализовал именно этот, чем и хочу поделиться.
Используемое программное обеспечение
Для решения поставленной задачи потребуются:
- netmond - сердце системы, выполняет опрос объектов
Домашняя страница производителя RINET Software Team находится по адресу http://soft.risp.ru/ , там имеется очень хорошая документация о продукте на русском языке. Netmond представляет из себя некий серверный инструмент, позволяющий собирать данные со всех объектов и сервисов сети в одном месте (сервере мониторинга) и в удобном для использования виде (в нашем случае это rrdtool, возможно хранить данные в SQL базах данных)
- rrdtool - средство сохранения (база данных) и отображения статистики (утилиты построения изображений)
За информацией о rrdtool можно обращаться на сайт http://www.rrdtool.org. Есть очень неплохая статья про работу с этой базой http://www.bog.pp.ru/work/rrdtool.html на русском языке. В man страницах подробно описаны все утилиты работы см. man rrdtool. Стоит более подробно ознакомится с man страницами по rrdcreate, rrdupdate, rrdgraph.
- Perl - скрипты для сохранения и отображения данных
- Apache - веб сервер
- Пакет Net-SNMP - для удобства проверки работы протокола snmp
Netmond будет выполнять роль системы получения данных по протоколу SNMP, а так же будет сохранять данные загрузки интерфейсов в базу rrdtool через внешний скрипт на Perl. Работа с сохранёнными данными возможна из командной строки и средствами скриптов. Для удобства использования написан скрипт отображения результатов в Web интерфейсе.
Настройка системы мониторинга производилась на базе операционной системы FreeBSD (4.x, 5.x, 6.x), но всё ниже написанное, думаю, можно будет перенести на Linux (изменится в основном способ установки ПО и место размещения конфигурационных файлов).
Установка
Чтобы приступить к настройке системы ставим необходимое программное обеспечение. Вся установка велась из портов FreeBSD. Если у кого-то есть желание ставить из исходников или пакетов - пожалуйста.
- Perl:
#
Код:
cd /usr/ports/lang/perl5.8 && make install clean
- Ставим rrdtool (на момент написания статьи версия 1.2.15):
#
Код:
cd /usr/ports/net/rrdtool && make install clean
- Ставим netmond:
#
Код:
cd /usr/ports/net-mgmt/netmond && make install clean
- Пакет Net-SNMP:
#
Код:
cd /usr/ports/net-mgmt/net-snmp && make install clean
- Ставим, настраиваем и запускаем www сервер apache.
Настройка netmond
Конфигурационный файл
netmond лежит в файле
/usr/local/etc/netmon.conf.sample. Переименовываем его в
netmon.conf и редактируем:
#
mv /usr/local/etc/netmon.conf.sample /usr/local/etc/netmon.conf
#
vi /usr/local/etc/netmon.conf
Ниже будет дан пример конфигурационного файла с описанием.
Код:
RootDir "/var/netmon" # Каталог для сохранения данных
Polling 60 # Время опроса объектов мониторинга (в секундах)
Timeout 2 # Время ожидания ответа на запрос (в секундах)
Retries 3 # Количество переповторов
Saving 60 # Интервал периодического сохранения данных(60 секунд)
TimeFmt "%H:%M:%S" # Формат времени
# Группы доступа к netstate
Group "local" {
Permit "^localhost$"
Permit "^127\\.0\\.0\\.1$"
Deny ".*"
}
Group "remote" {
Permit "^172\\.21\\.81\\."
}
NetState {
Port 3333
# Порт netstate сервера
Timeout 30
Group "local"
Group "remote"
}
Save "make_dir" {
# метод сохранения для создания каталога
File ""
When "0" 0
}
Save "save_rrd_if" {
# Определяем метод сохранения статистики интерфейсов в rrd базу
Pipe "/usr/local/sbin/rrdsave"
# Вызываем скрипт /usr/local/sbin/rrdsave и передаём ему данные на стандартный вход (директива Pipe)
# Возможен вариант с Exec тогда данные будут переданы в командной строке
# После директивы Data идут данные, можно писать с новой строки в кавычках
# Передаём разницу показателей счётчиков байт, много- и моноадресных пакетов, ошибок, дропов на
интерфейсе, для которого данный метод сохранения прописан в разделе объектов мониторинга
Data
"$DATADIR/rrdint\n"
"60\n"
"RRA:AVERAGE:0.5:1:10080 RRA:AVERAGE:0.5:5:10080 RRA:AVERAGE:0.5:60:10080
RRA:AVERAGE:0.5:3600:10080\n"
"${ifOperStatus}:ifoperstatus:GAUGE:600:0:1.25\n"
"${ifInOctets.delta}:ifinoctets:GAUGE:600:0:U\n"
"${ifOutOctets.delta}:ifoutoctets:GAUGE:600:0:U\n"
"${ifInErrors.delta}:ifinerrors:GAUGE:600:0:U\n"
"${ifOutErrors.delta}:ifouterrors:GAUGE:600:0:U\n"
"${ifInDrops.delta}:ifindrops:GAUGE:600:0:U\n"
"${ifOutDrops.delta}:ifoutdrops:GAUGE:600:0:U\n"
"${ifInUcastPkts.delta}:ifinucastpkts:GAUGE:600:0:U\n"
"${ifOutUcastPkts.delta}:ifoutucastpkts:GAUGE:600:0:U\n"
"${ifInNUcastPkts.delta}:ifinncastpkts:GAUGE:600:0:U\n"
"${ifOutNUcastPkts.delta}:ifoutncastpkts:GAUGE:600:0:U"
}
# ****Здесь начинается раздел описания объектов мониторинга********
Object "Cisco_catalyst" {
# Определяем объект мониторинга - коммутатор Cisco
Address "172.21.80.11" # Адрес, по которому будем опрашивать
Method router "public"
# Определяем стандартный метод опроса router с известной строкой community
Save "make_dir"
Interface "FastEthernet0/1" {
# Определяем интерфейс на коммутаторе по его ifName
# Предопределяем методы сохранения данных на данном интерфейсе
# первый метод нужен для определения переменной DATATDIR
# Второй выполняет сохранение данных
Save "make_dir"
Save "save_rrd_if"
}
Interface 2 {
# Определяем интерфейс по значению ifIndex (по номеру)
Save "make_dir"
Save "save_rrd_if"
}
}
Object "Server" {
Address "172.21.8.1"
Method router "mysnmpcommunity"
Save "make_dir"
Interface "fxp0" {
Save "make_dir"
Save "save_rrd_if"
}
Interface "fxp1"{
Save "make_dir"
Save "save_rrd_if"
}
Interface "em0"{
Save "make_dir"
Save "save_rrd_if"
}
}
Структура конфигурационного файла подробно описана на сайте производителя, я остановлюсь лишь на нескольких важных деталях. Весь конфигурационный файл состоит из 5 основных частей:
- Установка глобальных переменных.
- Параметры работы netstate протокола.
- Пользовательские методы опроса объектов и сервисов (в приведённом конфигурационном файле не используются)
- Пользовательские методы сохранения данных.
- Раздел описания объектов, сервисов и интерфейсов мониторинга.
Параметр Saving изменён с 300 на 60. Необходимо для правильного сохранения минутных статистик в базу rrdtool. Переменная RootDir содержит путь до каталога куда netmond будет сохранять полученные данные прописанными методами сохранения. Следует предусмотреть достаточный объём свободного места на разделе (Файл rrdtool для одного интерфейса в нашем случае будет занимать порядка 3,5 Мб).
В примере конфига добавлено для примера два объекта мониторинга: коммутатор Cisco и сервер на базе FreeBSD. В свойствах объекта мониторинга задаётся его IP адрес, метод опроса, и методы сохранения данных. Мы используем встроенный метод опроса router, который считывает по SNMP статистику с интерфейсов и некоторую другую информацию. Методу передаётся 1 параметр (выражение в кавычках после названия метода)- строка community (что то типа пароля для доступа к данным по SNMP).
В параметрах объектов описано так несколько интерфейсов: один по названию (по IfName), второй по номеру (по IfIndex). Кому как удобнее пользоваться. Например, при установке службы SNMP в MS Windows у интерфейсов вообще ifName отсутствует, так что приходится пользоваться только вторым способом.
Для каждого интерфейса прописано 2 метода сохранения данных: "make_dir" и "save_rrd_if".
Метод сохранения данных "save_rrd_if" передаёт данные собранные встроенным методом опроса "router" (показатели счётчиков байт, пакетов, дропов, ошибок), имя файла rrdtool базы куда надо данные поместить (берётся из переменной netmond "DATADIR"), а так же параметры базы rrdtool необходимые для её создания и последующего обновления на вход скрипта /usr/local/sbin/rrdsave. Если файл базы не существует скрипт его создаёт, если существует - то добавляет/обновляет в нём данные.
Опишу подробнее строки с данными (после директивы Data):
- "$DATADIR/rrdint\n" - путь до файла, в нашем случае rrdint, переменная DATADIR содержит путь до каталога, где хранятся данные данного объекта/сервиса/интерфейса (в нашем случае для интерфейса).
- "60\n" - время в секундах, как часто будет обновляется база. Параметр необходим при создании базы.
- "RRA:AVERAGE:0.5:1:10080 RRA:AVERAGE:0.5:5:10080 RRA:AVERAGE:0.5:60:10080 RRA:AVERAGE:0.5:3600:10080\n" RRA строки - параметр создания базы: определяем количества ячеек тип.
Общий формат:
RRA:функция-консолидации:x-доля:отсчетов-на-ячейку:число-ячеек
Функции консолидации определяют как и какие отсчёты группировать в одну ячейку (у нас методом усреднения, возможны так же MAX, MIN, TOTAL, LAST). Создаём 10080 ячеек под минутные отчёты (1 отсчёт по 60 секунд), 10080 ячеек под 5 минутные (5 отсчётов), сколько же под часовые (60 отсчётов) и т.д.. Если кому жалко место на диске, можно без проблем значительно уменьшить количество ячеек. Например вот так: "RRA:AVERAGE:0.5:1:1440 RRA:AVERAGE:0.5:5:2016 RRA:AVERAGE:0.5:60:720 RRA:AVERAGE:0.5:3600:365\n"
- "${ifOperStatus}:ifoperstatus:GAUGE:600:0:1.25 \n" - передаём OperStatus для интерфейса в виде переменой ${ifOperStatus}, сохраняем как есть (тип GAUGE), максимальное значние 1.25.
- "${ifInOctets.delta}:ifinoctets:GAUGE:600:0:U\ n" - переедем переменную разницы счётчиков входящих байт между опросами. В базе имя столбца будет названо как ifinoctets. Думаю с остальными строками уже понятно
- "${ifOutOctets.delta}:ifoutoctets:GAUGE:600:0: U\n" (исходящий байты)
- "${ifInErrors.delta}:ifinerrors:GAUGE:600:0:U\ n" (ошибки)
- "${ifOutErrors.delta}:ifouterrors:GAUGE:600:0: U\n"
- "${ifInDrops.delta}:ifindrops:GAUGE:600:0:U\n" (дропы)
- "${ifOutDrops.delta}:ifoutdrops:GAUGE:600:0:U\ n"
- "${ifInUcastPkts.delta}:ifinucastpkts:GAUGE:600:0: U\n" (моноадресные пакеты)
- "${ifOutUcastPkts.delta}:ifoutucastpkts:GAUGE:600: 0:U\n"
- "${ifInNUcastPkts.delta}:ifinncastpkts:GAUGE:600:0 :U\n" (многоадресные пакеты)
- "${ifOutNUcastPkts.delta}:ifoutncastpkts:GAUGE:600 :0:U"
Метод "make_dir" необходимо вызывать до метода "save_rrd_if" для того лишь, чтобы определить переменную DATADIR. В противном случае без вызова метода File она будет не определена.
Скрипт для сохранения данных в rrdtool
Далее необходимо создать скрипт сохранения данных в базу rrd /usr/local/sbin/rrdsave. Вот его листинг:
Код:
#!/usr/local/bin/perl
my (@ds,$line,$exe);
my $FileName=<STDIN>;
my $TimeStep=<STDIN>;
my $RRAString=<STDIN>;
chomp($RRAString,$TimeStep,$FileName);
$FileName=~s/\"//g;
my $rrdtoolpath='/usr/local/bin/rrdtool';
my $num=-1;
while ( defined( $line=<STDIN> ) ) {
chomp($line); $num++; $ds[$num]=$line;
};
if( -e($FileName) ) {
$exe=$rrdtoolpath.' update '.$FileName.' --template';
my $dsname=''; my $value='';
foreach my $ds1 (@ds) {
my @prom=split/:/,$ds1;
$dsname=$dsname.$prom[1].':';
$value=$value.$prom[0].':';
};
$value=~s/:$//; $dsname=~s/:$//;
$exe=$exe.' '.$dsname.' N:'.$value;
system($exe);
} else {
$exe=$rrdtoolpath.' create '.$FileName.' --step '.$TimeStep;
foreach my $ds1 (@ds) {
$ds1=~s/^.+?://;
$exe=$exe.' DS:'.$ds1;
};
$exe=$exe.' '.$RRAString;
system($exe);
system('/bin/chmod 644 '.$FileName);
};
Изменим права доступа на данный скрипт:
Код:
# chmod 755 /usr/local/sbin/rrdsave
Запуск приложения
Приложение готово к запуску, запускаем кому как удобно:
Код:
# /usr/local/sbin/netmond
# /usr/local/etc/rc.d/netmond.sh start
(предварительно добавив в rc.conf 'netmond_enable="YES"')
# /usr/local/sbin/netmondctl start
Проверяем наличие процесса в памяти (# ps auxw|grep netmond), отсутствие ошибок в /var/log/messages, а так же наличие каталогов в RootDir:
Код:
# cd /var/netmon && ls
Единственный минусом можно назвать факт, что каталоги создались с правами 750. Для возможности работы системы отображения необходима возможность пользователю www иметь доступ к файлам, хранящимся в каталогах в /var/netmon. Для этого необходимо сменить права доступа на все подкаталоги, находящиеся в /var/netmon на 755. Самый быстрый (но не самый правильный) вариант:
Код:
# chmod -R 755 /var/netmon
Следует отметить, что все скрипты вызываемые из методов сохранения запускаются с правами пользователя netmon, так что необходимо предусмотреть возможность записи в каталоги с интерфейсами:
Код:
# cd /var/netmon
# chown -R netmon *
Через пару минут после запуска netmond можно проверить наличие файлов rrdint в подкаталогах интерфейсов. При желании можно посмотреть содержимое фалов следующим образом:
Код:
# rrdtool fetch rrdint AVERAGE, где rrdfilename - имя созданного файла.
Вот часть результат вывода данной команды:
Код:
ifoperstatus ifinoctets ifoutoctets ifinerrors ifouterrors ifindrops ifoutdrops ifinucastpkts ifoutucastpkts ifinncastpkts ifoutncastpkts
1156826040: nan nan nan nan nan nan nan nan nan nan nan
1156826100: nan nan nan nan nan nan nan nan nan nan nan
1156826160: nan nan nan nan nan nan nan nan nan nan nan
1156826220: nan nan nan nan nan nan nan nan nan nan nan
1156826280: nan nan nan nan nan nan nan nan nan nan nan
Информацию о файле можно посмотреть вот так:
Код:
# rrdtool info rrdint
Вот чать результата вывода команды:
Код:
filename = "rrdint"
rrd_version = "0003"
step = 60
last_update = 1156912412
ds[ifoperstatus].type = "GAUGE"
ds[ifoperstatus].minimal_heartbeat = 600
ds[ifoperstatus].min = 0.0000000000e+00
ds[ifoperstatus].max = 1.2500000000e+00
ds[ifoperstatus].last_ds = "UNKN"
Работа с netstate
Приведу немного изменённую цитату с soft.risp.ru:
Netmond хранит все накопленные данные о текущем состоянии сети у себя в памяти, в специально предназначенных контейнерах - переменных VARIABLE. Значения VARIABLE могут вводиться в программу по результатам работы системы сбора данных, а выводиться с помощью разнообразных методов сохранения SAVE. Однако вывод данных с помощью SAVE выполняется только по инициативе самого Netmond (периодически или в зависимости от каких-то условий) совершенно конкретных значений, предусмотренных конфигурацией программы. Что может быть очень удобно при решении задач накопления и долговременного хранения данных, но, например, практически не пригодно для задачи получения мгновенной актуальной картины состояния всей сети в реальном времени. Для решения задачи вывода любых данных в произвольные моменты времени в Netmond встроен специальный сервер NetState, который обеспечивает авторизованным сетевым клиентам асинхронный доступ ко всему массиву переменных VARIABLE на чтение.
Весь массив переменных VARIABLE представляется в виде иерархии имен переменных и их владельцев, разделенных специальным символом `!':
Обьект!Подобьект!Переменна я = Значение
Возможно получение текущих и предыдущих значений переменных, а также выбор интересующих переменных по REGEX-маскам на их имена.
Netstate сервер удобен для проверки правильности работы программы, а так же получения всех текущих переменных, например текущее показание счётчика байт на интерфейсе, состояние объекта (UP,DOWN), значение пользовательских переменных и т.п.
Подключение к netstate выполняется по команде:
Код:
# telnet 127.0.0.1 3333
В результате отобразится окно приветствия и сервер готов в выполнению команд пользователя:
NetState server ready (timeout 30 sec.)
Compress: ZLIB 1.2.2
!
В процессе отладки системы неплохо бы узнать основные команды. Приведу их в примерах
Any ;* - покажет все переменные которые держит в памяти netmond.
Object NAME - покажет имена всех объектов. Приведу часть вывода сервера на эту команду:
!OBJECT
Server-Proxy!NAME = "Server-Proxy"
!OBJECT
Catalyst11!NAME = "Catalyst11"
!OBJECT
Catalyst25!NAME = "Catalyst25"
!OBJECT
Catalyst34!NAME = "Catalyst34"
!OBJECT
Catalyst45!NAME = "Catalyst45"
!OBJECT
Catalyst46!NAME = "Catalyst46"
Interface STATUS - покажет статус интерфейсов (DOWN,UP)
Object Cisco - покажет переменные которые есть у объекта "Cisco"
Interface Cisco!1 - покажет данные по интерфейсу "1" у объекта "Cisco"
Any Cisco!1!IfIndex - покажет значение переменной IfIndex на интерфейсе/сервисе "1" объекта "Cisco".
Продолжение следует...