Мониторинг Zabbix и энергосбережение

Вопрос или проблема

Как я могу настроить Zabbix, чтобы позволить хостам быть недоступными в непредусмотренное время?

У нас работает кластер, где обычно не все узлы полностью загружены (VMware, Slurm, OpenStack), и мы рассматриваем возможность отключения хостов для экономии энергии, когда это возможно.

И VMware, и Slurm могут сделать это легко, но они более или менее случайно решают, какие хосты отключать и когда, поэтому окна обслуживания невозможно использовать.

На Slurm мне нужно написать скрипт для управления отключением и включением, я мог бы добавить вызов API, который отключает и включает мониторинг отключенного сервера, но на VMware я не могу этого сделать.

Единственный способ, о котором я сейчас думаю, это зависимости от триггеров, но я не вижу, как их можно настроить полезным образом.


Некоторые уточнения:

  • Я хочу «приостановить» мониторинг узлов, которые были отключены намеренно
  • Мне по-прежнему нужны маркеры, которые срабатывают, когда узлы отключены ненамеренно
  • Я предпочел бы не устанавливать ничего на хост ESXi, за исключением, возможно, VIB, который будет поддерживаться в обозримом будущем
  • Я хотел бы иметь все прямо в Zabbix или на хосте Zabbix
  • Я предпочел бы иметь одинаковый метод для всех типов хостов, чтобы было легче поддерживать

Моя текущая идея (в процессе работы):

  • Мониторинг состояния узла через контрольную плоскость
  • Триггер, который срабатывает, когда состояние в запланированном режиме ожидания
  • Действие, которое либо включает/выключает хост, либо создает/удаляет периоды обслуживания
    Это требует небольшого скрипта на хосте Zabbix, который использует API, но это нормально для меня

Вы можете определить так называемый период обслуживания (запланированное время простоя).

Перейдите в Конфигурация → Обслуживание
Нажмите кнопку Создать период обслуживания
Введите имя периода обслуживания
Выберите тип обслуживания и временной интервал активности
Добавьте период, в течение которого будет проводиться обслуживание
Выберите хосты и/или группы хостов
При необходимости укажите теги, чтобы подавить только соответствующие проблемы 
Добавьте период обслуживания
Подождите, пока сервер Zabbix не примет изменения конфигурации
Перейдите в Мониторинг → Проблемы
Проверьте, подавлены ли проблемы на хосте

Вы можете определить вышеуказанное через API Zabbix.

Я продолжил работу с текущими наработками из вопроса и хочу поделиться результатом, если у кого-то возникнет аналогичная проблема.

Сначала я получаю состояние релевантных узлов из их конкретной контрольной плоскости.

Slurm

Настройка агента на одном из управляющих узлов:

UserParameter=slurm.nodes.discovery,sinfo -N -h -o '{"{#NODENAME}":"%N"}' |jq -sr '[.[]]'
UserParameter=slurm.node.state[*],sinfo -h -o %T -n $1

Правило обнаружения Zabbix:

  • Ключ: slurm.nodes.discovery
    • Прототип элемента
      • Имя: Состояние узла Slurm {#NODENAME}
      • Тип: агент Zabbix
      • Ключ: slurm.node.state[{#NODENAME}]
      • Тип информации: Текст
    • Прототип триггера
      • Имя: Узел Slurm {#NODENAME} в режиме ожидания
      • Операционные данные: {#NODENAME}
      • Значимость: Информация
      • Выражение: find(/controlnodename/slurm.node.state[{#NODENAME}],#3,"regexp","[~#]$")=1
      • Теги: powersave: standby

VMware vSphere

Я написал небольшой скрипт для получения состояния электропитания хостов ESXi из API vCenter:

#!/usr/bin/env python3
import os
import sys
from pyVim import connect
from pyVmomi import vim

vc_url = "vcenter.example.com"
vc_user = "[email protected]"
vc_password = "aHR0cDovL2JpdC5seS8xVHFjd243Cg=="

if len(sys.argv) < 1:
print("host parameter missing", file=sys.stderr)
os.exit(3)

esx_name = sys.argv[1]

my_cluster = connect.ConnectNoSSL(vc_url, 443, vc_user, vc_password)

content = my_cluster.RetrieveContent()
object_view = content.viewManager.CreateContainerView(content.rootFolder, [vim.HostSystem], True)

host_list = object_view.view
object_view.Destroy()

for host in host_list:
if host.name == esx_name:
    print(host.runtime.powerState)

connect.Disconnect(my_cluster)

Это был единственный способ, которым я смог получить статус хостов, даже когда они выключены.

Правило обнаружения Zabbix:

  • Ключ: vmware.hv.discovery[{$VMWARE.URL}]
    Тип: Простая проверка
    • Прототип элемента
      • Имя: Состояние электропитания гипервизора {#HV.NAME}
      • Тип: Внешняя проверка
      • Ключ: vsphere_host_powerstate.py[{#HV.NAME}]
      • Тип информации: Текст
    • Прототип триггера
      • Имя: Хост VMware {#HV.NAME} в режиме ожидания
      • Операционные данные: {#HV.NAME}
      • Значимость: Информация
      • Выражение: last(/vc/vsphere_host_powerstate.py[{#HV.NAME}])="standBy"
      • Теги: powersave: standby

Общая конфигурация

Поле Операционные данные важно, так как я использую его позже, когда вызываются скрипты с макросом {EVENT.OPDATA}. Тег powersave со значением standby в триггерах используется, чтобы я мог использовать одно действие для всех хостов.

Я спорил, стоит ли отключенные для экономии энергии машины выключать в Zabbix или помещать в окно обслуживания.

Я решил, что мне кажется более интуитивно понятным иметь машины в окне обслуживания:

  • если оно отключено, неочевидно для всех, кто управляет машинами в Zabbix, ПОЧЕМУ оно отключено
  • Описание окна обслуживания отображается непосредственно в событиях

Я написал скрипт для добавления и удаления машин в окнах обслуживания:

#!/usr/bin/env bash
# set -xv
ZBX_URL="https://zabbix.example.com/zabbix/api_jsonrpc.php"
ZBX_USERNAME="zabbix-api"
ZBX_PASSWORD="aHR0cDovL2JpdC5seS8xVHFjd243Cg=="
ZBX_MAINTENANCE_ID=431

function usage {
    echo "Usage:"
    echo "  $0 <hostname> <maintenance_add|maintenance_remove>"
}

function api_error {
    echo -n "API ERROR: "
    echo "$*" | jq -r .error.data
    exit 3
}

if [[ $# -lt 2 ]]; then
    echo "Error: argument missing"
    usage
    exit 1
fi

function zbx_request {
    REQUEST='{
        "jsonrpc": "2.0",
        "method": "'$1'",
        "params": '$2',
        "auth": "'$AUTH'",
        "id": 1
    }'
    # echo "$REQUEST" |jq

    RESPONSE=$(curl -s -X POST \
    -H 'Content-Type: application/json-rpc' \
    -d "$REQUEST" "$ZBX_URL")

    echo "$RESPONSE" | jq --exit-status .result > /dev/null || api_error "$RESPONSE"
    echo "$RESPONSE"
}

function host_get {
    PARAMS='{
            "filter": {
                "host": [
                    "'$1'"
                ]
            }
        }'
    RESPONSE=$(zbx_request "host.get" "$PARAMS")
    echo "$RESPONSE" | jq -r .result[0].hostid
}

function maintenance_get {
    PARAMS='{
            "maintenanceids": [ '$ZBX_MAINTENANCE_ID' ],
            "selectHosts": [ "hostid" ]
        }'
    RESPONSE=$(zbx_request "maintenance.get" "$PARAMS")
    echo "$RESPONSE" |jq .result[0].hosts | jq -r 'map(.hostid)'
}

function maintenance_add {
    MAINTENANCE_HOSTS=$(maintenance_get)
    HOSTID=$(host_get "$1")

    if jq -e '. | index("'"$HOSTID"'")' <<<"$MAINTENANCE_HOSTS"  > /dev/null; th
en return; fi

    HOSTS=$(jq '. += ["'"$HOSTID"'"]' <<<"$MAINTENANCE_HOSTS")

    PARAMS='{
            "maintenanceid": "'$ZBX_MAINTENANCE_ID'",
            "hostids": '$HOSTS'
        }'
    zbx_request "maintenance.update" "$PARAMS" > /dev/null
}

function maintenance_remove {
    MAINTENANCE_HOSTS=$(maintenance_get)
    HOSTID=$(host_get "$1")

    HOSTINDEX=$(jq '. | index("'"$HOSTID"'")' <<<"$MAINTENANCE_HOSTS")
    if [ "$HOSTINDEX" == "null" ]; then return; fi
    HOSTS=$(jq 'del(.['"$HOSTINDEX"'])' <<<"$MAINTENANCE_HOSTS")
    PARAMS='{
            "maintenanceid": "'$ZBX_MAINTENANCE_ID'",
            "hostids": '$HOSTS'
        }'
    zbx_request "maintenance.update" "$PARAMS" > /dev/null
}

RESPONSE=$(curl -s -X POST -H 'Content-Type: application/json-rpc' \
-d '
{"jsonrpc":"2.0","method":"user.login","params":
{"user":"'"$ZBX_USERNAME"'","password":"'"$ZBX_PASSWORD"'"},
"id":1,"auth":null}
' "$ZBX_URL")
echo "$RESPONSE" | jq --exit-status .result > /dev/null || api_error "$RESPONSE"
AUTH=$(echo "$RESPONSE" | jq -r .result)

case $2 in
    maintenance_add)
        maintenance_add "$1"
    ;;
    maintenance_remove)
        maintenance_remove "$1"
    ;;
    *)
        echo "invalid state: $2"
        usage
        exit 2
    ;;
esac

Конфигурация скрипта:

  • Имя: Запустить скрипт zbx-set-host.sh maintenance_add
    • Тип: Скрипт
    • Команды: /path/to/zbx-set-host.sh {EVENT.OPDATA} maintenance_add
  • Имя: Запустить скрипт zbx-set-host.sh maintenance_remove
    • Тип: Скрипт
    • Команды: /path/to/zbx-set-host.sh {EVENT.OPDATA} maintenance_remove

Действие триггера:

  • Имя: Отключить хост в режиме ожидания (экономия энергии)
  • Условия:
    • Значение тега powersave равно standby
  • Операции
    • Операция: Запустить скрипт "Run Script zbx-set-host.sh maintenance_add"
    • Список целей: текущий хост
  • Восстановительные операции
    • Операция: Запустить скрипт "Run Script zbx-set-host.sh maintenance_remove"
    • Список целей: текущий хост

.

Ответ или решение

Конфигурация Zabbix для обработки непредвиденной недоступности хостов при экономии энергии

В условиях, когда некоторые узлы вашего кластера, работающего на платформах VMware, Slurm или OpenStack, не всегда полностью загружены, вы стремитесь выключать их для экономии энергии. Однако при этом важно, чтобы ваша система мониторинга Zabbix не выдавала ложные тревоги. Давайте разберем, как настроить Zabbix, чтобы учитывать данные обстоятельства.

1. Основные задачи

Перед вами стоит несколько задач:

  • Остановка мониторинга узлов, которые отключены преднамеренно.
  • Поддержка уведомлений в случае непредвиденного отключения узлов.
  • Избегание инсталляции дополнительных компонентов на узлы ESXi, кроме тех, которые будут поддерживаться в будущем.
  • Единообразие метода для всех типов узлов с целью упрощения администрирования.

2. Предложенный подход

Здесь представлено решение на примере интеграции с платформами Slurm и VMware, охватывающее как автоматизацию отключения мониторинга для преднамеренно выключенных узлов, так и поддержание алертинга для остальных случаев.

Slurm

Для Slurm вы можете настраивать агент на одном из управляющих узлов, который будет:

  • Обнаруживать узлы и получать информацию об их статусе.
  • Создавать элементы и триггеры в Zabbix для обработки этих статусов.

VMware vSphere

При помощи Python-скриптов, взаимодействующих с API vCenter, можно отслеживать состояние ESXi-хостов, даже если они выключены. С помощью Python и модуля pyVmomi вы можете запускать скрипт из Zabbix, который будет возвращать текущее состояние питания ESXi-хостов.

3. Общее решение

Автоматизация через API

Для вашего случая целесообразно создать скрипт, который через API Zabbix будет управлять окнами обслуживания узлов. Такой подход позволяет:

  • Интуитивно понятно работать в интерфейсе Zabbix с отключенными узлами.
  • Видеть подробности причин выключения узлов прямо в событиях.

4. Установление триггеров и правил действия

  1. Создание триггеров для определения состояния узлов в режиме ожидания.

  2. Автоматизация операции через API:

    • Скрипт автоматически добавляет или удаляет узлы в окно обслуживания на основании их текущего состояния.
  3. Определение и выполнение сценариев действий:

    • Действия для добавления узлов в окно обслуживания.
    • Действия для удаления узлов из окна обслуживания при изменении их состояния на активно работающие.

Заключение

Предложенное решение позволяет вам гибко управлять мониторингом в Zabbix с учетом потребности в динамическом отключении узлов для энергосбережения. Способствуя более эффективному использованию ресурсов и автоматизации рутинных задач, данный подход способствует сокращению накладных расходов и оптимизации рабочих процессов в IT-инфраструктуре.

Оцените материал
Добавить комментарий

Капча загружается...