読書メモ: Prometheus実践ガイド: クラウドネイティブな監視システムの構築

どんな本?

Prometheus の概要から実践的な運用ノウハウまでまとまっていて、それを日本語で読めるのがポイント。 また、雑多になるのでここにはメモしてないが PromQL の解説も詳しいので、クエリの書き方に迷ったときの辞書としても便利そう。

Prometheus のアーキテクチャ

Prometheus のシステムを構成するコンポーネントは主に次の四つ:

  • Prometheus Server: Prometheus 本体。Exporter から受け取ったメトリクスを保存してクエリの実行を担う。
  • Exporter: メトリクスの収集。監視したい対象に合わせて必要なものを導入する。種類は非常に多く、200 以上存在する。
  • AlertManager: アラートの発報
  • Grafana: 収集したメトリクスの可視化

これらのコンポーネントは Go 言語で実装されており、シンプルなバイナリで提供されている。

Why Prometheus?

一つ目の理由は、他の監視システムに比べて構成がシンプルであること。 Web サーバーやデータベースといったミドルウェアが必要ないので、どんな環境でも導入が容易になってる。

二つ目の理由は、クラウドネイティブな監視が可能であること。 ここでいうクラウドネイティブな監視とは、監視対象となるシステムが頻繁に変化しても適切に追従でき、システム全体の正常性が常に把握できること を意味してる。 そのために Prometheus は、監視サーバーがクライアントに対してメトリクスを収集しに行く、 Pull 型のメトリクス収集の仕組みを採用している。 同時に、クラウドシステムではサーバーの IP アドレスもクライアントの数も固定されていないので、Prometheus はサービスディスカバリの仕組みも備えている。 サービスディスカバリは、クラウドサービスの API などを利用して対象の情報を能動的に取得・更新して、構成の変化に動的に追従して監視を継続できるようにする仕組みのこと。

三つ目の理由は、Kubernetes 上での監視のデファクトスタンダードになっているため、エコシステムが充実していること。 結果、エクスポーターが豊富に提供されている。サーバーのメトリクス監視には Node exporter、nginx の監視には nginx-prometheus-exporter、MySQL の監視には mysqld_exporter などが利用できる。 また、Kubernetes とともに CNCF にホスティングされている。Kubernetes 上で Prometheus を構築するための Prometheus Operator というプロジェクトもある。

データ構造とクエリ

Prometheus では、すべてのデータがメトリクスとして表現される。メトリクスは Key-Value 構造になっている。 たとえば、localhost:9090 マシンの CPU 使用率が 50% というメトリクスは、cpu_usage{instance="localhost:9090"} が Key で、50 が Value になるデータで表せる。 このとき、cpu_usage は メトリクス名、instance="localhost:9090" はラベルと呼ばれる。

メトリクスを取得するには、PromQL を使ってクエリを実行する。http_requests_total{instance="prometheus"} というクエリを実行すると、http_requests_total というメトリクスのうち、サーバー名に "prometheus" という文字列が含まれる情報を取得できる。

k8s 上のセットアップ

Prometheus の管理の効率化と自動化が可能になる、Prometheus Operator を使うのが良い。 カスタムリソースによって監視ターゲット設定を簡単に定義できる。

監視ターゲットを追加するには ServiceMonitor や PodMonitor を、ルールを追加するには PrometheusRule といった対応する CRD を定義する。

冗長構成

Prometheus の可用性を高めるためには、Prometheus 本体の冗長化と、AlertManager の冗長化をそれぞれ行う必要がある。

Prometheus 本体には冗長化の仕組みは備わっていないので、実現するには同一の設定を持つ Prometheus を二つ構築する方法が取られる。 こうすることで Prometheus はそれぞれ独立してメトリクスを収集する。

AlertManager では単純に複数起動するとそれぞれの AlertManager からアラートが発報されてしまうので、クラスタリングの仕組みが用意されている。 AlertManager を起動する際に別の AlertManager のアドレスをフラグで渡すことで、クラスターが構成される。 Prometheus からはクラスタ化された二つの AlertManager の両方にアラートを通知すればよく、あとは重複排除されて一つだけアラートが発報されるようになる。

ストレージ

Prometheus が利用するストレージには、ローカルストレージリモートストレージの二種類がある。

  • ローカルストレージは、Prometheus を起動しているサーバー上に作成されるストレージである。デフォルトでは、Prometheus のバイナリと同じディレクトリに data ディレクトリを作成し、そこに TSDB(Time Series Database)を構築する。
  • リモートストレージは、外部のストレージソフトウェアへメトリクスを転送する機能のことを指す。リモートストレージを利用するには、Prometheus のリモートストレージ機能に対応したソフトウェアを用意する必要がある。たとえば InfluxDB は標準機能として Prometheus のリモートストレージ API をサポートしており、比較的安定している OSS の時系列データベースである。

短期間かつ小規模であればローカルストレージでも十分実用に耐える。逆に、長期間データを運用する場合、PromQL のパフォーマンス低下などが問題になるのでそのような現象に陥った場合はリモートストレージの利用を検討すべき。