Zabbix监控告警ELK

2020-07-21  本文已影响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也是差不多操作,仔细瞧瞧吧!

上一篇下一篇

猜你喜欢

热点阅读