OS: "Linux Debian 8/9 (Jessie/Stretch)", "Linux Ubuntu 16/18 (Xenial/Bionic) LTS". Application: "Bacula Director v7", "Zabbix v3.4". Задача: наладить посредством системы мониторинга "Zabbix" отслеживание текущего состояния компонентов и задач централизованной системы резервного копирования "Bacula", хранения истории отработанных заданий и уведомления о сбоях в процессе их исполнения. Общий принцип действия выработанного решения таков:
2. Для полученного перечня объектов мониторинга сервером «Zabbix», в соответствии с заготовками в специализированном шаблоне, в соответствии со спецификацией «Low-Level Discovery (LLD)», создаются необходимые элементы и подэлементы.
3. Практически все запросы обрабатываются запускаемыми «Zabbix Agent»-ом самодельными скриптами, извлекающими данные через CLI-интерфейс «Bacula».
Получившееся полностью автоматизированное решение отслеживает состояние системы резервного копирования по следующим позициям:
Статус задач (item, every 5min);
Длительность исполнения задач (item/graph, every 2hour);
Объём загруженных при исполнении задач данных (item/graph, every 2hour);
Количество загруженных при исполнении задач файлов (item/graph, every 2hour);
Уведомление о неудачном завершении задач (trigger);
Уведомление об активности задач в данный момент (trigger);
Уведомление о длительном отсутствии данных о статусе задач (trigger, 6hour);
Уведомление о длительном перерыве в исполнении задач (trigger, 15 day).
Предварительная подготовка.
На
стороне сервера резервного копирования должен быть установлен "Zabbix
Agent" и CLI-интерфейс для "Bacula", а также утилита проверки синтаксиса
JSON:
Перед всеми дальнейшими работами потребуется применить заранее подготовленный мною специализированный шаблон для системы мониторинга:
Размер файла: 44.83 KB
Очень желательно сразу проверить возможность прохождения запроса от сервера мониторинга "Zabbix" к запущенному на стороне системы резервного копирования "Zabbix Agent"-у:
Настраиваем аутентификацию между компонентами.
Прежде
чем приступать к выстраиванию логики сбора данных, обеспечим к таковым
ограниченный доступ (только "на чтение", и не ко всем подсистемам)
агенту мониторинга "Zabbix".
В конфигурации "Bacula Director"
заведём отдельную точку входа со своими параметрами аутентификации для
утилиты "bconsole", через которую к "Bacula" будет подключатся "Zabbix
Agent":
# # Блок описания подсистем управления и мониторинга:
Console {
Name = «zabbix-agent.local»
Password = «zabbixConsolePassword»
# Разрешаем исполнение только перечисленных команд
Command ACL = show,list,llist,quit
# Явно разрешаем получать данные о любых задачах и обращаться к любым каталогам хранения метаданных
Job ACL = *all*
Catalog ACL = *all*
}
….
Проверяем корректность конфигурации средствами самого "Bacula" и применяем таковую:
# /etc/init.d/bacula-director reload
Мне представляется естественным, что клиентский конфигурационный файл утилиты "bconsole" должен быть расположен поближе к источнику запросов - в директории настроек "Zabbix Agent"-а:
# Bacula Console Configuration File, intended for Zabbix-Agent
#
# Указываем на сервис «Director Daemon», к которому нужно подключится:
Director {
Name = bacula.example.net
Address = bacula.example.net
DIRport = 9101
# (несмотря на то, что в действительности аутентификация осуществляется в контексте блока «Console», в блоке описания «Director» тоже требуется указание параметра «Password» — он не должен ничему соответствовать, просто необходимо присутствие его определения)
Password = «XXXXXXXXXXX»
}
# Параметры аутентификации клиента при подключении к «Director Daemon»:
Console {
Name = zabbix-agent.local
Password = «zabbixConsolePassword»
Director = bacula.example.net
}
Проверяем корректность конфигурации средствами самого CLI-агента "Bacula":
Есть смысл сразу удостовериться, действуют ли ограничения - уж не буду здесь о методике.
Настраиваем "Zabbix Agent".
Учитывая
то, что процедуры сбора данных и отправки их на сервер мониторинга
осуществляется клиентом "Zabbix", то конфигурационные файл и скрипты
расположим в его директории:
# mkdir -p /etc/zabbix/zabbix_agents.conf.d
UserParameter=bacula.jobs.check[*], /etc/zabbix/scripts/bacula_check_job.sh $1 $2 $3 $4
Подстраховываясь, закрываем к настройкам и скриптам "Zabbix" доступ посторонним:
# chmod o-rwx /etc/zabbix
Для применения изменений в конфигурации "Zabbix Agent" необходимо перезапустить:
Пишем и тестируем скрипт "Zabbix Auto Discovery (LLD)".
Подготовим
простейший Bash-скрипт, по запросу подключающийся к "Bacula",
запрашивающий перечень разрешённых к исполнению задач резервного
копирования и формирующий соответствующий требования "Zabbix Auto
Discovery" JSON-массив:
# vi ./bacula_discovery.sh && chown zabix:zabbix ./bacula_discovery.sh && chmod ug+x ./bacula_discovery.sh
# usage: ./bacula_discovery.sh
# Задаём переменные рабочего окружения
BCON=»bconsole -c /etc/zabbix/bconsole.conf»
LOG=»/var/log/zabbix-agent/zabbix-bacula-error.log»
DATE=$(date +»%Y-%m-%d.%H:%M:%S»)
# Проверяем наличие ожидаемых утилит
[ -x «$(command -v bconsole)» ] && [ -x «$(command -v jq)» ] || { echo «${DATE}: Не обнаружены необходимые для работы утилиты. Процедура создания списка активных заданий резервного копирования прервана.» >> ${LOG}; exit 1; }
# Формируем список имён активных заданий «Bacula»
JOBS=$(echo -e «show job\n.\nquit» | ${BCON} | grep -i -E «^job:.*enabled[ \t]*=[ \t]*1» | awk ‘{print $2}’ | grep -i -E «^name[ \t]*=[ \t]*.*$» | awk -F «=» ‘{print $2}’)
# Если список имён заданий не пуст, то формируем JSON для «Zabbix Low-Level Discovery (LLD)»
if [ ! -z «${JOBS}» ] ; then
# Задаём начало JSON
JSONZLLD=»{\»data\»:[»
FIRST=1
# Перебираем имена заданий
for JOB in ${JOBS} ; do
# Пропускаем обработку некоторых задач (заготовку для «восстановления», например)
[ $(echo ${JOB} | grep «restore») ] && continue
# Проставляем разделитель между элементами JSON
if [ ${FIRST} == 0 ] ; then
JSONZLLD=${JSONZLLD}»,»
fi
FIRST=0
# Вводим имя задания в качестве элмента JSON
JSONZLLD=${JSONZLLD}»{\»{#JOB}\»:\»${JOB}\»}»
done
# Завершаем JSON
JSONZLLD=${JSONZLLD}»]}»
# Проверяем синтаксическую корректность JSON
if jq -e . 1>/dev/null 2>&1 <<< «${JSONZLLD}» ; then
# Отдаём JSON на STDOUT
echo ${JSONZLLD}
fi
fi
exit ${?}
Пример получаемого в ответ на запрос JSON-файла для "Zabbix LLD", с обнаруженными активными задачами:
«data»:[
{«{#JOB}»:»client0.example.net»},
{«{#JOB}»:»clientX.example.net»}
] }
Есть смысл сразу проверить корректность срабатывания скрипта "Auto Discovery (LLD)":
Пишем и тестируем скрипт получения запрашиваемых параметров.
Создаём
специализированный Bash-скрипт, принимающий от "Zabbix Agent"-а запросы
на получение данных по ряду интересующих нас параметров, обращающийся к
CLI-утилите "Bacula" и нормализующий их перед выдачей:
# vi ./bacula_check_job.sh && chown zabix:zabbix ./bacula_check_job.sh && chmod ug+x ./bacula_check_job.sh
# usage: ./bacula_check_job.sh «jobName» «jobParam» {jobLevel}
# Задаём переменные рабочего окружения
BCON=»bconsole -c /etc/zabbix/bconsole.conf»
LOG=»/var/log/zabbix-agent/zabbix-bacula-error.log»
DATE=$(date +»%Y-%m-%d.%H:%M:%S»)
# Проверяем наличие ожидаемых утилит
[ -x «$(command -v bconsole)» ] || { echo «${DATE}: Не обнаружены необходимые для работы утилиты. Процедура запроса статуса задания резервного копирования прервана.» >> ${LOG}; exit 1; }
# Проверяем корректность вводимых данных и выводим подсказку в журнал событий при необходимости
#
JINAME=»${1}»
JIPARAM=»${2}»
JILEVEL=»${3}»
#
[ ! «${JINAME}» ] && { echo «${DATE}: Запрос: \»$(basename $0) $@\». Не указано имя задания резервного копирования. Процедура запроса статуса задания резервного копирования прервана.» >> ${LOG}; exit 1; }
#
[ ! «${JIPARAM}» ] && { echo «${DATE}: Запрос: \»$(basename $0) $@\». Не указан запрашиваемый параметр задания резервного копирования. Процедура запроса статуса задания резервного копирования прервана.» >> ${LOG}; exit 1; }
#
[ «${JILEVEL}» ] && [[ «${JILEVEL}» != «F» && «${JILEVEL}» != «D» && «${JILEVEL}» != «I» ]] && { echo «${DATE}: Запрос: \»$(basename $0) $@\». Некорректно указан уровень задания резервного копирования. Процедура запроса статуса задания резервного копирования прервана.» >> ${LOG}; exit 1; }
# Запрашиваем упрощённую статистику задания, опираясь на его имя
JOBLINE=$(echo -e «list job=${JINAME}\n.\nquit» | ${BCON})
# Первым отрабатываем самые простые запросы о статусах текущего (последнего в списке) задания
if [ «${JIPARAM}» == «jobstatus» ] ; then
ANSWER=$(echo -e «${JOBLINE}» | grep ‘^|’ | tail -n1 | awk -F «|» ‘{print $9}’ | sed -e ‘s/[ ]*//g’)
elif [ «${JIPARAM}» == «lastexecution» ] ; then
STARTTIME=$(echo -e «${JOBLINE}» | grep ‘^|’ | tail -n1 | awk -F «|» ‘{print $4}’ | xargs -I{} date -d «{}» +%s)
let «ANSWER = $(date +%s) — STARTTIME»
# (для дальнейшей выгрузки статистики по отработанным задачам необходимо указание их уровня)
elif [ ! -z «${JILEVEL}» ] ; then
# Для получения статистики выясняем идентификатор последнего успешно завершённого задания
JOBID=$(echo -e «list job=${JINAME}\n.\nquit» | ${BCON} | grep ‘^|’ | grep -i -E «.*\|[ \t]*B[ \t]*\|[ \t]*${JILEVEL}[ \t]*\|.*\|[ \t]*T[ \t]*\|[ \t]*$» | tail -n1 | awk -F «|» ‘{print $2}’ | sed -e ‘s/[ \t]*//g’ | sed -e ‘s/,//g’)
if [ ! -z «${JOBID}» ] ; then
# Запрашиваем расширенную статистику задания, опираясь на его идентификатор
JOBLONG=$(echo -e «llist jobid=${JOBID}\n.\nquit» | ${BCON})
# Формируем запросы и обрабатываем ответы с вычленением значений запрашиваемых параметров
if [ ! -z «${JOBLONG}» ] ; then
case «${JIPARAM}» in
«jobbytes»)
ANSWER=$(echo -e «${JOBLONG}» | grep -i -E «^[ \t]*jobbytes:» | awk -F «:» ‘{print $2}’ | sed -e ‘s/[ \t]*//g’ | sed -e ‘s/,//g’)
;;
«jobfiles»)
ANSWER=$(echo -e «${JOBLONG}» | grep -i -E «^[ \t]*jobfiles:» | awk -F «:» ‘{print $2}’ | sed -e ‘s/[ \t]*//g’ | sed -e ‘s/,//g’)
;;
«duration»)
STARTTIME=$(echo -e «${JOBLONG}» | grep -i -E «^[ \t]*starttime:» | awk -F «starttime:» ‘{print $2}’ | xargs -I{} date -d «{}» +%s)
ENDTIME=$(echo -e «${JOBLONG}» | grep -i -E «^[ \t]*endtime:» | awk -F «endtime:» ‘{print $2}’ | xargs -I{} date -d «{}» +%s)
let «ANSWER = ENDTIME — STARTTIME»
;;
*) echo «${DATE}: Запрос: \»$(basename $0) $@\». Некорректно указан запрашиваемый параметр задания резервного копирования. Процедура запроса статуса задания резервного копирования прервана.» >> ${LOG}; exit 1; ;;
esac
else
echo «${DATE}: Запрос: \»$(basename $0) $@\». Не получен ответ на запрос идентификатора и расширенного описания задания от подсистемы резервного копирования. Процедура запроса статуса задания резервного копирования прервана.» >> ${LOG}; exit 1;
fi
fi
else
echo «${DATE}: Запрос: \»$(basename $0) $@\». Не указан уровень задания резервного копирования. Процедура запроса статуса задания резервного копирования прервана.» >> ${LOG}; exit 1;
fi
# Отдаём значение запрашиваемого параметра (или ничего не делаем если запрашиваемый параметр отсутствует)
[ ! -z «${ANSWER}» ] && echo ${ANSWER}
exit ${?}
Аналогично предыдущим этапам проверяем корректность прохождения запросов к "Bacula" от сервера мониторинга "Zabbix":
Оптимизация оборота файлов журналов событий.
Наши
самодельные скрипты пишут в свой файл журнала событий, а кроме того
конфигурационный файл "Logrotate" для "Zabbix Agent" несовременный -
заменяем его на свой, всеобъемлющий:
weekly
rotate 7
compress
delaycompress
missingok
notifempty
copytruncate
su zabbix zabbix
}
Проверяем корректность конфигурации "Logrotate":
Yo, anyone played on bbjl77? How’s the gameplay? Is it a smooth experience? Give me the real deal.
Just made my first deposit on 345vipbet. Hoping for some good luck! Their VIP program seems pretty enticing, so I’m aiming for that!
If you like the classics, classicslots777 is the place to be. It is a simple place with traditional slots, without much fuss. Enjoy the retro vibes at classicslots777!
MJ777game is alright! Nice design. Quick support team, so far so good. Time will tell if the payouts solid ;). Still worth mj777game a look.
N777slot is giving the others a run for their money. Pretty nice interface and a decent variety of games. Just wish the bonuses were a bit better. But give it a shot, you never know!. n777slot
Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me. https://accounts.binance.com/si-LK/register-person?ref=LBF8F65G
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.