golang実装でバイナリが配布されているので簡単に設置・動作させられるのがポイントです。
とにかくすぐ動くので(ZabbixとかMuninとかと比べて)簡単に試すことができますよ。
当方はCentOS6で作業しておりますので適宜読み替えてください。
簡易動作
監視ホスト側
ソースはこちら(https://github.com/prometheus/prometheus) ですがコンパイルが面倒なのでrelease版をダウンロードして実行します。
# versionは2018/06/06時点最新 2.2.1
$ wget https://github.com/prometheus/prometheus/releases/download/v2.2.1/prometheus-2.2.1.linux-amd64.tar.gz
$ tar xzf prometheus-2.2.1.linux-amd64.tar.gz
$ cd prometheus-2.2.1.linux-amd64
$ ./prometheus
9090
ポートが解放されていればhttp://yourserver.com:9090
で動作します。
細かい設定は後述。
クライアント側
exporterを設置する事でホストからのpullの受け口になります。
監視したいサービスに合わせた様々なexporterがあります。公式によるまとめはこちら
Apache、MySQLはもちろんAWS等のクラウドに対応したexporterも多数用意されているので監視対象に合わせて選んでみるとよいでしょう。
今回は一番ベーシックなCPUやメモリ値を取得するnode_exporterを導入してみます。
nodeと名前にあるのでnodeサーバーの監視用かと思いましたが枝のnodeの事でした。
# バージョンと環境に合わせた構成のURLを確認(https://github.com/prometheus/node_exporter/releases)
$ wget https://github.com/prometheus/node_exporter/releases/download/v0.16.0/node_exporter-0.16.0.linux-amd64.tar.gz
$ tar xzf node_exporter-0.16.0.linux-amd64.tar.gz
$ cd node_exporter-0.16.0.linux-amd64
$ ./node_exporter
# 以下のように実行されました
INFO[0000] Starting node_exporter (version=0.16.0, branch=HEAD, revision=d42bd70f4363dced6b77d8fc311ea57b63387e4f) source="node_exporter.go:82"
INFO[0000] Build context (go=go1.9.6, user=root@a67a9bc13a69, date=20180515-15:52:42) source="node_exporter.go:83"
INFO[0000] Enabled collectors: source="node_exporter.go:90"
INFO[0000] - arp source="node_exporter.go:97"
INFO[0000] - bcache source="node_exporter.go:97"
INFO[0000] - bonding source="node_exporter.go:97"
INFO[0000] - conntrack source="node_exporter.go:97"
INFO[0000] - cpu source="node_exporter.go:97"
INFO[0000] - diskstats source="node_exporter.go:97"
INFO[0000] - edac source="node_exporter.go:97"
INFO[0000] - entropy source="node_exporter.go:97"
INFO[0000] - filefd source="node_exporter.go:97"
INFO[0000] - filesystem source="node_exporter.go:97"
INFO[0000] - hwmon source="node_exporter.go:97"
INFO[0000] - infiniband source="node_exporter.go:97"
INFO[0000] - ipvs source="node_exporter.go:97"
INFO[0000] - loadavg source="node_exporter.go:97"
INFO[0000] - mdadm source="node_exporter.go:97"
INFO[0000] - meminfo source="node_exporter.go:97"
INFO[0000] - netdev source="node_exporter.go:97"
INFO[0000] - netstat source="node_exporter.go:97"
INFO[0000] - nfs source="node_exporter.go:97"
INFO[0000] - nfsd source="node_exporter.go:97"
INFO[0000] - sockstat source="node_exporter.go:97"
INFO[0000] - stat source="node_exporter.go:97"
INFO[0000] - textfile source="node_exporter.go:97"
INFO[0000] - time source="node_exporter.go:97"
INFO[0000] - timex source="node_exporter.go:97"
INFO[0000] - uname source="node_exporter.go:97"
INFO[0000] - vmstat source="node_exporter.go:97"
INFO[0000] - wifi source="node_exporter.go:97"
INFO[0000] - xfs source="node_exporter.go:97"
INFO[0000] - zfs source="node_exporter.go:97"
INFO[0000] Listening on :9100
クライアント側は9100
ポートを解放します。
http://yourclient.com:9100/metrics
でメトリクスが表示されればOKです。
次にクライアントをホストの監視対象に入れます。
ホスト側で動いていた./prometheus
をCtrl+Cでstopして設定ファイルを修正します。
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
# 追記 ここから
- job_name: 'clientname'
static_configs:
- targets: ['yourclient.com:9100']
# ここまで
再度./prometheus
を実行するとhttp://yourserver.com:9090
に反映されます。
ここまででホスト側にクライアントのデータを取得するまでができましたね。
異常発生時のアラート設定
ここはホスト側で作業します。
閾値越えでメールを投げるなど、監視としては必要な部分ですね。
Prometheus本体にはこの機構は含まれていないのでAlertmanagerという拡張機能のようなものを別途設置します。
./prometheusとは独立していて別ポートで動作します。
$ wget https://github.com/prometheus/alertmanager/releases/download/v0.14.0/alertmanager-0.14.0.linux-amd64.tar.gz
$ tar xzf alertmanager-0.14.0.linux-amd64.tar.gz
$ cd alertmanager-0.14.0.linux-amd64
※v0.15.0-rc.1だとエラーで動かなかったので0.14.0を使うことにした。
level=error ts=2018-06-06T10:29:16.315983112Z caller=main.go:160 msg="Unable to initialize gossip mesh" err="create memberlist: Failed to get final advertise address: No private IP address found, and explicit IP not provided"
AlertManager設定しないと動作しないのでここで一旦アラート設定もろもろを設定します。
Prometheus側には閾値等のアラート発生とするまでの定義条件を、
AlertManager側にはメールで誰々宛に送るよーみたいな設定をそれぞれしていきます。
- prometheusのグローバル設定
# もともとコメントしてあった部分を調整します
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- # - alertmanager:9093
+ # AlertManagerに丸投げ Prometheusと同一サーバーで動かす場合はlocalhost:9093
+ - localhost:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
- # - "first_rules.yml"
- # - "second_rules.yml"
+ # ルールは別ファイルで定義します
+ "alert_rules.yml"
- prometheusのルール設定
# 例:5分間インスタンスダウン
groups:
- name: node_exporter
rules:
- alert: InstanceDown
expr: up == 0
for: 5m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} has been down for more than 5 minutes."
expr条件の組み立て方は公式のドキュメントが詳しい
- alertmanagerの送信設定
global:
slack_api_url: 'https://hooks.slack.com/services/****'
route:
receiver: 'test-route'
group_by: [alertname]
group_wait: 10s
group_interval: 5m
repeat_interval: 1h
receivers:
- name: 'test-route'
slack_configs:
- channel: '#channel_name'
AlertManagerを起動します!
./alertmanager --config.file=alert.yml
この設定で監視対象サーバーでポート塞いだりすると5分後にslack飛びました。
簡単で良かった・・・
しっかり導入するなら
自動起動まわりの設定をしてあげると実運用レベルまで持っていけそうです。
/usr/local/binあたりにシンボリックリンク置いてパスを通します。
$ sudo ln -s "/path/to/prometheus" "/usr/local/bin/prometheus"
$ sudo ln -s "/path/to/alertmanager" "/usr/local/bin/alertmanager"
起動スクリプトはこのあたりを参考にさせて頂きました。各々環境に合わせてどうぞ。
自動起動しちゃいましょう。オプションが通らない場合は--help見た方が良いです。
$ chmod 755 /etc/rc.d/init.d/prometheus
$ chmod 755 /etc/rc.d/init.d/alertmanager
$ chkconfig --add prometheus
$ chkconfig --add alertmanager
$ chkconfig prometheus on
$ chkconfig alertmanager on
クライアント側でも同様にinit.dで動かしてもいいけど、root権限で触ったり仰々しいのでちょっとというサーバーもあるでしょう。
そういった場合は簡易的な死活監視shellをcronで実行してみるというのも手かもしれない。
ちょっと書いてみました。
#!/bin/bash
# exporterが動いているか監視します。cronで適当に実行します。
PWD=$(cd $(dirname $0);pwd)
EXPORTERS_DIR="$PWD/exporters/"
PROCESSES=("node_exporter")
for process in ${PROCESSES[@]};
do
isAlive=`ps -ef | grep "$process" | grep -v grep | grep -v prometheus.sh | wc -l`
if [ $isAlive = 1 ]; then
echo $process" is running."
else
echo $process" is dead, restarting..."
# restart
exporter="${EXPORTERS_DIR}${process}"
if [ -e $exporter ]; then
chmod 755 $exporter
echo "$exporter &"
else
echo "$exporter not found"
fi
fi
done
crontab -e
でこんな感じに設定すれば毎分動いているか確認して止まっていたら再起動といった感じにお手軽に動くかと(テストしてませんので注意)
* * * * * path/to/prometheus.sh
考察
やはりバイナリをポンと置いてやれあれが足りないこれが足りない言われずに動くのは気持ちいいですね。
まさにギリシャ神話のプロメテウスが天界から盗み出し人に与えた火の如く、golang世紀の産物だと思いました(ほんとかよ)。
このPrometheusで監視を始めても山に磔にされて肝臓をハゲタカについばまれるような運用対応が必要になる事もないでしょう。
ドキュメントが少ないと言われがちですがそんなに複雑でないのでオフィシャルだけあればいいのではとも思います。
grafanaとの連携で美しいグラフで表示したいというニーズも多数あるようですが
個人的にはアラートがslack・メールに飛んでくるだけで必要十分なので余計な負荷をかけないようスルーします。
が、ちょっと試したいという場合はdockerでささっ見るのがお手頃でした。
docker run -d -p 3000:3000 grafana/grafana
grafana詳細はこちら http://docs.grafana.org/installation/