Учим zabbix-agent «есть» на ходу и не давиться пользовательскими параметрами (UserParameter)

в 19:21, , рубрики: zabbix мониторинг, Серверное администрирование, системное администрирование
Учим zabbix-agent «есть» на ходу и не давиться пользовательскими параметрами (UserParameter) - 1

Привет, HABR!

Все те кто пользуются системой мониторинга Zabbix, с большой вероятностью, уже использовали UserParameter. Это, безусловно, очень полезный инструмент позволяющий значительно расширить базовые возможности Zabbix и поставить на мониторинг что-то такое эдакое. Но, к сожалению, у данного подхода есть свои минусы:

  1. Необходимость распространение файлов конфигураций UserParameter

  2. Необходимость перезапуска zabbix-agent после добавления UserParameter

  3. Не нулевой шанс, что 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 с динамическими пользовательскими параметрами будет выглядеть следующим образом

Учим zabbix-agent «есть» на ходу и не давиться пользовательскими параметрами (UserParameter) - 2

Основные тезисы данного подхода:

  1. Мы используем классические файлы UserParameter, т.е. переписывать ничего не придется.

  2. Если UserParameter параметр не корректный, то сломается сбор данных только для данного UserParameter и только для ключа/ключей, где закралась ошибка

  3. Если 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js