Привет, HABR!
Все те кто пользуются системой мониторинга Zabbix, с большой вероятностью, уже использовали UserParameter. Это, безусловно, очень полезный инструмент позволяющий значительно расширить базовые возможности Zabbix и поставить на мониторинг что-то такое эдакое. Но, к сожалению, у данного подхода есть свои минусы:
-
Необходимость распространение файлов конфигураций UserParameter
-
Необходимость перезапуска zabbix-agent после добавления UserParameter
-
Не нулевой шанс, что zabbix-agent не запустится после добавления некорректного файла конфигурации UserParameter
Проблему под пунктом 1 затрагивать не будем и перейдем к оставшимся двум, т.к. решив проблему 2 и 3 пунктов, та что под №1 станет чуть менее проблемной потому-что мы не будем бояться сломать запуск zabbix-agent при распространении файлов UserParameter.
Не так давно Zabbix в своем Release Notes for Zabbix 6.0.0 сообщил о том, что внедрил runtime команду для перечитки пользовательских параметров, без необходимости перезагрузки zabbix-agent. Но, по моему скромному мнению, что перезагрузка агента, что выполнение runtime команды (zabbix_agentd -R userparameter_reload) - являются дополнительным шагом при распространении UserParameter. А так как проблема с возможной поломкой запуска zabbix-agent не решена, то по прежнему распространение UserParameter остается не совсем безопасным этапом.
Запуск zabbix-agent достаточно просто сломать, не аккуратно работая с файлами пользовательских параметров. Добавьте агенту zabbix некорректный файл пользовательских параметров (дублирующие ключи, опечатки, лишние непечатаемые символы) и выполнив его перезагрузку, он пожалуется на конфиг и не запуститься. В случае если "плохой" UserParameter уже распространили на несколько тысяч или десятков тысяч серверов, то это очень неприятно исправлять. При большом парке серверов, большого разнообразия продуктов, нескольких десятков инженеров, разрабатывающих мониторинг, и нескольких сотен различных UserParameter, данная ситуация нет-нет, да и случится. Конечно же надо тестировать UserParameter перед распространением, но человеческий фактор никто не отменял.
Именно возможность сломать zabbix-agent, я считаю, основой опасностью UserParameter, и, поэтому, в первую очередь надо решать именно эту проблему.
Как же не стать параноиком и при этом не сломать zabbix-agent?
Не хочется мириться с потенциальным риском сломать zabbix-agent на большом количестве серверов практически одномоментно, но при этом хочется продолжать пользоваться пользовательскими параметрами, расширяя возможности мониторинга Zabbix.
Решение, которое можно предложить - это использовать один стандартный UserParameter (в связке со скриптом), который нам добавит возможность использования безопасно и динамически(как бонус) загружаемых пользовательских параметров.
Взаимодействие zabbix-agent с динамическими пользовательскими параметрами будет выглядеть следующим образом
Основные тезисы данного подхода:
-
Мы используем классические файлы UserParameter, т.е. переписывать ничего не придется.
-
Если UserParameter параметр не корректный, то сломается сбор данных только для данного UserParameter и только для ключа/ключей, где закралась ошибка
-
Если UserParameter попадает в директорию динамически загружаемых, то сбор метрик по нему начнется моментально.
Пример настройки на Linux
1. Создадим в /etc/zabbix/zabbix_agentd.d/ директорию dyn_up
для динамических UserParameter:
2. Создадим в директории /etc/zabbix/zabbix_agentd.d/ скрипт dyn_up.sh со следующим содержимым:
#!/bin/bash
#Укажем расположение директории динамических UserParameter
dyn_up_dir="/etc/zabbix/zabbix_agentd.d/dyn_up"
#Получим ключ команды и имя UserParameter
read -r up_key up_name <<< $(echo "$1" | tr '@' ' ')
#Получи команду из ключе в динамическом UserParameter
up_cmd=`perl -ne "print if s/^UserParameters?=s?S+,s?(.*)/1/" "$dyn_up_dir/$up_name"`
#Пройдемся по всем полученным скриптом параметрам и заменим соответствующие ссылки на позиции
for ((i=1; i<=${#*}; i++))
do
up_cmd=$(echo "$up_cmd" | perl -pe 's/(?<!$)${1}'$(( i - 1 ))'/'"${!i}"'/g')
done
#$$ меняем на $
up_cmd=$(echo "$up_cmd" | perl -pe 's/$$/$/g')
#Выполняем команду
/bin/bash -c "$up_cmd"
3. Создадим в директории /etc/zabbix/zabbix_agentd.d/ наш единственный обычный UserParameter userparameter_dyn_up.conf со следующим содержимым:
UserParameter=dyn.up[*], ./dyn_up.sh "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
4. Запуск проверки будет выглядеть следующим образом:
dyn.up["item_key@userparameter","param1","param2","param3","param4","param5","param6"]
P.S. Вашему вниманию представлен концепт, который опробован только на zabbix-агентах под Linux.
Скрипт для Windows может выглядеть следующим образом
$dir_path = 'D:zabbixzabbix_agentd.ddyn_up'
$up_key, $up_name = $args[0].split('@')
$up_name = Join-Path -Path $dir_path -ChildPath $up_name
$up_cmd = (Select-String -Path $up_name -Pattern "^UserParameters?=s?$up_key([*])?,").Line.Split(',') | Select-Object -Skip 1
for($i=1; $i -lt $args.Count; $i++){
$str = '(?<!$)${1}'+$i
$up_cmd = $up_cmd -replace $str, $args[$i]
}
$up_cmd = $up_cmd -replace '${2}', '$'
Invoke-Expression "$up_cmd"
Спасибо за внимание!
Автор:
azk