Basicライセンスの下、Elasticsearchのアラートを発報する


はじめに

Elasticsearchを使っていると、データが溜まってくるに従ってインデックスが多くなってきます。
インデックスパターン毎にライフサイクルを管理できていれば良いですが、
うっかりしていると多くなりすぎて、open_file_descriptorsが最大値(max_file_descriptors)に達してしまい、
インデックスが作成できなくなる事態が発生し得ます。

こういったリソース不足の発生を検知するために、リソース状況を監視し、通常と異なる振る舞いをしている場合にはアラートを発報することが必要です。

Elasticsearchの有償ライセンスを購入していれば、Watcherというアラート機能を使用することができますが、無償のBasicライセンスで運用している場合、Watcher機能を使用することができません。

そこで、アラート通知のためにgrafanaを利用し、Elasticsearchノードのリソース不足を通知できるようにしてみます。
(Elasticsearch + grafanaという組み合わせは検索するとたくさん出てきますが、「Elasticsearchでアラートと言ったらWatcher!」という固定観念があり、なかなかそれに気が付きませんでした。grafana自体ほとんど使ったことがなかったので、今回はその備忘を兼ねて書きます。)

環境

以下の環境で試してみます。

$ docker version
Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:22:05 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea838
  Built:            Wed Nov 13 07:28:45 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

$ docker images | grep elasticsearch
elasticsearch                       7.6.1               41072cdeebc5        4 weeks ago         790MB

$ docker images | grep grafana
grafana/grafana                     6.7.0               8d9380d6a636        11 days ago         233MB

Elasticsearch の設定

何はともあれ、X-Pack Monitoringを有効にして、モニタリングデータを収集できるようにします(デフォルトでは有効になっていません)。
こちらを参考にして、収集したモニタリングデータを同じクラスタに格納します。
(本番環境でX-Pack Monitoringを使用する場合、本番ワークロードを実行するクラスタとモニタリングデータを収集するクラスタを分けることが推奨されています。また、モニタリングデータの収集・転送には、MetricBeatを使用することが推奨されています。)

今回は簡単のため、単一のElasticsearchノードからなるクラスタで試します。
(複数ノードクラスタを使用する場合、Basicライセンス下ではX-Pack Securityの設定が必要となります。)

今回は、以下の通り設定しました。(設定可能な項目の一覧はこちら)。

docker-compose.yml
services:
  elasticsearch:
    image: elasticsearch:7.6.1
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.monitoring.enabled=true
      - xpack.monitoring.collection.enabled=true
      - xpack.monitoring.elasticsearch.collection.enabled=true
    ports:
      - "9200:9200"

収集されたElasticsearchのモニタリングデータは、インデックスパターンが.monitoring-es-7-*であるインデックスに格納されます(templateは.monitoring-esです)。

$ curl -s "localhost:9200/_cat/indices" | grep "\.monitoring-es-7"
green open .monitoring-es-7-2020.03.21 5GydtmSWSCSmKHYmVIUoXw 1 0 1001 165 701kb 701kb

Grafanaの設定

モニタリングデータの収集ができるようになったので、grafanaでデータを取得し、アラートを設定します。
以下は、公式ドキュメントを参考に設定しています。
docker-compose.ymlは以下の通り。

docker-compose.yml
version: "2.2"
services:
  grafana:
    image: grafana/grafana:6.7.0
    container_name: grafana
    ports:
      - "3000:3000"

データソース設定

データソースとして、収集対象のインデックスを設定します。
注意点として、普通のインデックスでは、データ投入時点を表す@timestampフィールドが存在しますが、.monitoring-*のインデックスには@timestampが存在しません。代わりにtimestampフィールドが存在するので、Time field nameにはそちらを指定します。
今回は以下の通り設定しました。


通知チャネルの設定

通知チャネルを作成します。今回は、Slackへ通知してみることにします。
SlackでIncoming Webhookをあらかじめ作成しておきます。
以下のように設定しました。

アラートの設定

file descriptorの増加を監視するためのメトリックはnode_stats.process.open_file_descriptorsです。
監視設定とアラートの設定を、以下の通り設定しました。
(アラートが発報されるのを確認するため、閾値は小さい値を設定しています。)


アラートの確認

設定できたら、アラートの確認をします。(モニタリングインデックス自体が増加するため、それに伴いfile descriptorも増加します。)

ちゃんと通知できているようです。