Zabbix监控与省电

Zabbix监控与省电

如何配置 Zabbix 以允许主机在计划外的时间不可访问?

我们有一些正在运行的集群,其中通常并非所有节点都得到充分利用(VMware、Slurm、OpenStack),我们目前正在评估在哪里可以关闭主机以尽可能节省电力。

VMware 和 Slurm 都可以轻松做到这一点,但它们或多或少是随机决定关闭哪些主机以及何时关闭,因此维护窗口被关闭。

在 Slurm 上,我必须编写一个脚本来处理关机和启动,我可以在那里添加一个 API 调用来禁用和启用对关闭服务器的监控,但在 VMware 上我无法做到这一点。

我目前能想到的唯一方法是触发依赖关系,但我真的不知道如何以有用的方式配置它们。


一些澄清:

  • 我想“暂停”对已关闭节点的监控故意地
  • 我仍然需要在节点宕机时触发警报无意地
  • 我宁愿不在 ESXi 主机上安装任何东西,除非是将来会支持的 VIB
  • 我希望所有内容都直接在 Zabbix 或 Zabbix 主机上进行
  • 我希望所有类型的主机都使用相同的方法,这样更容易维护

我目前的想法(正在进行中):

  • 通过控制平面监控节点状态
  • 当状态为计划待机时触发的触发器
  • 启用/禁用主机或创建/删除维护期的操作
    这需要在 Zabbix 主机上使用 API 的小脚本,但这对我来说没问题

答案1

您可以定义如此命名维护期(计划停机)。

Navigate to Configuration → Maintenance
Click on the Create maintenance period button
Type in the maintenance period name
Select the maintenance type and the activity time window
Add a period during which your maintenance will take place
Select hosts and/or host groups
Optionally, specify tags to suppress only the matching problems 
Add the maintenance period
Wait until the configuration changes are picked up by the Zabbix server
Navigate to Monitoring → Problems
Confirm if the problems on the host are suppressed

您可以通过以下方式定义上述内容Zabbix API

答案2

我继续处理这个问题,并想分享结果,以防其他人遇到类似的问题。

首先,我从特定的控制平面获取相关节点的状态。

泥浆

其中一个控制节点上的代理配置:

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 node {#NODENAME} status
      • 类型:Zabbix 代理
      • 钥匙:slurm.node.state[{#NODENAME}]
      • 信息类型:文本
    • 扳機原型
      • 姓名:Slurm node {#NODENAME} in stand by
      • 运行数据:{#NODENAME}
      • 严重性:信息
      • 表达:find(/controlnodename/slurm.node.state[{#NODENAME}],#3,"regexp","[~#]$")=1
      • 标签powersave::standby

VMware vSphere

我编写了一个小脚本,从 vCenter API 获取 ESXi 主机的电源状态:

#!/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}] 类型:简单检查
    • 产品原型
      • 姓名:Power state of Hypervisor {#HV.NAME}
      • 类型:外部检查
      • 钥匙:vsphere_host_powerstate.py[{#HV.NAME}]
      • 信息类型:文本
    • 扳機原型
      • 姓名:VMware Host {#HV.NAME} in stand by
      • 运行数据:{#HV.NAME}
      • 严重性:信息
      • 表达:last(/vc/vsphere_host_powerstate.py[{#HV.NAME}])="standBy"
      • 标签powersave::standby

通用配置

该字段Operational data很重要,因为我稍后在使用宏调用脚本时会用到它。使用带有触发器值的{EVENT.OPDATA}标签,因此我可以对所有主机使用单个操作。powersavestandby

我一直在争论是否应该在 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

脚本配置:

  • 姓名:Run Script zbx-set-host.sh maintenance_add
    • 类型:脚本
    • 命令:/path/to/zbx-set-host.sh {EVENT.OPDATA} maintenance_add
  • 姓名:Run Script zbx-set-host.sh maintenance_add
    • 类型:脚本
    • 命令:/path/to/zbx-set-host.sh {EVENT.OPDATA} maintenance_remove

触发动作:

  • 姓名:Disable host in stand by (power saving)
  • 状况:
    • 标签值powersave等于standby
  • 运营
    • 手术:Run script "Run Script zbx-set-host.sh maintenance_add"
    • 目标列表:当前主机
  • 恢复操作Recovery operations
    • 手术:Run script "Run Script zbx-set-host.sh maintenance_remove"
    • 目标列表:当前主机

相关内容