Prometheus の Alertmanager(と Postfix)でメール通知

前回 Prometheus server と node_exporter を同じノード上にインストールしてグラフが取れてることを確認したりしました。 なので今度はメール通知をやってみようと思う。 メール通知するためには Alertmanager というアラートを出す専用のやつをインストールして Prometheus server と連携する必要がある。 なので構成としては

  • 監視サーバ(ホスト名:promhost)
    • Prometheus server, Alertmanager, node_exporter(エージェント)
  • 監視対象のサーバ(ホスト名:targethost)
    • node_exporter(エージェント)

みたいな形でインストールする。 というわけで前回インストールしたノードを監視サーバにしたてて、新たに別のノードにエージェントをインストールしました。 node_exporter のインストールは前回書いたので、Alertmanager のインストール方法をメモします。

Alertmanager のインストール

Prometheus server, node_exporter と同じく Go 製なのでインストールが簡単。 前回にならって /opt/alertmanager/ にインストールする。

現在の最新バージョンは v0.8.0その他のリリース)。

$ curl -LO https://github.com/prometheus/alertmanager/releases/download/v0.8.0/alertmanager-0.8.0.linux-amd64.tar.gz

$ tar xzf alertmanager-0.8.0.linux-amd64.tar.gz
$ sudo mv alertmanager-0.8.0.linux-amd64 /opt/alertmanager
$ sudo chmod 755 /opt/alertmanager
$ sudo chown -R root:root /opt/alertmanager

終わり。

Alertmanager の設定

/etc/alertmanager/alertmanager.yml(alertmanager の設定ファイル)を作成。 /global/smtp_require_tls に false を指定していることに注目。 TLS サポートを有効にしていないローカルの Postfix などで配送する場合はこの値を指定してやらないとメールが送れなかった。

global:
  # The smarthost and SMTP sender used for mail notifications.
  smtp_smarthost: 'localhost:25'
  smtp_require_tls: false
  smtp_from: 'Alertmanager <alertmanager@localhost.localdomain>'

# The root route on which each incoming alert enters.
route:
  # When a new group of alerts is created by an incoming alert, wait at
  # least 'group_wait' to send the initial notification.
  # This way ensures that you get multiple alerts for the same group that start
  # firing shortly after another are batched together on the first
  # notification.
  group_wait: 30s

  # When the first notification was sent, wait 'group_interval' to send a batch
  # of new alerts that started firing for that group.
  group_interval: 5m

  # If an alert has successfully been sent, wait 'repeat_interval' to
  # resend them.
  repeat_interval: 3h

  # A default receiver
  receiver: default

receivers:
- name: 'default'
  email_configs:
  - to: 'alertmanager@localhost.localdomain'

/etc/systemd/system/alertmanager.service(alertmanager 用 systemd 設定ファイル)を作成。

[Unit]
Description=Alertmanager for Prometheus
After=network.target

[Service]
Type=simple
EnvironmentFile=-/etc/default/alertmanager
ExecStart=/opt/alertmanager/alertmanager $OPTIONS
PrivateTmp=true
WorkingDirectory=/opt/alertmanager

[Install]
WantedBy=multi-user.target

/etc/default/alertmanager(systemd で参照する環境変数ファイル)を作成。 ここで -storage.path を指定しないとカレントディレクトリの data ディレクトリにデータ用ディレクトリを作ろうとする。 systemd で動いてる場合は WorkingDirectory の指定がない場合は / で動くので /data ってディレクトリが作られてしまう。 上の systemd 設定ファイルで WorkingDirectory 指定してあるのは -storage.path の他にもカレントディレクトリに何か作ってしまわないか心配になったので念のため。

OPTIONS="-config.file /etc/alertmanager/alertmanager.yml -storage.path /var/lib/alertmanager"

Prometheus に Alerting rules の定義

アラートをメール通知するためにはまだ足りない。 アラートの条件はどこに書くかというと、Prometheus server の設定ファイル(前回の通りだと /etc/prometheus/prometheus.yml)に書く。

rule_files:
  - /etc/prometheus/alert.rules

こんな行を追加する。 あと監視対象のノード追加。

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets:
        - 'localhost:9090'
        - 'promhost:9100'     # 監視サーバ (localhost:9100 でもいいけど)
        - 'targethost:9100'   # 監視対象サーバ

前回との差分は以下の通り。

--- /etc/prometheus/prometheus.yml.old  2017-07-29 22:53:32.319944850 +0900
+++ /etc/prometheus/prometheus.yml      2017-07-29 22:44:24.542404336 +0900
@@ -11,8 +11,7 @@

 # Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
 rule_files:
-  # - "first.rules"
-  # - "second.rules"
+  - /etc/prometheus/alert.rules

 # A scrape configuration containing exactly one endpoint to scrape:
 # Here it's Prometheus itself.
@@ -24,4 +23,7 @@
     # scheme defaults to 'http'.

     static_configs:
-      - targets: ['localhost:9090']
+      - targets:
+        - 'localhost:9090'
+        - 'promhost:9100'
+        - 'targethost:9100'

念のため全体も。

# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
      monitor: 'codelab-monitor'

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  - /etc/prometheus/alert.rules

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
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'
        - 'promhost:9100'
        - 'targethost:9100'

prometheus.yml を更新した後は、/etc/prometheus/alert.rules を作成。

# Alert for any instance that is unreachable for >5 minutes.
ALERT InstanceDown
  IF 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 have a median request latency >1s.
ALERT APIHighRequestLatency
  IF api_http_request_latencies_second{quantile="0.5"} > 1
  FOR 1m
  ANNOTATIONS {
    summary = "High request latency on {{ $labels.instance }}",
    description = "{{ $labels.instance }} has a median request latency above 1s (current value: {{ $value }}s)",
  }

上記は公式ドキュメントまんま。 監視対象の node_exporter が落ちたりノードが停止したりするとメールが飛ぶ設定(だがまだ足りない)。

Prometheus server と Alertmanager の連携

Prometheus server に Alertmanager を認識させるにはコマンドライン引数に -alertmanager.url を追加する。 前回 /etc/default/prometheus を作ったのでそこに書く。

OPTIONS="-config.file=/etc/prometheus/prometheus.yml -storage.local.path=/var/lib/prometheus -web.console.libraries=/etc/prometheus/console_libraries -web.console.templates=/etc/prometheus/consoles -alertmanager.url=http://localhost:9093"

上記のように末尾に追加して再起動。

$ systemctl restart prometheus

これでメールが飛ぶようになったはず。

エラーメッセージへの対処

いくつかエラーメッセージに出くわしたのでその対処法を書く。

Error on notify: Cancelling notify retry due to unrecoverable error: parsing from addresses: mail: missing phrase

systemctl status -l alertmanager に出てたエラーメッセージ。

/global/smtp_from, /receivers/email_configs/to などに指定するメールアドレスが不正な場合に出ます。 smtp_from: 'Alertmanager <alertmanager@localhost.localdomain>' みたいに書くか smtp_from: alertmanager@localhost.localdomain みたいに書く必要があります(localhost だからって @ 以降も忘れずに)。