美文网首页
Zabbix监控告警ELK

Zabbix监控告警ELK

作者: 托瓦斯克一 | 来源:发表于2020-07-21 15:22 被阅读0次

    概述

    Zabbix允许自定义监控项,使用ansible批量安装zabbix-agent,在部署有ansible工具的机器上编写监控ELK端口,ES集群状态,索引数量脚本,然后编写ansible-playbook发送脚本到所有agent机器上;当监控项被触发时,自动发送告警到钉钉机器人和企业微信号上;告警的次数是5次,告警的频率是每隔5分钟告警一次。

    本文跳过ansible,zabbix和elk的部署操作,旨在呈现zabbix的相关功能!


    准备环境

    主机名 设备IP 角色 系统版本
    es1 192.168.6.10 es,zabbix-server,zabbix-agent CentOS 7.6
    es2 192.168.6.11 es,logstash,zabbix-agent CentOS 7.6
    es3 192.168.6.12 es,kibana,zabbix-agent CentOS 7.6

    本文的ELK全家桶版本为7.0.0,Zabbix版本为4.2.5


    修改zabbix服务端的配置文件

    主要参数说明:

    StartPollers             处理zabbix数据的进程数
    StartPollersUnreachable  recheck的进程数
    StartTrappers            建立agent连接传输进程数
    StartHTTPPollers         http检测
    startDBSyncers           写入db进程
    CacheSize                增加主机,监控项等配置缓存
    DBName                   数据库名称
    DBUser                   数据库用户名
    DBPassword               数据库密码
    StartDiscoverers         自动发现功能的进程数
    AlertScriptsPath         告警脚本的存放路径
    ExternalScripts          外部脚本的存放路径
    StatsAllowedIP           服务端IP地址
    

    具体的优化配置,根据自身环境来决定:

    [root@es1 zabbix]# cat > /etc/zabbix/zabbix_server.conf <<EOF 
    LogFile=/var/log/zabbix/zabbix_server.log
    StartPollers=160
    StartPollersUnreachable=80
    StartTrappers=20
    StartHTTPPollers=60
    startDBSyncers=16
    CacheSize=1024M
    LogFileSize=0
    PidFile=/var/run/zabbix/zabbix_server.pid
    SocketDir=/var/run/zabbix
    DBName=zabbix
    DBUser=zabbix
    DBPassword=123456
    StartDiscoverers=30
    SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
    Timeout=4
    AlertScriptsPath=/usr/lib/zabbix/alertscripts
    ExternalScripts=/usr/lib/zabbix/externalscripts
    LogSlowQueries=3000
    StatsAllowedIP=218.201.205.211
    EOF
    

    修改agent节点的配置文件

    主要参数说明:

    Server                  开启被动模式,配置为zabbix-server的IP地址
    ServerActive            开启主动模式,配置为zabbix-server的IP地址
    Hostname                配置为本地主机名
    UnsafeUserParameters    允许自定义监控项功能
    

    所有agent节点上都需要修改:

    [root@es1 zabbix]# cat > /etc/zabbix/zabbix_agentd.conf <<EOF
    PidFile=/var/run/zabbix/zabbix_agentd.pid
    LogFile=/var/log/zabbix/zabbix_agentd.log
    LogFileSize=0
    Server=192.168.6.10
    ServerActive=192.168.6.10
    Hostname=es1
    Include=/etc/zabbix/zabbix_agentd.d/*.conf
    UnsafeUserParameters=1
    EOF
    

    编写监控es端口脚本

    脚本主要实现将端口json格式化,其他的服务端口监控脚本也类似,根据服务器来修改portarray的端口号即可!

    [root@es1 zabbix]# cat > /etc/zabbix/es_port_alert.sh <<EOF
    #!/bin/bash
    portarray=(9200 9300)
    PortDiscovery(){
        length=${#portarray[@]}
        printf "{\n" 
        printf '\t'"\"data\":["
        for ((i=0;i<$length;i++))
        do
                printf '\n\t\t{'
                printf "\"{#TCP_PORT}\":\"${portarray[$i]}\"}"
                if [ $i -lt $[$length-1] ];then
                        printf ','
                fi
        done
        printf "\n\t]\n"
        printf "}\n"
    }
    PortDiscovery
    EOF
    

    编写监控索引数据量脚本

    使用python的elasticsearch模块编写dsl语句,得出每5分钟内指定索引的数据量,监控其他索引也类似,该脚本只需部署在一台服务器上即可!

    [root@es1 zabbix]# cat > /etc/zabbix/index_alert.py <<EOF
    #!/usr/bin/env python2.7
    # -*- coding: utf-8 -*-
    import time
    import pytz
    from datetime import datetime
    from tzlocal import get_localzone
    from elasticsearch import Elasticsearch
    
    tz = get_localzone()
    utc = pytz.utc
    now = datetime.today()
    
    loc_dt = tz.localize(now)
    utc_dt = loc_dt.astimezone(utc)
    today = datetime.strftime(utc_dt,'%Y%m')
    
    index_today=("index_%s" % today)
    es = Elasticsearch("http://192.168.6.10:9200")
    
    def get_indices_nums():
        global index_today
        global es
        querybody_warn = {
             "size": 0,
             "query": {
                 "bool": {
                      "filter": {
                           "range": {
                                "@timestamp": {
                                      "gte": "now-5m/m",
                                      "lte": "now/m"
                                }
                           }
                      }
                  }
             }
        }
        response_warn = es.search(index=index_today, body=querybody_warn)
        reqsum = response_warn['hits']['total']['value']
        print reqsum
    
    if __name__ == '__main__':
       get_indices_nums()
    EOF
    

    自定义key,将脚本定义为监控命令

    除了事先定义好脚本的方式,还能用命令取值的方式来定义key!

    [root@es1 zabbix]# cat > /etc/zabbix/zabbix_agentd.d/elk_alert.conf <<EOF
    UserParameter=get_es_port,/etc/zabbix/es_port_alert.sh
    UserParameter=get_index,/etc/zabbix/index_alert.py
    UserParameter=get_es_status,curl -s -XGET 'http://localhost:9200/_cluster/health?pretty' | grep "status" | awk -F'"' '{print $4}' | grep -c 'red'
    EOF
    

    修改脚本相关权限,并重启服务

    修改脚本的属主和组,赋予脚本执行权限,最后重启zabbix相关服务!

    [root@es1 zabbix]# chown -R zabbix:zabbix /etc/zabbix/es_port_alert.sh
    [root@es1 zabbix]# chown -R zabbix:zabbix /etc/zabbix/index_alert.py
    [root@es1 zabbix]# chown -R zabbix:zabbix /etc/zabbix/zabbix_agentd.d/elk_alert.conf
    [root@es1 zabbix]# chmod +x /etc/zabbix/es_port_alert.sh /etc/zabbix/index_alert.py
    [root@es1 zabbix]# chmod +x /etc/zabbix/zabbix_agentd.d/elk_alert.conf
    
    [root@es1 zabbix]# systemctl restart zabbix-server
    [root@es1 zabbix]# systemctl restart zabbix-agent
    

    测试自定义key

    在zabbix服务器上操作,可测试所有客户端agent,-s后指定客户端地址,-k后指定自定义的key!

    [root@es1 zabbix]# zabbix_get -s 192.168.6.10 -k get_es_port
    

    配置ansible-playbook

    通过编写ansible-playbook文件,完成其他agent节点的脚本批量部署!

    [root@es1 zabbix]# cat > /etc/ansible/zabbix_agent.yml <<EOF
    - hosts: elkservers
      remote_user: root
      tasks:
         - name: copying zabbix_agentd.conf
           copy:
              src: /etc/zabbix/zabbix_agentd.conf
              dest: /etc/zabbix/zabbix_agentd.conf
              owner: root
              group: root
              mode: 0644
        - name: copying es_port_alert.sh
          copy:
              src: /etc/zabbix/es_port_alert.sh
              dest: /etc/zabbix/es_port_alert.sh
              owner: zabbix
              group: zabbix
              mode: 0754
        - name: copying elk_alert.conf
          copy:
              src: /etc/zabbix/zabbix_agentd.d/elk_alert.conf
              dest: /etc/zabbix/zabbix_agentd.d/elk_alert.conf
              owner: zabbix
              group: zabbix
              mode: 0644
    EOF
    
    [root@es1 zabbix]# ansible-playbook /etc/ansible/zabbix_agent.yml
    

    编写相关告警脚本

    在zabbix服务器上操作,脚本要放在指定路径下;本文主要呈现钉钉机器人和企业微信号告警功能,告警内容使用了markdown格式;企业微信告警需要先安装python3环境;钉钉告警需要先获取自定义机器人webhook,可参考 https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq/9e91d73c

    钉钉机器人告警

    [root@es1 zabbix]# cat > /usr/lib/zabbix/alertscripts/dingding.py <<EOF
    #!/usr/bin/env python2.7
    # -*- coding:utf-8 -*-
    import json
    import requests
    import sys
    
    def send_msg(url, remiders, text):
        headers = {'Content-Type': 'application/json; charset=utf-8'}
        data = {
            "msgtype": "markdown",
            "markdown": {
                 "title": "ELK告警",
                 "text": text + "@13475333688 @18756668888"        # @手机号码,指定接收人
            },
            "at": {
                "atMobiles": remiders,
                "isAtAll": False
            }
        }
        r = requests.post(url, data=json.dumps(data), headers=headers).json()
        return r
    
    if __name__ == '__main__':
        url = 'https://oapi.dingtalk.com/robot/send?access_token=bawfasaf8c023197526c29ddddd'
        remiders = ['13475333688', '18756668888']
        text = sys.argv[1]
        print(send_msg(url, remiders, text))
    EOF
    

    企业微信号告警

    [root@es1 zabbix]# cat > /usr/lib/zabbix/alertscripts/weixin.py <<EOF
    #!/usr/bin/python3
    # -*- coding:utf-8 -*-
    import requests
    import json
    import sys
    
    # 企业号及应用相关信息
    corp_id = 'ww730dff80343abcdf'
    corp_secret = 'iufX35rEGz4Q9qJezIhHCT4S-k_f331kP69D3abcdef'
    agent_id = '1000001'
    
    # 存放access_token文件路径
    file_path = '/tmp/access_token.log'
    
    # 读取文本里记录的token
    def get_access_token_from_file():
        try:
            f = open(file_path, 'r+')
            this_access_token = f.read()
            print('get success %s' % this_access_token)
            f.close()
            return this_access_token
        except Exception as e:
            print(e)
    
    # 获取token函数,文本里记录的token失效时调用
    def get_access_token():
        get_token_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s' % (corp_id, corp_secret)
        print(get_token_url)
        r = requests.get(get_token_url)
        request_json = r.json()
        this_access_token = request_json['access_token']
        print(this_access_token)
        r.close()
    
        # 把获取到的access_token写入文本
        try:
            f = open(file_path, 'w+')
            f.write(this_access_token)
            f.close()
        except Exception as e:
            print(e)
    
        # 返回获取到的access_token值
        return this_access_token
    
    ##发送消息
    # 死循环,直到消息成功发送
    flag = True
    while(flag):
        # 从文本获取access_token
        access_token = get_access_token_from_file()
        try:
            to_user = '@all'
            message = sys.argv[1]
            send_message_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s' % access_token
            print(send_message_url)
            message_params = {
                "touser": to_user,
                "msgtype": "markdown",
                "agentid": agent_id,
                "markdown": {
                    "content": message
                },
                "safe": 0
            }
            r = requests.post(send_message_url, data=json.dumps(message_params))
            print('post success %s' % r.text)
    
            # 判断是否发送成功,如不成功则抛出异常,让其执行异常处理里的函数
            request_json = r.json()
            errmsg = request_json['errmsg']
            if errmsg != 'ok': raise
    
            # 消息成功发送,则停止死循环
            flag = False
        except Exception as e:
            print(e)
            access_token = get_access_token()
    EOF
    

    修改相关权限,并重启zabbix服务

    [root@es1 zabbix]# chown -R zabbix:zabbix /usr/lib/zabbix/alertscripts/dingding.py
    [root@es1 zabbix]# chown -R zabbix:zabbix /usr/lib/zabbix/alertscripts/weixin.py
    [root@es1 zabbix]# chmod +x /usr/lib/zabbix/alertscripts/dingding.py
    [root@es1 zabbix]# chmod +x /usr/lib/zabbix/alertscripts/weixin.py
    
    [root@es1 zabbix]# systemctl restart zabbix-server
    [root@es1 zabbix]# systemctl restart zabbix-agent
    

    Zabbix中文界面操作

    监控端口(以配置ES端口监控模板为例)

    配置 --> 模板 --> 创建模板 --> 添加
    模板名称     ES_Port_Alert
    可见的名称   ES端口监控
    群组        Linux server
    

    [图片上传失败...(image-89f211-1595316084892)]


    配置 --> 模板(ES端口监控) --> 自动发现规则 --> 创建发现规则 --> 添加
    名称      ES_Port_Discovey
    类型      Zabbix客户端(主动式)
    键值      get_es_port    # 该键值名称必须与自定义的key名一致
    更新间隔  30s            # 数据采集的频率,此处指30s采集一次
    
    image
    配置 --> 模板(ES端口监控) --> 自动发现规则 --> 监控项原型 --> 创建监控项原型 --> 添加
    名称                {#TCP_PORT}端口
    类型                Zabbix客户端(主动式)
    键值                net.tcp.listen[{#TCP_PORT}]
    信息类型            数字(无正负)
    新的应用程序原型     port-alert
    
    image
    配置 --> 模板(ES端口监控) --> 自动发现规则 --> 触发器类型 --> 创建触发器原型 --> 添加
    名称            端口{#TCP_PORT} down,请检查
    严重性          严重
    表达式          {ES_Port_Alert:net.tcp.listen[{#TCP_PORT}].last()}<>1 and {ES_Port_Alert:net.tcp.listen[{#TCP_PORT}].nodata(15m)}=1
    允许手动关闭
    描述            监控结果不等于1,并且端口断开持续15分钟,即表示es端口未被监控到!
    
    image

    配置ES集群状态监控模板

    配置 --> 模板 --> 创建模板 --> 添加
    模板名称     ES_Status_Alert
    可见的名称   ES集群状态监控
    群组        Linux servers
    
    image
    配置 --> 模板(ES集群状态监控) --> 应用集 --> 创建应用集 --> 添加
    名称      ES_Health
    
    image
    配置 --> 模板(ES集群状态监控) --> 监控项 --> 创建监控项 --> 添加
    名称      ES_Status_Check
    类型      Zabbix客户端(主动式)
    键值      get_es_status
    信息类型  数字(无正负)
    应用集    ES_Health
    

    [图片上传失败...(image-454ef6-1595316084893)]


    配置 --> 模板(ES集群状态监控) --> 触发器 --> 创建触发器 --> 添加
    名称           ES_Cluster_Health
    严重性         灾难
    表达式         {ES_Status_Alert:get_es_status.last()}<>0 and {ES_Status_Alert:get_es_status.nodata(15m)}=1
    允许手动关闭
    描述           状态值不为0,并且持续15分钟,即表示集群状态为Red
    
    image

    配置ES索引监控模板

    配置 --> 模板 --> 创建模板 --> 添加
    模板名称     Indices_index_Alert
    可见的名称   回填索引监控
    群组        Linux servers
    
    image
    配置 --> 模板(回填索引监控) --> 应用集 --> 创建应用集 --> 添加
    名称      index_*
    
    image
    配置 --> 模板(回填索引监控) --> 监控项 --> 创建监控项 --> 添加
    名称      索引index_gz
    类型      Zabbix客户端(主动式)
    键值      get_index
    信息类型  数字(无正负)
    应用集    index_*
    
    image
    配置 --> 模板(回填索引监控) --> 触发器 --> 创建触发器 --> 添加
    名称      回填索引入库数据=0
    严重性    严重
    表达式    {Indices_index_Alert:get_index.last(#1)}<=0 and {Indices_index_Alert:get_index.nodata(15m)}=1
    允许手动关闭
    描述      最近5分钟的回填索引 index_* 数量小于等于0,且持续15分钟
    
    image

    自动发现主机,添加发现主机,为主机关联模板 以下以主机es1为例

    配置 --> 自动发现 --> 创建发现规则 --> 添加
    名称      Local network
    IP范围    192.168.6.0-254
    更新间隔  1h
    检查     新的(检查类型:Zabbix客户端,端口范围:10050,键值:system.uname) --> 添加
    
    image
    配置 --> 主机 --> 创建主机 --> 添加
    主机名称            es1
    群组                Linux servers
    agent代理程序的接口  (IP地址:192.168.6.10,连接到:IP地址,端口:10050) --> 添加
    
    image
    配置 --> 主机(es1) --> 模板 --> 更新
    链接指示器(选择对应模板)--> 添加
    
    image

    实现钉钉机器人告警功能 企业微信号告警配置与此雷同

    管理--> 报警媒介类型 --> 创建媒体类型 --> 添加
    名称      dingalert_script
    类型      脚本
    脚本名称  dingding.py      # 该名称必须与服务端上创建的一致
    脚本参数  {ALERT.MESSAGE}  --> 添加
    
    image
    管理--> 用户(Admin) --> 报警媒介 --> 添加 --> 更新
    类型      dingalert_script
    收件人    Admin
    
    image
    配置 --> 动作 --> 创建动作 --> 添加
    名称   alert_to_ding
    操作 --> 新的 --> 添加
    恢复操作 --> 新的 --> 添加(与操作类似)
    
    image
    image

    测试钉钉机器人告警功能

    管理 --> 报警媒介类型 --> 测试
    收件人    Admin
    主题      Test subject
    消息      This is the test message from Zabbix
    
    image

    真实告警案例

    image
    image image
    image

    Zabbix监控告警ELK相关内容已到此为止,上面的演示都是针对es服务,其他的logstash和kibana也是差不多操作,仔细瞧瞧吧!

    相关文章

      网友评论

          本文标题:Zabbix监控告警ELK

          本文链接:https://www.haomeiwen.com/subject/sjbikktx.html