IBM Cloud Private (ICP) 付属のAlertmanagerでメール通知をする

# 目的

[前回](https://qiita.com/teruq/items/c29438c7e7f4c3335f32)の記事で、ICP付属のPrometheusとGrafanaを使って、アプリケーションのメトリクスの可視化を行いました。今回はそこから異常を検知した際に、メール通知をしてみます。

メール通知はPrometheusの仲間のコンポーネントであるAlertmanagerがやはりデフォルトで起動しているので、それを使うことができます。ちなみにそういった通知機能はGrafanaにもあります。実運用ではどちらを使うのがいいのか、あるいは使いわけをすべきなのか、正直まだよくわかっていません。今回はAlertmanagerを使います。


検証環境
- IBM Cloud Private 2.1.0.2 (Kubernetes 1.9.1)

# 手順

## Alertmanagerにメール送信設定を追加

Alertmanagerはkube-systemネームスペースの`monitoring-prometheus-alertmanager`というConfigMapを使用します。デフォルトではほとんど何も書かれていないので、ここに様々な設定を追加します。今回は最低限のメール送信設定を追加します（下記コメントのある5行）。

```
$ kubectl edit configmap monitoring-prometheus-alertmanager -n kube-system

apiVersion: v1
data:
  alertmanager.yml: |-
    global:
      smtp_smarthost: 192.168.11.12:25      # SMTPサーバ
      smtp_from: alertmanager@hoge.jp       # FROMアドレス
      smtp_require_tls: false               # TLS使用有無
    receivers:
      - name: default-receiver
        email_configs:                      # メール送信先設定
        - to: teru@hoge.jp                  # TOアドレス
    route:
      group_wait: 10s
      group_interval: 5m
      receiver: default-receiver
      repeat_interval: 3h
(略)
```

保存したら自動的にAlertmanagerのPodに反映されます。ただし即時ではなく、数十秒～数分程度かかります。

## Prometheusにルール追加

検知のルールはPrometheus側の`alert-rules`というConfigMapを使います。こちらもデフォルトでは全然内容がないので、新たなルールを追加します。今回は必ず通知するように閾値を小さめにしています。

```
$ kubectl edit configmap alert-rules -n kube-system

apiVersion: v1
data:
  sample.rules: "" # デフォルトではこれしか書かれていない
  # ここから追加
  jvm.rules: |-
    groups:
      - name: jvm                       # グループ名
        rules:
          - alert: jvm_heap_high        # ルール名
            expr: jvm_memory_used_bytes{area="heap",job="kubernetes-pods"} > 134217728
                                        # 128MBを超えたら通知
            for: 1m                     # 1分継続したら通知
            labels:
              severity: warning         # 緊急度など
```

こちらも保存して少し待てばPrometheusのPodに反映されます。

## Promethuesコンソールからの確認

Prometheusのコンソールで状態を確認します。

```
$ kubectl get pods -n kube-system | grep prometheus
monitoring-prometheus-7994986858-4nwp8                    3/3       Running   0          6d
monitoring-prometheus-alertmanager-7dc884c44d-hnjj2       3/3       Running   0          3d
monitoring-prometheus-kubestatemetrics-798dd85965-jrfr2   1/1       Running   0          6d
monitoring-prometheus-nodeexporter-amd64-25nhf            1/1       Running   0          6d
monitoring-prometheus-nodeexporter-amd64-4dbgm            1/1       Running   0          6d
monitoring-prometheus-nodeexporter-amd64-tl6mb            1/1       Running   0          6d
monitoring-prometheus-nodeexporter-amd64-wwcht            1/1       Running   0          6d

$ kubectl port-forward monitoring-prometheus-7994986858-4nwp8 9090:9090 -n kube-system
```

メニューのAlertsを表示すると、さっそく検知されています。StatusがFiringになっているとAlertmanagerに通知が飛んだということのようです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/241424/af05006d-e493-786b-75d6-4ada24dcf21c.png)

## メールの確認

次のようなメールを受信しました。通知も動きましたね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/241424/70b83377-422e-7d7a-76dd-6069d8935506.png)

各種リンクは残念ながらデッドリンクになります。URLがPodの名称とポートそのままになってしまうためです。これを正しく機能させたい場合はIngressやNodePortを使って、PrometheusやAlertmanagerをクラスタ外部からアクセス可能にし、メールテンプレートを書き換える必要があるでしょう。今回は力尽きたのでここまで。

# 感想

今回は動作確認のために最低限の設定しかしませんでしたが、商用環境ではより細かい設定が必要になります。特に監視の世界は奥が深いので、マニュアルを読んで研究が必要ですね。

> https://prometheus.io/docs/introduction/overview/