2019年7月3日水曜日

Zabbix4.2 でアラートを Slack に通知してみた

概要

Zabbix のアラートを Slack に飛ばしてみました
一応公式の perl スクリプトがあるので今回はそれを使っています

環境

  • Zabbix サーバ
    • Ubuntu 16.04 LTS
    • docker 18.09.6
    • Zabbix Server 4.2

イメージ準備

Perl スクリプトは当然ですが docker の公式イメージにはインストールされていません
なのでスクリプトインストール入りのイメージを作成します

  • mkdir docker
  • cd docker
  • vim Dockerfile
FROM zabbix/zabbix-server-mysql:ubuntu-4.2-latest

RUN apt -y update
RUN apt -y install libwww-perl libjson-xs-perl
RUN apt -y install libtest-simple-perl libtest-most-perl
RUN apt -y install git
RUN apt -y install build-essential
RUN git clone https://github.com/v-zhuravlev/zabbix-notify.git
WORKDIR zabbix-notify
RUN perl Makefile.PL INSTALLSITESCRIPT=/usr/lib/zabbix/alertscripts
RUN make test
RUN make install
  • docker build -t my_zabbix .

これでイメージの作成は完了です
alertscripts のパスは公式の docker 版の場合以下のようになっていました

  • docker-compose -f docker-compose_v3_ubuntu_mysql_latest.yaml exec zabbix-server grep 'alertscripts' /etc/zabbix/zabbix_server.conf

=> AlertScriptsPath=/usr/lib/zabbix/alertscripts

docker-compose ファイルの作成

公式の既存の docker-compose.yaml ファイルを書き換えます

  • vim docker-compose_v3_ubuntu_mysql_latest.yaml
version: '3.5'
services:
 zabbix-server:
  image: my_zabbix
  ports:
   - "10051:10051"
  volumes:
   - /etc/localtime:/etc/localtime:ro
   - ./zbx_env/usr/lib/zabbix/externalscripts:/usr/lib/zabbix/externalscripts:ro
   - ./zbx_env/var/lib/zabbix/modules:/var/lib/zabbix/modules:ro
   - ./zbx_env/var/lib/zabbix/enc:/var/lib/zabbix/enc:ro
   - ./zbx_env/var/lib/zabbix/ssh_keys:/var/lib/zabbix/ssh_keys:ro
   - ./zbx_env/var/lib/zabbix/mibs:/var/lib/zabbix/mibs:ro
  links:
   - mysql-server:mysql-server
  ulimits:
   nproc: 65535
   nofile:
    soft: 20000
    hard: 40000
  deploy:
   resources:
    limits:
      cpus: '0.70'
      memory: 1G
    reservations:
      cpus: '0.5'
      memory: 512M
  env_file:
   - .env_db_mysql
   - .env_srv
  user: root
  depends_on:
   - mysql-server
  networks:
   zbx_net_backend:
     aliases:
      - zabbix-server
      - zabbix-server-mysql
      - zabbix-server-ubuntu-mysql
      - zabbix-server-mysql-ubuntu
   zbx_net_frontend:
  stop_grace_period: 30s
  sysctls:
   - net.ipv4.ip_local_port_range=1024 65000
   - net.ipv4.conf.all.accept_redirects=0
   - net.ipv4.conf.all.secure_redirects=0
   - net.ipv4.conf.all.send_redirects=0
  labels:
   com.zabbix.description: "Zabbix server with MySQL database support"
   com.zabbix.company: "Zabbix SIA"
   com.zabbix.component: "zabbix-server"
   com.zabbix.dbtype: "mysql"
   com.zabbix.os: "ubuntu"

 zabbix-web-apache-mysql:
  image: zabbix/zabbix-web-apache-mysql:ubuntu-4.2-latest
  ports:
   - "80:80"
   - "443:443"
  links:
   - mysql-server:mysql-server
   - zabbix-server:zabbix-server
  volumes:
   - /etc/localtime:/etc/localtime:ro
   - ./zbx_env/etc/ssl/apache2:/etc/ssl/apache2:ro
  deploy:
   resources:
    limits:
      cpus: '0.70'
      memory: 512M
    reservations:
      cpus: '0.5'
      memory: 256M
  env_file:
   - .env_db_mysql
   - .env_web
  user: root
  depends_on:
   - mysql-server
   - zabbix-server
  healthcheck:
   test: ["CMD", "curl", "-f", "http://localhost"]
   interval: 10s
   timeout: 5s
   retries: 3
   start_period: 30s
  networks:
   zbx_net_backend:
    aliases:
     - zabbix-web-apache-mysql
     - zabbix-web-apache-ubuntu-mysql
     - zabbix-web-apache-mysql-ubuntu
   zbx_net_frontend:
  stop_grace_period: 10s
  sysctls:
   - net.core.somaxconn=65535
  labels:
   com.zabbix.description: "Zabbix frontend on Apache web-server with MySQL database support"
   com.zabbix.company: "Zabbix SIA"
   com.zabbix.component: "zabbix-frontend"
   com.zabbix.webserver: "apache2"
   com.zabbix.dbtype: "mysql"
   com.zabbix.os: "ubuntu"

 zabbix-web-nginx-mysql:
  image: zabbix/zabbix-web-nginx-mysql:ubuntu-4.2-latest
  ports:
   - "8081:80"
   - "8443:443"
  links:
   - mysql-server:mysql-server
   - zabbix-server:zabbix-server
  volumes:
   - /etc/localtime:/etc/localtime:ro
   - ./zbx_env/etc/ssl/nginx:/etc/ssl/nginx:ro
  deploy:
   resources:
    limits:
      cpus: '0.70'
      memory: 512M
    reservations:
      cpus: '0.5'
      memory: 256M
  env_file:
   - .env_db_mysql
   - .env_web
  user: root
  depends_on:
   - mysql-server
   - zabbix-server
  healthcheck:
   test: ["CMD", "curl", "-f", "http://localhost"]
   interval: 10s
   timeout: 5s
   retries: 3
   start_period: 30s
  networks:
   zbx_net_backend:
    aliases:
     - zabbix-web-nginx-mysql
     - zabbix-web-nginx-ubuntu-mysql
     - zabbix-web-nginx-mysql-ubuntu
   zbx_net_frontend:
  stop_grace_period: 10s
  sysctls:
   - net.core.somaxconn=65535
  labels:
   com.zabbix.description: "Zabbix frontend on Nginx web-server with MySQL database support"
   com.zabbix.company: "Zabbix SIA"
   com.zabbix.component: "zabbix-frontend"
   com.zabbix.webserver: "nginx"
   com.zabbix.dbtype: "mysql"
   com.zabbix.os: "ubuntu"

 zabbix-agent:
  image: zabbix/zabbix-agent:ubuntu-4.2-latest
  ports:
   - "10050:10050"
  volumes:
   - /etc/localtime:/etc/localtime:ro
   - ./zbx_env/etc/zabbix/zabbix_agentd.d:/etc/zabbix/zabbix_agentd.d:ro
   - ./zbx_env/var/lib/zabbix/modules:/var/lib/zabbix/modules:ro
   - ./zbx_env/var/lib/zabbix/enc:/var/lib/zabbix/enc:ro
   - ./zbx_env/var/lib/zabbix/ssh_keys:/var/lib/zabbix/ssh_keys:ro
  links:
   - zabbix-server:zabbix-server
  deploy:
   resources:
    limits:
      cpus: '0.2'
      memory: 128M
    reservations:
      cpus: '0.1'
      memory: 64M
   mode: global
  env_file:
   - .env_agent
  user: root
  privileged: true
  pid: "host"
  networks:
   zbx_net_backend:
    aliases:
     - zabbix-agent
     - zabbix-agent-passive
     - zabbix-agent-ubuntu
  stop_grace_period: 5s
  labels:
   com.zabbix.description: "Zabbix agent"
   com.zabbix.company: "Zabbix SIA"
   com.zabbix.component: "zabbix-agentd"
   com.zabbix.os: "ubuntu"

 mysql-server:
  image: mysql:8.0
  command: [mysqld, --character-set-server=utf8, --collation-server=utf8_bin, --default-authentication-plugin=mysql_native_password]
  volumes:
   - ./zbx_env/var/lib/mysql:/var/lib/mysql:rw
  env_file:
   - .env_db_mysql
  user: root
  stop_grace_period: 1m
  networks:
   zbx_net_backend:
    aliases:
     - mysql-server
     - zabbix-database
     - mysql-database

 db_data_mysql:
  image: busybox
  volumes:
   - ./zbx_env/var/lib/mysql:/var/lib/mysql:rw

networks:
  zbx_net_frontend:
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "false"
    ipam:
      driver: default
      config:
      - subnet: 172.16.238.0/24
  zbx_net_backend:
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "false"
    internal: true
    ipam:
      driver: default
      config:
      - subnet: 172.16.239.0/24

少し長いですが書き換えているのは以下の通りです

  • Zabbix サーバのイメージをビルドした my_zabbix に変更
  • ./zbx_env/usr/lib/zabbix/alertscripts:/usr/lib/zabbix/alertscript:ro を削除
  • zabbix-proxy-sqlite3, zabbix-proxy-mysql を削除
  • zabbix-java-gateway, zabbix-snmptraps を削除

スクリプトは直接コンテナに配置していますがホストでインストールして配置してそれをマウントしても OK です
またホスト側に alertscript ディレクトリがある場合は事前に削除しておきましょう

  • sudo rm -rf zbx_env/usr/lib/zabbix/alertscripts/

削除しているのは up する際に起動するサービスを指定しても OK です

Zabbix サーバ起動

  • docker-compose -f docker-compose_v3_ubuntu_mysql_latest.yaml up -d
  • docker-compose -f docker-compose_v3_ubuntu_mysql_latest.yaml ps
               Name                              Command                       State                          Ports               
----------------------------------------------------------------------------------------------------------------------------------
zabbix-docker_db_data_mysql_1         sh                               Exit 0                                                     
zabbix-docker_mysql-server_1          docker-entrypoint.sh mysql ...   Up                                                         
zabbix-docker_zabbix-agent_1          /sbin/tini -- /usr/bin/doc ...   Up                                                         
zabbix-docker_zabbix-server_1         /sbin/tini -- /usr/bin/doc ...   Up                      0.0.0.0:10051->10051/tcp           
zabbix-docker_zabbix-web-apache-      docker-entrypoint.sh             Up (health: starting)   0.0.0.0:443->443/tcp,              
mysql_1                                                                                        0.0.0.0:80->80/tcp                 
zabbix-docker_zabbix-web-nginx-       docker-entrypoint.sh             Up (health: starting)   0.0.0.0:8443->443/tcp,             
mysql_1

起動しているホストの 80 番ポートにアクセスすれば管理画面が表示されます

スクリプト動作確認

コンテナに配置したスクリプトを手動で実行して動作確認します
Slack 上に Bots アプリが必要になるので作成しましょう
今回は「zabbix_bot」という名前のボットにしました
アイコンなどは適当に設定してください
必要になるのは API Token になるのでコピーしておきます

ボットが作成できたら Slack 上でチャネルに招待しましょう

  • /invite @zabbix_bot

そしてコンテナ上のスクリプトを実行してみます

  • docker-compose -f docker-compose_v3_ubuntu_mysql_latest.yaml exec zabbix-server /bin/bash

でコンテナに入り以下を実行しましょう

  • cd /usr/lib/zabbix/alertscripts/
  • docker-compose -f docker-compose_v3_ubuntu_mysql_latest.yaml exec zabbix-server /usr/lib/zabbix/alertscripts/zbx-notify @hawksnowlog 'PROBLEM:myHOSTNAME Temperature Failure on DAE5S Bus 1 Enclosure 1' 'Host: myHOSTNAME Trigger: PROBLEM: myHOSTNAME Temperature Failure on DAE5S Bus 1 Enclosure 1: High Timestamp: 2016.03.14 11:57:10 YEKT eventid: 100502' --api_token=xoxb-58452257553-675165639408-w75zUlSmXlqZpKh8o2HdOp7o --slack
  • ./zbx-notify @hawksnowlog 'OK:myHOSTNAME Temperature Failure on DAE5S Bus 1 Enclosure 1' 'Host: myHOSTNAME Trigger: OK: myHOSTNAME Temperature Failure on DAE5S Bus 1 Enclosure 1: High Timestamp: 2016.03.14 11:57:10 YEKT eventid: 100502' --api_token=xoxb-58452257553-675165639408-w75zUlSmXlqZpKh8o2HdOp7o --slack

以下のように通知されればスクリプトの動作確認は OK です


スクリプトが見つからない場合は再度インストールしてみましょう

  • docker-compose -f docker-compose_v3_ubuntu_mysql_latest.yaml exec zabbix-server make install

メディアの設定

Zabbix の Slack 通知の仕組みはインストールしたスクリプトを実行しているだけです
そしてそのスクリプトを実行するのはメディアになります

Administraion -> Media types
で「Create media type」を選択しましょう
そして以下のように入力します

  • Name・・・好きな名前を設定します
  • Type・・・Script
  • Script name・・・zbx-notify
  • Script parameters
    • {ALERT.SENDTO}
    • {ALERT.SUBJECT}
    • {ALERT.MESSAGE}
    • --api_token=you_token_here
    • --slack

これで Update しましょう

作成されると一覧に表示されます
ちなみに --slack_mode=alarm というパラメータも付与するとアラートが復帰した情報も通知してくれるようになります

ユーザのメディアを変更する

メンションするユーザ名は Zabbix のユーザに紐付いているメディア情報を編集します
Administraion -> Users
でメディアを編集するユーザを選択します
そして Media タブを選択し Type に先程作成した「Alert to Slack」を選択します
そして Send to にメンションしたいユーザ名を設定します

ちなみに Send to を「#general」にすればチャネルに通知できます 

アクションの作成

アラートが上がったら作成したメディアに通知するアクションを作成します
Configuration -> Actions で右上の Event source のプルダウンを「Triggers」に変更し「Create action」を選択します

Action タグで条件を設定します

  • Name・・・好きな名前を設定します
  • New condition・・・Trigger serverity equals Average

で Add しましょう
条件も好きな条件を設定して OK です

次に Operation タブを設定します

  • Default subject・・・{TRIGGER.STATUS}:{HOSTNAME}:{TRIGGER.NAME}.
  • Default message
Host: {HOSTNAME}
Trigger: {STATUS}: {TRIGGER.NAME}: {TRIGGER.SEVERITY}
Timestamp: {EVENT.DATE} {EVENT.TIME}
{TRIGGER.COMMENT}
{TRIGGER.URL}
http://192.168.99.200
Eventid: {EVENT.ID}
  • Operations
    • Operation type・・・Send message
    • Send to Users・・・Admin
    • Send only to・・・Alert to Slack (作成したメディア)

通知のメッセージはそのままでも OK ですが上記をおすすめしていたので素直に変更しました
で Add を押して追加します

これでアクションの作成は完了です
Average なトリガーが発泡されると Action 経由で Slack に通知が行きます

動作確認 (アラートを上げる)

何でもいいのでアラートを上げてみましょう
今回の場合は Average なトリガーでなければいけません
一番手っ取り早いのは監視しているホストの zabbix-agent を停止します
Monitoring -> Problems でトリガーが上がれば Slack 側にもメンションが来るのが確認できると思います

最後に

Zabbix4.2 で Slack にアラート情報を通知してみました
仕組みとしては単純でスクリプトを実行しているだけです
公式は Perl スクリプトになっていますがシェバングで Ruby などを指定すれば Ruby の通知スクリプトも作成可能です
(当然 Ruby がインストールされているイメージが必要ですが)
Perl のスクリプトを見ながら実装しても良いと思います

正直スクリプトなのでやり方は何でも OK です
直接 Zabbix から通知してもいいですが一旦 IFTTT を経由しても OK ですし Cloud Function などに渡しても OK です

参考サイト

0 件のコメント:

コメントを投稿