Prometheus + Grafana システム監視:6ヶ月の本番運用レビュー

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

以前使っていた構成(そして乗り換えた理由)

Prometheus + Grafanaに落ち着くまで、数週間かけて監視スタックを比較検討した。最終候補に残ったのは3つ:ELKスタック(Elasticsearch + Logstash + Kibana)、Datadog、そしてPrometheus + Grafanaの組み合わせだ。選択を誤れば単に不便というだけでは済まない——ダッシュボードの移行、操作感の再学習、サービスの再計装が必要になる。何週間もの苦労が待っている。

当時どのように比較を整理したかを紹介する。

アプローチ1:マネージドSaaS(Datadog、New Relic)

セットアップのオーバーヘッドがゼロ。エージェントを入れればメトリクスが流れ込み、ダッシュボードが出来上がる。インフラのことを考えたくないチームには向いている。問題はコストだ。Datadogの基本インフラ監視は1ホストあたり月約23ドル——APMやカスタムメトリクスを追加すれば40〜60ドルに跳ね上がる。50台のサーバーなら、カスタムメトリクスを1つも追加する前に月2,000〜3,000ドルかかる計算だ。スタートアップや少人数チームにはこの数字は厳しい。

アプローチ2:ELKスタック

Elasticsearchは検索エンジンだ。時系列データを保存できるからといってメトリクスパイプラインに組み込む人がいるが、最適化されているのはメトリクスの集計ではなくログ検索だ。メモリフットプリントだけでも辛い——メトリクス用のElasticsearchクラスターは16〜32GBのRAMを必要とするのに対し、同等のPrometheus構成なら4GBで済む。Kibanaの可視化は大幅に改善されたが、ダッシュボード構築の操作感はGrafanaと比べるとまだ違和感がある。

アプローチ3:Prometheus + Grafana

今実際に使っているのがこれだ。Prometheusはメトリクスのために設計されている:プルモデルでエンドポイントをスクレイプし、圧縮された時系列フォーマットでデータを保存し、PromQL——システムの動作について考える方法に自然にマッピングされるクエリ言語——を搭載している。GrafanaはPrometheus(および数十の他のデータソース)に接続し、実際に使いやすいダッシュボードを提供してくれる。

導入が早いのはエクスポーターのエコシステムがほぼすべてをカバーしているからだ。PostgreSQL、Redis、Nginx、Kubernetes、RabbitMQ——ほとんどの主要なオープンソースプロジェクトは/metricsエンドポイントを提供しているか、コミュニティエクスポーターが存在する。数日ではなく数時間でスタックの監視が始められる。

6ヶ月使って感じた正直なメリット・デメリット

Prometheus + Grafanaが優れている点

  • プルベースのスクレイピングは運用上合理的だ。サービスがメトリクスを公開し、Prometheusがスケジュールに従って取得する。サービスが落ちれば即座にわかる——スクレイプが失敗してアラートが発火する。プッシュベースのシステムは、クライアントがデータ送信を止めても静かに障害を隠してしまうことがある。
  • PromQLは慣れると強力だ。学習曲線は確かにある。しかしrate()irate()histogram_quantile()、ラベルマッチャーを身につければ、システムに関するほぼあらゆる疑問に数秒で答えられるようになる。
  • エクスポーターのエコシステムがほぼすべてをカバーしている。Node Exporter、cAdvisor、PostgreSQL Exporter、Redis Exporter、Nginx Exporter——運用しているものならほぼエクスポーターが存在する。標準的なインフラコンポーネントにカスタム計装は不要だ。
  • コミュニティダッシュボードが実際の時間を節約してくれる。Grafana.com/dashboardsには数千のコミュニティ公開設定がある。IDをインポートするだけで1分以内に本番対応のダッシュボードが手に入る。
  • リソースフットプリントは管理可能な範囲だ。15秒間隔で50ホストを監視しても、2コアと4GBのRAMで快適に動作する。ストレージも現実的な範囲に収まる——デフォルトの圧縮設定で50ホストの30日分のメトリクスは通常20GB未満だ。

不足している点

  • 長期保存には追加作業が必要だ。PrometheusのローカルTSDBは複数年の保持を想定していない。15〜30日を超えるデータにはリモート書き込み先が必要になる:Thanos、Cortex、またはVictoriaMetricsだ。
  • Alertmanagerの設定は学習コストが高い。ルーティングツリーは柔軟だが直感的ではない。サイレンスルールとレシーバールーティングを期待通りに動かすまでに数時間かかると見込んでおこう。
  • ログとの相関機能が組み込まれていない。Prometheusはメトリクス専用だ。ログを追加するにはLokiを導入することになる——GrafanaとはうまくIntegrateするが、運用・デバッグが必要なコンポーネントがもう一つ増える。
  • PromQLには想定外のエッジケースが存在する。ストーレス処理、レンジセレクター、カウンターリセットの動作は最初は直感的ではない。サービス再起動時にアラートが予期せず発火する——Prometheusのカウンターリセット処理が原因——のは初期段階でよくある落とし穴だ。完全に理解するにはある程度読み込む必要がある。

ほとんどのチームに推奨するセットアップ

標準的なLinuxワークロード、コンテナ、いくつかのデータベースを運用する10〜100台のサーバーを持つチームなら、以下の構成をデプロイするとよい:

  • Prometheus — コアメトリクス収集、30日ローカル保持
  • Node Exporter — 全ホストのシステムレベルメトリクス(CPU、メモリ、ディスク、ネットワーク)
  • cAdvisor — DockerやKubernetesを運用している場合のコンテナメトリクス
  • Alertmanager — Slack/PagerDuty/メールへのアラートルーティング
  • Grafana — ダッシュボードと可視化

長期保持やPrometheus HAが必要なら、VictoriaMetricsをリモート書き込み先として追加しよう。Thanosより運用が簡単で、生のPrometheusと比べてディスク使用量が約5分の1に収まる。

実装ガイド

ステップ1:Prometheusのインストール

監視サーバーにPrometheusをダウンロードしてインストールする:

# 専用ユーザーを作成する
sudo useradd --no-create-home --shell /bin/false prometheus

# Prometheusをダウンロードする(最新バージョンはprometheus.ioで確認)
wget https://github.com/prometheus/prometheus/releases/download/v2.51.0/prometheus-2.51.0.linux-amd64.tar.gz
tar xvf prometheus-2.51.0.linux-amd64.tar.gz
cd prometheus-2.51.0.linux-amd64

# バイナリをインストールする
sudo cp prometheus /usr/local/bin/
sudo cp promtool /usr/local/bin/
sudo chown prometheus:prometheus /usr/local/bin/prometheus
sudo chown prometheus:prometheus /usr/local/bin/promtool

# ディレクトリをセットアップする
sudo mkdir /etc/prometheus /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus /var/lib/prometheus

/etc/prometheus/prometheus.ymlに基本設定を作成する:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['localhost:9093']

rule_files:
  - "/etc/prometheus/rules/*.yml"

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    static_configs:
      - targets:
          - 'server1:9100'
          - 'server2:9100'

/etc/systemd/system/prometheus.serviceにsystemdサービスファイルを作成する:

[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
  --config.file /etc/prometheus/prometheus.yml \
  --storage.tsdb.path /var/lib/prometheus/ \
  --storage.tsdb.retention.time=30d \
  --web.listen-address=0.0.0.0:9090

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable prometheus
sudo systemctl start prometheus

ステップ2:各ホストにNode Exporterをインストール

wget https://github.com/prometheus/node_exporter/releases/download/v1.8.0/node_exporter-1.8.0.linux-amd64.tar.gz
tar xvf node_exporter-1.8.0.linux-amd64.tar.gz
sudo cp node_exporter-1.8.0.linux-amd64/node_exporter /usr/local/bin/
sudo useradd --no-create-home --shell /bin/false node_exporter

/etc/systemd/system/node_exporter.serviceを作成する:

[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable node_exporter
sudo systemctl start node_exporter

ステップ3:Grafanaのインストール

# Ubuntu/Debian
sudo apt-get install -y apt-transport-https software-properties-common wget
sudo mkdir -p /etc/apt/keyrings/
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt-get update
sudo apt-get install grafana

sudo systemctl enable grafana-server
sudo systemctl start grafana-server

Grafanaはポート3000で動作する。デフォルトのログインはadmin / admin——初回ログイン時に必ず変更すること。

ステップ4:PrometheusをGrafanaに接続

  1. ブラウザでGrafanaを開く:http://your-server:3000
  2. Connections → Data Sources → Add data sourceに移動する
  3. Prometheusを選択する
  4. URLにhttp://localhost:9090を設定する
  5. Save & Testをクリックする

ダッシュボードID 1860をインポートしよう——Node Exporter Fullダッシュボードだ。Prometheus設定に含まれる全ホストのCPU、メモリ、ディスク、ネットワークをカバーしており、追加設定は一切不要だ。

ステップ5:まず設定すべきアラートルール

/etc/prometheus/rules/node.ymlを作成する:

groups:
  - name: node_alerts
    rules:
      - alert: HighCPULoad
        expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "{{ $labels.instance }}のCPU負荷が高い"
          description: "CPU使用率は{{ $value | printf \"%.1f\" }}%です"

      - alert: DiskSpaceLow
        expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 15
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "{{ $labels.instance }}のディスク容量が残り少ない"
          description: "ルートファイルシステムの空き容量は{{ $value | printf \"%.1f\" }}%です"

再起動なしでPrometheus設定をリロードする:

curl -X POST http://localhost:9090/-/reload

6ヶ月後の結果

監視の穴による重大インシデントはゼロ。ディスクフルの状況が3回発生したが、すべて障害になる前に検知・解決できた。Node.jsサービスのメモリリークも早期に特定できた——1日あたり約200MBずつ増加していたもので、本番環境に影響が出る前にパッチを当てられた。監視コストはこの規模でDatadogを使った場合と比べて約70%削減できた。

初期セットアップはエンドツーエンドで4〜6時間かかる。Prometheus、全ホストへのNode Exporter、Grafana、そしてアラートルールの初回設定まで含んだ時間だ。ほとんどのチームは最初の1週間以内にその時間を取り戻せる。

数台以上のサーバーを体系的なメトリクスなしに運用するのは、計器なしで飛行するようなものだ。このスタックは月3,000ドルの請求なしにその問題を解決してくれる。

Share: