この記事は、Kubernetes Advent Calendar 2020 その1の12日目の記事です。
Prometheusは、Kubernetesと親和性の高いシステム監視ソフトウェアの一つです。しかし、新規でシステム監視を開始する場合、「アラート設計」は悩みがちな要素の1つでしょう。今回は、kubernetes-mixinというリポジトリを利用し、Kubernetes監視でのアラートの標準化を行いましょう。
Introduction
コンテキストの違い
Kubernetesに限らず、アラート設計の悩みは絶えません。既存のシステムのアラートも、決して完璧な状態から作成されたわけではなく、日々の運用の経験から修正を重ねたアラート達でしょう。
しかし、これらのアラートの多くはプロジェクトやチーム独自のものであり、人やチーム、プロジェクト等によってコンテキストが大きく異なります。
たとえば、「KubernetesのNodeが停止した」という障害に対して、アラートレベルを設定する場合、あなたは何を設定するでしょうか。
- 「Nodeが停止するとPodも停止するので
critical
だ!」 - 「Nodeが停止してもサービスには影響ないので
error
にしよう」 - 「サービスには影響ないが問題ではあるので
problem
にしよう」
逆に、 error
というアラートレベルに対して、どの程度のサービス影響があるように感じるでしょうか。このように、それぞれの人やプロジェクトの背景や経験、前提によって解釈は大きく異なります。
kubernetes-mixinを利用した標準化
そこで、コミュニティによってメンテナンスされているkubernetes-monitoring/kubernetes-mixinを活用してみましょう。このリポジトリでは、Prometheusを利用したKubernetes監視のアラート、ルール、ダッシュボードを定義し、jsonnetによるビルドを実現しています。
具体的に生成可能なアラートは次のRunBookを確認してみましょう。 KubeAPIDown
や KubeletDown
のようなそれらしいアラートが定義されています。
また、それぞれのアラートには severity
が指定されているので、 critical
のみアラートを投げるようにし、それ以外はイベント管理システムに投げるだけ、というような運用もできそうです。
ファイルを生成する
それでは、早速kubernetes-mixinを利用してアラートファイルを生成してみましょう。手順は公式サイトのREADMEにもあるので適宜ご参照ください。
まずはjbコマンドをインストールします。jb(jsonnet-bundler)は、必要な依存関係をダウンロードするために利用します。
$ go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb
$ brew install jsonnet
その後、リポジトリをクローンして、依存関係をダウンロードします。なお、私の環境では、そのままではjbコマンドが利用できなかったので、次のように直接PATHを指定しました。
$ git clone https://github.com/kubernetes-monitoring/kubernetes-mixin
$ cd kubernetes-mixin
$ ~/go/bin/jb install
GET https://github.com/grafana/grafonnet-lib/archive/356bd73e4792ffe107725776ca8946895969c191.tar.gz 200
GET https://github.com/grafana/jsonnet-libs/archive/216bc806bb512f218e3cf5ed3d4f5699b07f04d6.tar.gz 200
依存関係のダウンロードが完了したらファイルを生成します。 make
コマンドのあとに、それぞれ prometheus_alerts.yaml
, prometheus_rules.yaml
, dashboards_out
と指定すると、それぞれのファイルを生成してくれるようです。今回はアラートだけを生成したいので、 prometheus_alerts.yml
を指定します。
$ make prometheus_alerts.yaml
jsonnet -J vendor -S lib/alerts.jsonnet > prometheus_alerts.yaml
カレントディレクトリに prometheus_alerts.yaml
が作成されました。一部覗いてみましょう。このアラートはCrashLoopBackOffなPodを検知するアラートです。特に注目すべきは annotations
です。それぞれ、 description
と runbook_url
が存在します。このAnnotationsをAlertManagerで指定することで、いい感じのメッセージをアラートに表示できそうですね。
---
groups:
-
name: kubernetes-apps
rules:
-
alert: KubePodCrashLooping
annotations:
description: "Pod {{ $labels.namespace }}/{{ $labels.pod }} ({{ $labels.container }}) is restarting {{ printf \"%.2f\" $value }} times / 5 minutes."
runbook_url: "https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/runbook.md#alert-name-kubepodcrashlooping"
summary: "Pod is crash looping."
expr: "rate(kube_pod_container_status_restarts_total{job=\"kube-state-metrics\"}[5m]) * 60 * 5 > 0\n"
for: 15m
labels:
severity: warning
あとは、Prometheusの他にkube-state-metricsなどをデプロイし、スクレイプすればアラートが正常に動くでしょう。なお、アラートを見る限り、kube-state-metricsの他に、 kube-apiserver
辺りもスクレイプする必要がありそうです。
終わりに
冒頭にも書いたとおり、アラートってかなり環境や人によって異なってしまうので、こういった形でコミュニティでメンテされているアラートがあると、その辺りを合わせられて良いのかなと思います。ただし、あくまでもこれは参考値で、実際に運用する場合は、チームやプロジェクトに併せて適切な値、しきい値に変更すると良いかもしれません。
また、本当はもっとちゃんとKubernetes Monitoringのあれこれを書こうと思ったんですが、環境づくりで1,2日くらい使ってしまい、結局アラートネタになりました。また今度、Kubernetes Monitoring全般の記事を書こうかと思い明日🙏