はじめに
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の設定が必要となります。)
今回は、以下の通り設定しました。(設定可能な項目の一覧はこちら)。
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
は以下の通り。
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も増加します。)
ちゃんと通知できているようです。