Grafana で Elasticserch に蓄積したサーバーメトリクスの可視化+アラートのSlack通知環境を構築してみた (ニフクラ)

このエントリーをはてなブックマークに追加

こんにちは。データデザイン部の矢部です。
主にデータエンジニアとしてニフクラや Google Cloud Platform (GCP) 上でのデータ処理基盤や外部連携用の API 開発などを担当しています。

データデザイン部では異常な動作を検知し運用担当者に通知するために各種監視機能を利用していますが、
今回はその中で Grafana を Elasticsearch に接続して可視化・監視する方法を紹介いたします。

目次

  • 背景
  • 構築するシステムの概要
  • 製品について
    • Elastic Stack
    • Grafana
  • この構成のメリットとデメリット
  • Grafana サーバーの構築
    • インフラの準備
    • Grafana の構築
  • ダッシュボードの作成
  • アラートの設定
  • アラートの Slack 連携
    • Slack 通知の追加
    • 画像付き通知の対応
      • 送信テストでは正しく画像が添付されていたが?
  • まとめ

背景

ニフクラ上に構築したサーバーの稼働状況を可視化して、異常があればアラートを上げる。このような監視作業を自動化する手段として、ニフクラには「基本監視」機能があります。

ニフクラの基本監視を使用すればUNIX の top コマンドで取得できるレベルのメトリクスをはじめ、PINGを用いた疎通確認や起動ステータスなどを可視化したり、アラートの設定をしたりなどといったことができます。

しかしながら、時にはサーバーが出力するログやメトリクスを Elasticsearch のような検索エンジンで分析して異常検知に活かしたいというケースもあります。

ニフクラ上で「基本監視」よりも高度な監視を構築する方法として ニフクラの有人監視サービスの利用やニフクラのサーバーにZabbix、Prometheus + Grafana、Elastic Stack を導入する、クラウドサービス (Mackerel や GCPに統合されている StackDriver Logging など) を利用するなどの方法が考えられます。

今回はこの中から Elasticsearch に簡単に接続できて構築も簡単な Grafana を取り上げます。(簡単そうに思えましたが落とし穴はありました)

Elastic Stack をすでに構築している(構築しようとしている)のであれば Elastic Stack + Grafana の組み合わせは手軽な可視化・アラート通知の手段であり、最小限のコストでアラート機能を追加できます。

構築するシステムの概要

各サーバーから収集したデータを一旦 Elasticsearch に集約して蓄積し、Grafana から必要な範囲のデータを取得して可視化したり、閾値を超えた値に対してアラートを送信したりできます。

近年のシステム構築では docker を利用するケースも増えているため、他のコンテナと Grafana を共存させることを想定して docker コンテナで Grafana を実行します。

構築作業ではニフクラの機能を使用していますが、DB を SQLite に設定するか RDB 相当の機能を別途用意すれば、他の環境にも適用できます。

製品について

Elastic Stack

Elastic Stack は Elastic が公開しているデータの収集・加工・集計・分析のソフトウェア群です。
Elasticsearch を中心として Logstash、Kibana、Beats と拡張機能の X-Pack があります。

X-Pack は設定しているライセンスによって使用できる機能の範囲が異なり、
有償プランを契約している場合は Alerting 機能が利用できるため、あえて Grafana を使うメリットは無いかもしれません。

公式サイト: https://www.elastic.co/jp/

Grafana

Grafana Labs が公開しているデータの可視化ツールです。
Kibana と比較すると表示がシンプルで、操作も軽快です。
Prometheus をはじめ Zabbix や Elasticsearch など、様々なデータソースを統合して扱えます。

公式サイト: https://grafana.com/

この構成のメリットとデメリット

メリット

  • KQL で直感的に柔軟な監視クエリを記述できる

デメリット

  • バックエンドに Elasticsearch を使用しているため、マシンリソースを必要とする

Grafana サーバーの構築

Grafana サーバーをニフクラ上に構築する方法を説明します。
Grafana が接続する対象の Elasticsearch の構築方法についてはここでは扱いませんので、 Elastic の公式サイトなどを参考にしてください。

インフラの準備

Grafana を動作させるために必要なインフラを準備します。大きく分けて2つのものを準備します。

  1. サーバー
  2. RDB

実際のプロジェクトで使用する場合には、細かく設定する必要があるかもしれませんが、ここでは Grafana を ニフクラの機能を使用して構成できることを確認できることを優先して設定しています。

1. サーバー

SSHキーとファイアウォールを適切に設定したサーバーを作成します。

CentOS を選択していますが、他のディストリビューションでも docker デーモンが動作する環境であれば構築は可能です。

サーバーを作成するリージョンとゾーンはRDBと合わせたほうが後の接続は容易になります。

作成したサーバーへの接続方法などはニフクラのドキュメントなどをご参照ください。

関連ドキュメント: https://pfs.nifcloud.com/guide/cp/

2. RDB

RDB を作成する前にファイアウォールの設定をします。

ここでのポイントは DBファイヤーウォールグループに TestGrafana ファイヤーウォールグループを追加することです。この設定により TestGrafana ファイヤーウォールを設定しているすべてのサーバーから、この DBファイヤーウォールグループを設定している DB への通信が許可されます。

関連ドキュメント: https://pfs.nifcloud.com/spec/rdb/fw.htm

DBファイヤーウォールとDB設定を正しく設定した DB サーバーを作成します。

こちらの RDB は Grafana の設定を保存するためのものなので、容量も性能も最低限のもので問題ありません。

要件に応じて自動バックアップや冗長化を設定してください。また、DB設定の DB名とマスターユーザー名は 後述する Docker Compose の設定と一致するようにします。こちらも必要に応じて変更してください。

Grafana の構築

構築を簡単に済ませる方法は docker を用いる方法です。

docker 実行時のオプションが多数あることや、後ほど Slack 通知のために外部ストレージが必要になったり、メール通知のためにメールサーバーを設定したりする関係で Docker Compose を使用します。

以降の手順は Grafana サーバーの構築 > 1. サーバーの準備 で作成したサーバーに root ユーザーでログインしたシェル上で実行します。
手順はニフクラ上にサーバーを作成した直後を前提として記述しています。

デフォルトの Docker を削除
yum remove \
    docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine
Docker のインストール
yum install \
    yum-utils \
    device-mapper-persistent-data \
    lvm2 \
    -y
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum makecache fast
yum install \
    docker-ce \
    docker-ce-cli \
    containerd.io \
    -y
systemctl start docker
systemctl enable docker
Docker Compose のインストール
DOCKER_COMPOSE_FILE=/usr/local/bin/docker-compose
DOCKER_COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4)
mkdir -p ${DOCKER_COMPOSE_FILE%/*}
curl \
    -L https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_VERSION/docker-compose-`uname -s`-`uname -m` \
    -o $DOCKER_COMPOSE_FILE
chmod +x $DOCKER_COMPOSE_FILE
docker-compose.yml ファイルの作成

以下の変数に先程の環境構築で構築したサーバーの情報を設定します。
GF_SECURITY_ADMIN_PASSWORD は任意のパスワードを設定します。
HTTPS化するまで通信は平文ですので、他のシステムで使用しているパスワードの使い回しは避けてください。また、実プロジェクトで構築する場合はシステムに平文でパスワードを保存しないようにしてください。

GF_SERVER_ROOT_URL=http://(Grafana サーバーのグローバル IP アドレス).nip.io
GF_DATABASE_HOST=(RDB のプライベート IP アドレス):(ポート番号)
GF_DATA_PASSWORD=(RDB のマスターユーザーのパスワード)
GF_SECURITY_ADMIN_PASSWORD=(Web GUI にログインするユーザーのパスワード)

以下のコマンドを実行してファイルを生成します。

PROJECT_DIR=~/grafana
COMPOSE_YAML_FILE=docker-compose.yml

mkdir -p "$PROJECT_DIR"
cd "$PROJECT_DIR"

cat << EOS >"$COMPOSE_YAML_FILE"
services:
  grafana:
    container_name: grafana
    environment:
      GF_SERVER_ROOT_URL: $GF_SERVER_ROOT_URL
      GF_SERVER_ENABLE_GZIP: 'true'
      GF_DATABASE_TYPE: postgres
      GF_DATABASE_HOST: $GF_DATABASE_HOST
      GF_DATABASE_NAME: grafana
      GF_DATABASE_USER: grafana
      GF_DATABASE_PASSWORD: $GF_DATA_PASSWORD
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: $GF_SECURITY_ADMIN_PASSWORD
      TZ:
    image: grafana/grafana:6.5.3
    ports:
      - '80:3000'
    restart: always
EOS

cat "$COMPOSE_YAML_FILE"
Grafana の起動
cd "$PROJECT_DIR"
docker-compose up -d --build
ログの確認
cd "$PROJECT_DIR"
docker-compose logs -f grafana

エラーが出ずに DB のマイグレーションが完了することを確認します。問題がなければ Ctrl+C 等でログ表示を終了し、シェルに戻ります。

Web UI からのログイン

ニフクラのサーバーに設定されているファイヤーウォールはデフォルトでインバウンドのポートがすべてブロックされています。
ブラウザからアクセスする前にニフクラのファイヤーウォールに適切な INルールを設定します。

通信は暗号化されておらず、認証情報が読み取られた場合の乗っ取りを防止するため、接続元のグローバル IP アドレスで接続元を制限すると良いでしょう。

ファイヤーウォール設定画面で、以下のように接続元種別を 接続しているIPアドレス にすることで簡単に設定できます。

接続元IPが動的に変動する環境の場合はその都度ルールの更新が必要です。

ファイヤーウォールの設定が適用できたところでブラウザ等から先程 $GF_SERVER_ROOT_URL として設定した URL を開き、ログインできることを確認します。

ログインに使用するアカウントは以下です。

  • ユーザーID: admin
  • パスワード: ($GF_SECURITY_ADMIN_PASSWORD に設定した値)

Elasticsearchの接続

ダッシュボードからCreate your first data source > Elasticsearchを選択します。

以下の画像は、

  • Basic 認証あり
  • TLS の証明書は自己署名
  • CA Certファイルあり

の場合の設定例です。環境に合わせて設定してください。

ダッシュボードの作成

Elasticsearch をデータソースにした場合、検索クエリが Elasticsearch に依存したものになります。Grafana のクエリUIよりも Kibana のものに慣れている場合は Kibana 上でクエリを組み立てたものをコピーして実行するのも Grafana に慣れる練習としてはアリだと思います。


Using Elasticsearch in Grafana (英語): https://grafana.com/docs/grafana/latest/features/datasources/elasticsearch/

アラートの設定

アラートの設定はダッシュボードの作成時に設定します。アラート設定の柔軟性を考えると、専用にダッシュボードを作成するのも良さそうです。

Slack との連携は Grafana にログインした後にアラートのチャネル設定から追加できます。

アラートの Slack 連携

Grafana は WebHook を利用して簡単にアラートの通知を Slack に通知することが出来ます。

Slack のワークスペースをお持ちで、ログインした状態を前提に解説していきますので、必要に応じて準備していただければと思います。

Slack 通知の追加

まず、 Slack の App 設定から Incomming WebHooks の Seggings を開き、適当な通知設定を作成します。
このとき、Webhook URL が発行されますので、後で貼り付けられるように記録しておきます。

次に、 Grafana の Alerting > Notification channels > New channelsと開き、Slack settings の Url に先程記録した Webhook URL を設定します。

通知 channel を作成することで、ダッシュボードのアラート設定時に通知先として選択できるようになります。

画像付き通知の対応

送信テストでは正しく画像が添付されていたが?

アラート設定時に Send Testを実行された方もいらっしゃるかもしれませんが、ここに落とし穴があります
実は、このとき送信された画像は今回構築した Grafana のサーバーから送信されたものではありません。

Grafana はアラート時に添付する画像を配信する機能を持っていません。 Slack でアラートを受信した時に画像を正しく表示するためには Slack から認証なしで読み取り可能なストレージ (Amazon S3、WebDAV、Google Cloud Storage、Azure Blob Storage) 上に画像を保存しておく必要があります。

ニフクラにも同様の機能としてオブジェクトストレージがありますが、 Grafana の該当部分のソースコードを読んだ限りでは対応していませんでした。

参考: Enable images in notifications(英語)

画像付き Slack 通知を送れるようにニフクラ上に WebDAV サーバーを構築して対処出来ますが、
長くなってしまうので、こちらの問題の解決方法は、また別の機会といたします。

まとめ

Grafana をニフクラ上に構築し、データソースとして Elasticsearch を設定した上でダッシュボード表示に必要なクエリを実行しました。

構築したダッシュボードのクエリに対して監視のアラートを設定し、 Slack と連携することで無人かつ、どこにいてもアラートの通知を確認できる環境を構築することができました。

Grafana から Slack に通知する際の問題としてアラート発生時の画像を配信する環境を別途構築する必要があります。ニフクラのみで解決する場合は WebDAV を有効にした Web サーバーを構築することで画像付きのアラート配信に対応できます。

お気軽にご相談ください

データ活用からAI開発まで、お客様の事業課題を解決するお手伝いをいたします。
どうぞお気軽にご相談ください。

お問い合わせ・ご相談はこちらから

WRITER
Kazunari Yabe

データエンジニア

矢部 一成Kazunari Yabe

主にデータエンジニアとして、データ分析基盤の構築やAI活用のシステム開発を担当。  情報処理安全確保支援士、応用情報技術者

最新記事

ページTOPへ