Edited at

Pushgateway->Prometheus->Alertmanager->Webhook


目的

GKEにHelmでデプロイしたPushgateway, Prometheus, Alertmanagerの連携動作を確認しよう


やること

Pushgatewayにアラートルールを満たすメトリクスをPOSTすると外部サービスでアラートを受信することを確認する。

図をクリックするとPlantUMLを確認できます(gist)。

シーケンス

アプリケーション
機能

Pushgateway
・PUSHされたメトリクスを公開する

Prometheus
・メトリクスを収集する
・アラート条件を満たした場合アラートをAlertmanagerに送信する

Alertmanager
・アラートを受信しreceiver設定に従い外部サービスに送信する
・receiverにはemailやslack等が用意されている。
・今回はreceiverとしてWebhookを使用し、自前のサーバに送信するようにした。

ExternalService
・SMTPサーバやslack APIエンドポイント等。
・今回はnode.jsで簡易なWebサーバを準備した。


環境


  • クライアント(Ubuntu 17.10)



    • curlでPushgatewayにメトリクスをPOSTする用



  • k8sクラスタ(GKE)


    • Pushgatewary, Prometheus, Alertmanagerをデプロイ済み

    • デプロイツールはhelm

    • デプロイ手順はHelmのすゝめに記載しています。



  • Webサーバー(EC2(Ubuntu 16.04))


    • リクエスト内容をログに残す簡易なHTTPサーバーを稼働済み(node.js(Express))。




Prometheus

prometheus.yamlに以下設定が必要です。



  1. targets に PrometheusがscrapeすべきPushgatewayを設定する


  2. alertmanagers に Prometheusがアラートを送信すべきAlertmanagerを設定する


  3. rule_filesにアラートルールファイルのパスを設定する。

今回はHelmでデプロイしたので1と2はService Discoveryが設定済みです。


Service Discoveryできていることを確認する

Status -> Configration を確認します。

Alertmanager や Pushgateway は Service Discovery設定がされています。

Prometheus3.png

Status -> Runtime & Build Information を確認します。

AlertmanagerがDiscoveryされています。

Prometheus2.png

Status -> Targets を確認します。

PushgatewayがDiscoveryされています。

Prometheus9.png


アラートルールを設定する

公式ドキュメントのサンプルルールを設定してみましょう。

Configmapをeditします。

$ kubectl edit configmap test-prometheus-server -n helm-test

configmap "test-prometheus-server" edited
$ kubectl get configmap test-prometheus-server -n helm-test -o yaml
( 略 : )
rules: |
groups:
- name: example
rules:

# Alert for any instance that is unreachable for >5 minutes.
- alert: InstanceDown
expr: up == 0
for: 5m
labels:
severity: page
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."

# Alert for any instance that has a median request latency >1s.
- alert: APIHighRequestLatency
expr: api_http_request_latencies_second{quantile="0.5"} > 1
for: 10m
annotations:
summary: "High request latency on {{ $labels.instance }}"
description: "{{ $labels.instance }} has a median request latency above 1s (current value: {{ $value }}s)"
( 略 : )

edit後、しばらく待つと設定がリロードされます( 設定をリロードするコンテナがPrometheus Pod内にいます )。

WebUIのAlertsを確認します。確かにルールを設定できています。

Prometheus4.png


Alertmanager

Prometheusから受信したアラートの送信先(receiver)の設定が必要です。

今回は外部サーバに送信するため、webhookの設定を行います。


receiverを設定する。

WebUIのStatusを開いてConfigを確認します。

ここにreceiverを設定してあげれば様々な外部サービスにアラートを飛ばせます。

Alertmanager2.png

今回はwebhook_configsを追加し外部サーバにアラートをPOSTするようにしてみます。

ConfigMapをeditします。

$ kubectl edit configmap test-prometheus-alertmanager -n helm-test

configmap "test-prometheus-alertmanager" edited
$ kubectl get configmap test-prometheus-alertmanager -n helm-test -o yaml
( 略 : )
alertmanager.yml: |
global: {}
receivers:
- name: default-receiver
webhook_configs:
- url: "http://外部サーバのエンドポイント/"
( 略 : )

しばらく待つと設定がリロードされます。


Pushgateway


メトリクスをPOSTする

Pushgateway に公式ドキュメントのサンプルメトリクスをPOSTしてみます。

$ # POSTする

$ cat <<EOF | curl --data-binary @- http://localhost:9091/metrics/job/some_job/instance/some_instance
# TYPE some_metric counter
some_metric{label="val1"} 42
# TYPE another_metric gauge
# HELP another_metric Just an example.
another_metric 2398.283
EOF
$


メトリクスを確認する

WebUI をブラウザで開きます。

POSTしたメトリクスが確かに公開されています。

Pushgateway2.png

PrometheusのWebUIでsome_metricで検索します。

確かにPrometheusがメトリクスを収集しています。

Prometheus5.png


アラートを発火させる

ここからが本題です。以下の連携を確認しましょう。

・アラートが発火するようなメトリクスをPushgatewayにPOSTする

・Pushgatewayがメトリクスを公開する
・PrometheusがPushgatewayのメトリクスを収集する
・アラートルールを満たしたらPrometheusがAlertmanagerにアラートを送信する
・Alertmanagerがアラート受信する
・Alertmanagerがreceiver(webhook)の機能で外部サーバにPOSTする
・外部サーバがアラートを受信する


Pushgateway

アラートルール up == 0 を満たすメトリクスをPOSTしてみましょう。

$ cat <<EOF | curl --data-binary @- http://localhost:9091/metrics/job/some_job/instance/some_instance

# TYPE up counter
up 0
EOF
$

確かにメトリクスが公開されました。

Pushgateway3.png


Prometheus

Pushgatewayのメトリクスを収集した結果、アラートがPENDING状態となっています。

5分待ちます。

Prometheus6.png

5分経過しました、アラートがFIRING状態になり、発火しました!

Prometheus7.png


Alertmanager

Prometheusから送信されたアラートを確かに受信しています。

このアラートをreceiver(Webhook)の機能で外部サーバに送信しているでしょうか?

Alertmanager3.png


外部サーバ

Webサーバのログを見ると確かにアラートがPOSTされていました。

アラート情報は以下のようなjsonになっていました。

{ receiver: 'default-receiver',

status: 'firing',
alerts:
[ { status: 'firing',
labels: [Object],
annotations: [Object],
startsAt: '2018-11-29T15:14:18.501662728Z',
endsAt: '2018-11-29T15:17:18.501662728Z',
generatorURL:
'http://test-prometheus-server-7bd886b769-glcgt:9090/graph?g0.expr=up+%3D%3D+0&g0.tab=1' } ],
groupLabels: {},
commonLabels:
{ alertname: 'InstanceDown',
instance: 'some_instance',
job: 'some_job',
severity: 'page' },
commonAnnotations:
{ description:
'some_instance of job some_job has been down for more than 5 minutes.',
summary: 'Instance some_instance down' },
externalURL: '',
version: '4',
groupKey: '{}:{}' }


アラートを鎮火する

アラートを止めるために、up == 1 となるメトリクスをPushgatewayにPOSTしておきましょう。

cat <<EOF | curl --data-binary @- http://localhost:9091/metrics/job/some_job/instance/some_instance

# TYPE up counter
up 1
EOF

無事にアラートが鎮火しました。

Prometheus8.png


まとめ

GKEにHelmでデプロイしたPushgateway, Prometheus, Alertmanagerの連携動作を確認できました。

ポイント


  • Pushgatewayを使うと手軽にメトリクスを生成できるぞ

  • Pushgateway, Prometheus, AlertmanagerをHelmでデプロイした恩恵により、変更する設定項目はアラートルールだけで済んだ(service discovery最高!)

  • Webhookを活用するとemailやslackだけでなくいろいろなサービスとも連携できそうですね!