Prometheus

Prometheus 完全ガイド: 機能・アーキテクチャ・設定の全容


目次

  1. はじめに
  2. Prometheus とは何か
  3. コアコンセプトとデータモデル
  4. アーキテクチャ概要
  5. メトリクス収集 (Scraping)
  6. PromQL (Prometheus Query Language)
  7. ストレージエンジン (TSDB)
  8. アラートルールと Alertmanager
  9. サービスディスカバリ
  10. Exporter エコシステム
  11. Pushgateway
  12. Recording Rules
  13. Federation と Remote Storage
  14. セキュリティと認証
  15. 高可用性 (HA) 構成
  16. Kubernetes 環境での Prometheus
  17. Grafana との連携
  18. パフォーマンスチューニング
  19. 運用のベストプラクティス
  20. まとめ

1. はじめに

現代のインフラストラクチャとアプリケーションは、マイクロサービスアーキテクチャ、コンテナ、クラウドネイティブ環境の採用により、急速に複雑化している。この複雑なシステムを効果的に監視し、問題を迅速に検出・診断するためには、堅牢なモニタリング基盤が不可欠である。

Prometheus は、この課題に対する業界標準のソリューションとして位置づけられている。2012年に SoundCloud で開発が始まり、2016年に Cloud Native Computing Foundation (CNCF) の2番目のプロジェクト(Kubernetes に次ぐ)として採択された。2018年には CNCF の Graduated プロジェクトとなり、その成熟度と広範な採用を示している。

本稿では、Prometheus の機能、アーキテクチャ、設定方法を包括的に解説する。単なる機能紹介にとどまらず、実際の設定例やベストプラクティスを交えながら、Prometheus の全容を理解できることを目指す。

1.1 本稿の対象読者

  • SRE(Site Reliability Engineer)/ インフラエンジニア
  • DevOps エンジニア
  • モニタリング基盤の設計・運用担当者
  • Prometheus の導入を検討している技術者

1.2 前提知識

  • Linux / Unix の基本的な知識
  • HTTP プロトコルの基礎
  • YAML 形式の設定ファイルに関する理解
  • コンテナ技術(Docker / Kubernetes)の基礎(一部セクション)

2. Prometheus とは何か

2.1 概要

Prometheus は、オープンソースのシステム監視およびアラーティングツールキットである。以下の特徴を持つ。

特徴説明
多次元データモデルメトリクス名とキー/バリューのラベルペアで識別される時系列データ
PromQL多次元データモデルを活用した柔軟で強力なクエリ言語
分散ストレージへの非依存各サーバノードが自律的に動作
Pull モデルHTTP 経由でメトリクスを収集(スクレイピング)
Push のサポート中間ゲートウェイ(Pushgateway)経由でのメトリクス送信
サービスディスカバリ静的設定またはサービスディスカバリによるターゲット検出
豊富な可視化グラフ表示・ダッシュボード対応(Grafana 連携)

2.2 Prometheus が解決する課題

従来の監視ツール(Nagios、Zabbix 等)は、主にホスト単位の死活監視やしきい値ベースのアラートに特化していた。一方、Prometheus は以下の現代的な課題に対応する。

  1. 動的な環境への適応: コンテナやクラウド環境では、監視対象が頻繁に増減する。Prometheus のサービスディスカバリ機能により、これに自動的に追従できる。
  2. 高カーディナリティのメトリクス: ラベルベースのデータモデルにより、HTTP ステータスコード別、エンドポイント別、リージョン別など、多次元的な分析が可能。
  3. アプリケーションレベルの監視: アプリケーション固有のビジネスメトリクスやパフォーマンスメトリクスの収集に適している。
  4. 信頼性の高い監視: 外部の分散ストレージに依存しないため、監視対象のインフラに障害が発生しても監視システム自体は稼働し続ける。

2.3 タイムライン

イベント
2012SoundCloud で開発開始
2015公式に公開リリース
2016CNCF に参加(2番目のプロジェクト)
2017Prometheus 2.0 リリース(新ストレージエンジン)
2018CNCF Graduated プロジェクトに昇格
2019OpenMetrics 標準の策定
2021Prometheus Agent Mode の導入
2023Native Histograms のサポート
2024UTF-8 メトリクス名のサポート、OTLP ネイティブ取り込み

2.4 ライセンスとコミュニティ

  • ライセンス: Apache License 2.0
  • 開発言語: Go
  • リポジトリ: github.com/prometheus/prometheus
  • コミュニティ: 活発な GitHub Issues、メーリングリスト、年次カンファレンス(PromCon)

3. コアコンセプトとデータモデル

3.1 時系列データ (Time Series)

Prometheus の根幹は 時系列データ である。時系列とは、タイムスタンプと値のペアの連続的なストリームであり、一意の メトリクス名ラベルセット によって識別される。

<メトリクス名>{<ラベル名>=<ラベル値>, ...}

例:

http_requests_total{method="GET", handler="/api/v1/query", status="200"}

同じメトリクス名でもラベルの組み合わせが異なれば、それぞれが独立した時系列となる。

3.2 メトリクスタイプ

Prometheus は4種類のメトリクスタイプを定義している。

3.2.1 Counter(カウンター)

単調増加する累積値。リセット(再起動時のゼロ復帰)以外では減少しない。

用途: リクエスト総数、エラー発生回数、送受信バイト数

# HELP http_requests_total The total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="post",code="200"} 1027
http_requests_total{method="post",code="400"} 3

PromQL での利用例:

rate(http_requests_total[5m])

3.2.2 Gauge(ゲージ)

任意に増減する値。ある時点のスナップショットを表す。

用途: 現在の温度、メモリ使用量、同時接続数、キューの長さ

# TYPE node_memory_MemAvailable_bytes gauge
node_memory_MemAvailable_bytes 7.38197504e+09

3.2.3 Histogram(ヒストグラム)

観測値をバケットに分類して集計する。以下の3つの時系列を自動生成する:

  • <basename>_bucket{le="<上限値>"}: 各バケットの累積カウント
  • <basename>_sum: 観測値の合計
  • <basename>_count: 観測の総数
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.005"} 24054
http_request_duration_seconds_bucket{le="0.01"} 33444
http_request_duration_seconds_bucket{le="0.025"} 100392
http_request_duration_seconds_bucket{le="0.05"} 129389
http_request_duration_seconds_bucket{le="0.1"} 133988
http_request_duration_seconds_bucket{le="0.25"} 144320
http_request_duration_seconds_bucket{le="0.5"} 144320
http_request_duration_seconds_bucket{le="1"} 144320
http_request_duration_seconds_bucket{le="+Inf"} 144320
http_request_duration_seconds_sum 53.048556822000006
http_request_duration_seconds_count 144320

95パーセンタイルの算出:

histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

3.2.4 Summary(サマリー)

クライアント側で計算されたパーセンタイルを提供する。

# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0.5"} 0.000107601
go_gc_duration_seconds{quantile="0.75"} 0.000165601
go_gc_duration_seconds{quantile="1"} 0.005765601
go_gc_duration_seconds_sum 0.123456789
go_gc_duration_seconds_count 1234

3.2.5 Histogram vs Summary の比較

特性HistogramSummary
パーセンタイル計算サーバ側 (PromQL)クライアント側
集約可能性複数インスタンスを集約可能集約不可
バケット定義事前に設定が必要不要
精度バケット境界に依存より高精度
コスト低い(カウントのみ)高い(ストリーミング計算)

一般的には Histogram の使用が推奨 される。

3.3 ラベル (Labels)

ラベルは Prometheus の多次元データモデルの核心である。

注意点:

  • ラベルの組み合わせごとに独立した時系列が生成される
  • 高カーディナリティなラベル(ユーザーID、セッションIDなど)は避けるべき
  • __ で始まるラベルは内部使用のために予約されている
# 良い例: 有限かつ予測可能な値
http_requests_total{method="GET", status="200", endpoint="/api/users"}

# 悪い例: 高カーディナリティ(時系列が爆発する)
http_requests_total{user_id="12345", session_id="abc-def-ghi"}

3.4 Exposition Format

Prometheus のメトリクスは、テキストベースの exposition format で公開される。

# HELP <メトリクス名> <説明文>
# TYPE <メトリクス名> <タイプ>
<メトリクス名>[{<ラベル>}] <値> [<タイムスタンプ>]

OpenMetrics 形式(application/openmetrics-text)もサポートされている。


4. アーキテクチャ概要

4.1 全体アーキテクチャ

                          ┌──────────────────────────────┐
                          │      Alertmanager            │
                          │  (通知のルーティング・抑制)    │
                          └──────────┬───────────────────┘
                                     │ アラート通知
                                     │ (Email, Slack, PagerDuty...)
                                     ▼
                          ┌──────────────────────────────┐
┌─────────────────┐       │                              │       ┌──────────────────┐
│  Service         │◀─────│     Prometheus Server         │──────▶│  Grafana          │
│  Discovery       │      │                              │       │  (可視化)          │
│                 │       │  ┌─────────┐  ┌───────────┐ │       └──────────────────┘
│  - Kubernetes   │       │  │Retrieval│  │  TSDB     │ │
│  - Consul       │       │  │(Scraper)│  │(Storage)  │ │       ┌──────────────────┐
│  - DNS          │       │  └────┬────┘  └───────────┘ │       │  API Clients      │
│  - File         │       │       │                      │──────▶│  (PromQL)         │
│  - EC2/GCE      │       │  ┌────▼────┐  ┌───────────┐ │       └──────────────────┘
└─────────────────┘       │  │ Alert   │  │ Recording │ │
                          │  │ Rules   │  │ Rules     │ │
                          │  └─────────┘  └───────────┘ │
                          └──────────┬───────────────────┘
                                     │ Scrape (Pull)
                    ┌────────────────┼────────────────┐
                    ▼                ▼                ▼
             ┌───────────┐   ┌───────────┐   ┌───────────────┐
             │ App with   │   │ Exporter  │   │ Pushgateway   │
             │ /metrics   │   │(node, etc)│   │ (短命ジョブ用)  │
             └───────────┘   └───────────┘   └───────────────┘

4.2 各コンポーネントの役割

  • Prometheus Server: メトリクス収集 (Scraping)、ストレージ (TSDB)、ルール評価、API 提供
  • Alertmanager: アラートのグルーピング、抑制 (Inhibition)、サイレンス、ルーティング
  • Pushgateway: 短命のバッチジョブからのメトリクス収集用中間コンポーネント
  • Exporter: Prometheus 形式非対応システムからのメトリクス収集アダプター

4.3 Pull vs Push モデル

観点Pull モデル (Prometheus)Push モデル
監視対象の管理集中管理が容易各ターゲットが送信先を知る必要がある
障害検知ターゲットの死活を直接検知可能メトリクスが来ないことの判別が困難
開発時のテストブラウザで直接メトリクスを確認可能別途受信側が必要
設定変更Prometheus 側で一括変更全ターゲットで変更が必要

4.4 データフロー

  1. サービスディスカバリ がターゲットリストを生成
  2. Retrieval が各ターゲットの /metrics を HTTP GET で取得
  3. メトリクスが TSDB に書き込まれる
  4. Recording Rules が評価され、結果が新しい時系列として保存される
  5. Alert Rules が評価され、条件合致時に Alertmanager に通知される
  6. PromQL API 経由で Grafana 等がデータをクエリする

5. メトリクス収集 (Scraping)

5.1 基本的な Scrape 設定

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  scrape_timeout: 10s
  external_labels:
    cluster: "production"
    region: "us-east-1"

rule_files:
  - "rules/recording_rules.yml"
  - "rules/alerting_rules.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets: ["alertmanager:9093"]

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

5.2 Scrape 設定の詳細

scrape_configs:
  - job_name: "my-application"
    scrape_interval: 30s
    scrape_timeout: 10s
    metrics_path: "/prometheus/metrics"
    scheme: "https"
    tls_config:
      ca_file: /etc/prometheus/ca.crt
      cert_file: /etc/prometheus/client.crt
      key_file: /etc/prometheus/client.key
    basic_auth:
      username: "prometheus"
      password: "secret"
    static_configs:
      - targets: ["app-server-1:8080", "app-server-2:8080"]
        labels:
          environment: "production"
          team: "backend"

5.3 Relabeling

relabel_configs(スクレイプ前)

scrape_configs:
  - job_name: "kubernetes-pods"
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: "true"
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: kubernetes_pod_name

metric_relabel_configs(スクレイプ後)

    metric_relabel_configs:
      - source_labels: [__name__]
        regex: "go_gc_.*"
        action: drop
      - regex: "instance_id"
        action: labeldrop

Relabeling アクション一覧

アクション説明
replace正規表現でマッチした値でターゲットラベルを置換(デフォルト)
keep正規表現にマッチするターゲットのみ保持
drop正規表現にマッチするターゲットを除外
hashmodソースラベルのハッシュ値の modulus をターゲットラベルに設定
labelmap正規表現にマッチするラベル名を置換してコピー
labeldrop正規表現にマッチするラベルを削除
labelkeep正規表現にマッチするラベルのみ保持

5.4 スクレイプ時に自動付与されるメトリクス

メトリクス説明
upターゲットが正常にスクレイプできたか(1=成功, 0=失敗)
scrape_duration_secondsスクレイプにかかった時間
scrape_samples_scrapedスクレイプされたサンプル数
scrape_series_added新しく追加された時系列の数

6. PromQL (Prometheus Query Language)

6.1 データ型

データ型説明
Instant vector同一タイムスタンプの時系列サンプルのセット
Range vector一定期間の時系列サンプルのセット
Scalar単純な浮動小数点数値
String文字列値(現在ほとんど使用されない)

6.2 セレクターとマッチャー

http_requests_total{method="GET"}           # 完全一致
http_requests_total{method!="OPTIONS"}       # 不一致
http_requests_total{handler=~"/api/v[12]/.*"} # 正規表現マッチ
http_requests_total{handler!~"/health.*"}    # 正規表現不一致

http_requests_total{method="GET"}[5m]        # Range Vector(過去5分)
http_requests_total offset 1h                # 1時間前の値
http_requests_total @ 1609459200             # 特定タイムスタンプの値

6.3 演算子

# 算術: +, -, *, /, %, ^
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100

# 比較: ==, !=, >, <, >=, <=
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80

# 論理/集合: and, or, unless
http_requests_total{status=~"5.."} and on(instance) up == 1

# ベクターマッチング
method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m

6.4 集約演算子

演算子説明
sum合計
min / max最小値 / 最大値
avg平均値
stddev / stdvar標準偏差 / 分散
count要素数
topk / bottomk上位/下位k個
quantileパーセンタイル
sum by (instance) (rate(http_requests_total[5m]))
topk(5, container_memory_usage_bytes)
histogram_quantile(0.95, sum by (job, le) (rate(http_request_duration_seconds_bucket[5m])))

6.5 重要な関数

# rate(): 一定期間の平均レート
rate(http_requests_total[5m])

# irate(): 直近2点間の瞬間レート
irate(http_requests_total[5m])

# increase(): 一定期間の増加量
increase(http_requests_total[1h])

# histogram_quantile(): パーセンタイル算出
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

# predict_linear(): 線形予測
predict_linear(node_filesystem_avail_bytes[6h], 4 * 3600) < 0

# absent(): メトリクス不在検出
absent(up{job="my-service"})

# label_replace(): ラベル置換
label_replace(up, "host", "$1", "instance", "(.*):.*")

# サブクエリ
max_over_time(rate(http_requests_total[5m])[30m:1m])

6.6 実践的な PromQL クエリ例

# CPU使用率(%)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# メモリ使用率(%)
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100

# ディスク使用率(%)
(1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100

# エラーレート(%)
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100

# 秒間リクエスト数(RPS)
sum(rate(http_requests_total[5m]))

# Apdex スコア
(sum(rate(http_request_duration_seconds_bucket{le="0.3"}[5m]))
 + sum(rate(http_request_duration_seconds_bucket{le="1.2"}[5m]))
) / 2 / sum(rate(http_request_duration_seconds_count[5m]))

# 30日間のエラーバジェット残量(SLO 99.9%)
1 - (sum(increase(http_requests_total{status=~"5.."}[30d]))
     / sum(increase(http_requests_total[30d]))) / (1 - 0.999)

7. ストレージエンジン (TSDB)

7.1 ストレージアーキテクチャ

./data/
├── 01BKGV7JC0RY8A6MACW02A2PJD/    # Block(不変)
│   ├── chunks/000001                # チャンクデータ
│   ├── index                        # インデックス
│   ├── meta.json                    # ブロックメタデータ
│   └── tombstones                   # 削除マーク
├── chunks_head/                     # Head Block(メモリマップ)
├── lock
└── wal/                             # Write-Ahead Log
    ├── 00000001
    └── checkpoint.00000001/

7.2 Head Block と WAL

Head Block は直近2時間分のデータを保持するインメモリ構造。書き込みは WAL に記録され、クラッシュ時のデータ復旧に使用される。

Write Flow:
  Scrape → WAL (append-only) → Head Block (in-memory)
                                    │ (2時間後)
                              Compaction → Persistent Block (disk)

7.3 ストレージの設定

--storage.tsdb.path=/var/lib/prometheus        # データディレクトリ
--storage.tsdb.retention.time=15d              # 時間ベースのリテンション
--storage.tsdb.retention.size=50GB             # サイズベースのリテンション
--storage.tsdb.wal-compression                 # WAL 圧縮の有効化

7.4 ディスク使用量の見積もり

ディスク使用量 ≈ 時系列数 x (1 / スクレイプ間隔) x リテンション期間(秒) x 1.5バイト/サンプル

例: 10万時系列, 15秒間隔, 15日リテンション → 約13 GB

7.5 ストレージ関連のモニタリング

prometheus_tsdb_head_series                            # アクティブ時系列数
rate(prometheus_tsdb_head_samples_appended_total[5m])  # 取り込みレート
prometheus_tsdb_storage_blocks_bytes                   # ストレージサイズ
prometheus_tsdb_wal_corruptions_total                  # WAL 破損

8. アラートルールと Alertmanager

8.1 アラートルールの定義

groups:
  - name: instance_health
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Instance {{ $labels.instance }} is down"
          runbook_url: "https://wiki.example.com/runbook/instance-down"

      - alert: HighCPUUsage
        expr: |
          100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 10m
        labels:
          severity: warning

  - name: application_health
    rules:
      - alert: HighErrorRate
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m])) by (job)
          / sum(rate(http_requests_total[5m])) by (job) > 0.05
        for: 5m
        labels:
          severity: critical

      - alert: DiskWillFillIn24Hours
        expr: predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[6h], 24 * 3600) < 0
        for: 30m
        labels:
          severity: warning

8.2 アラートの状態遷移

inactive → pending → firing → resolved
  • inactive: アラート条件が false
  • pending: 条件 true だが for 期間未到達
  • firing: 条件が for 期間継続
  • resolved: 発火していたアラートが解消

8.3 Alertmanager の設定

global:
  resolve_timeout: 5m
  slack_api_url: "https://hooks.slack.com/services/xxx/yyy/zzz"

route:
  receiver: "slack-default"
  group_by: ["alertname", "cluster", "service"]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - match:
        severity: critical
      receiver: "pagerduty-critical"
      repeat_interval: 1h
    - match:
        severity: warning
      receiver: "slack-warning"

receivers:
  - name: "slack-default"
    slack_configs:
      - channel: "#alerts-default"
        send_resolved: true
  - name: "pagerduty-critical"
    pagerduty_configs:
      - service_key: "your-pagerduty-service-key"
  - name: "slack-warning"
    slack_configs:
      - channel: "#alerts-warning"

inhibit_rules:
  - source_match:
      severity: "critical"
    target_match:
      severity: "warning"
    equal: ["alertname", "instance"]

9. サービスディスカバリ

9.1 サポートされるSD

SD タイプ説明
static_configs静的なターゲットリスト
file_sd_configsファイルベースのターゲット検出
kubernetes_sd_configsKubernetes API ベース
consul_sd_configsConsul サービスレジストリ
dns_sd_configsDNS ベース(SRV/A/AAAA レコード)
ec2_sd_configsAWS EC2 インスタンス
gce_sd_configsGCP Compute Engine
azure_sd_configsAzure VM
http_sd_configsHTTP エンドポイント

9.2 File-based Service Discovery

scrape_configs:
  - job_name: "file-based-targets"
    file_sd_configs:
      - files: ["/etc/prometheus/targets/*.json"]
        refresh_interval: 5m
[{"targets": ["web-1:9100", "web-2:9100"], "labels": {"env": "production"}}]

9.3 Kubernetes Service Discovery

Kubernetes SD ロール: node, pod, service, endpoints, endpointslice, ingress

scrape_configs:
  - job_name: "kubernetes-pods"
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: "true"
      - source_labels: [__meta_kubernetes_namespace]
        target_label: kubernetes_namespace

9.4 EC2 / Consul / DNS SD

# EC2
- job_name: "ec2-instances"
  ec2_sd_configs:
    - region: "us-east-1"
      port: 9100
      filters:
        - name: "tag:Environment"
          values: ["production"]

# Consul
- job_name: "consul-services"
  consul_sd_configs:
    - server: "consul.example.com:8500"
      services: ["web", "api"]

# DNS
- job_name: "dns-discovery"
  dns_sd_configs:
    - names: ["_prometheus._tcp.example.com"]
      type: SRV

10. Exporter エコシステム

10.1 主要な Exporter

Exporterポート対象
node_exporter9100Linux/macOS OS メトリクス
blackbox_exporter9115HTTP/TCP/ICMP/DNS 外形監視
mysqld_exporter9104MySQL
postgres_exporter9187PostgreSQL
redis_exporter9121Redis
kafka_exporter9308Apache Kafka
nginx_exporter9113NGINX
snmp_exporter9116SNMP デバイス
cadvisor8080コンテナリソース
kube-state-metrics8080Kubernetes オブジェクト状態

10.2 Blackbox Exporter の設定例

# blackbox.yml
modules:
  http_2xx:
    prober: http
    timeout: 5s
    http:
      valid_status_codes: [200]
      method: GET
# prometheus.yml
scrape_configs:
  - job_name: "blackbox-http"
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets: ["https://example.com", "https://api.example.com/health"]
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: "blackbox-exporter:9115"

10.3 クライアントライブラリ(Go の例)

var httpRequestsTotal = prometheus.NewCounterVec(
    prometheus.CounterOpts{
        Name: "http_requests_total",
        Help: "Total number of HTTP requests",
    },
    []string{"method", "endpoint", "status"},
)

func init() {
    prometheus.MustRegister(httpRequestsTotal)
}

func main() {
    http.Handle("/metrics", promhttp.Handler())
    http.ListenAndServe(":8080", nil)
}

11. Pushgateway

短命のバッチジョブからメトリクスを収集するための中間コンポーネント。

scrape_configs:
  - job_name: "pushgateway"
    honor_labels: true
    static_configs:
      - targets: ["pushgateway:9091"]
echo "batch_job_duration_seconds 42.5" | curl --data-binary @- \
  http://pushgateway:9091/metrics/job/my_batch_job

注意: 長時間稼働するサービスには使用せず、直接 Pull すべき。


12. Recording Rules

頻繁に使用されるクエリを事前に計算し、新しい時系列として保存する。

命名規則: level:metric:operations

groups:
  - name: http_recording_rules
    rules:
      - record: job:http_requests_total:rate5m
        expr: sum by (job) (rate(http_requests_total[5m]))
      - record: job:http_request_duration_seconds:p95_5m
        expr: |
          histogram_quantile(0.95,
            sum by (job, le) (rate(http_request_duration_seconds_bucket[5m])))

  - name: node_recording_rules
    rules:
      - record: instance:node_cpu_utilisation:rate5m
        expr: 1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))
      - record: instance:node_memory_utilisation:ratio
        expr: 1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)

  - name: slo_recording_rules
    rules:
      - record: job:slo_error_budget_remaining:ratio30d
        expr: |
          1 - (sum by (job) (increase(http_requests_total{status=~"5.."}[30d]))
          / sum by (job) (increase(http_requests_total[30d]))) / (1 - 0.999)

13. Federation と Remote Storage

13.1 階層型 Federation

scrape_configs:
  - job_name: "federate"
    scrape_interval: 60s
    honor_labels: true
    metrics_path: "/federate"
    params:
      "match[]":
        - '{__name__=~"job:.*"}'
        - 'up'
    static_configs:
      - targets: ["prometheus-dc1:9090", "prometheus-dc2:9090"]

13.2 Remote Write / Read

remote_write:
  - url: "http://thanos-receive:19291/api/v1/receive"
    queue_config:
      capacity: 10000
      max_shards: 200
    write_relabel_configs:
      - source_labels: [__name__]
        regex: "job:.*|instance:.*"
        action: keep

remote_read:
  - url: "http://thanos-query:9090/api/v1/read"
    read_recent: false

13.3 主要な Remote Storage ソリューション

ソリューション特徴
Thanosグローバルビュー、オブジェクトストレージ活用、ダウンサンプリング
Cortexマルチテナント、水平スケーラブル
MimirCortex のフォーク、高パフォーマンス
VictoriaMetrics高圧縮率、高性能、Prometheus互換API

13.4 Thanos のアーキテクチャ概要

                         ┌───────────────┐
                         │  Thanos Query │  ← PromQL 互換 API
                         └───────┬───────┘
                    ┌────────────┼────────────┐
                    ▼            ▼            ▼
             ┌────────────┐ ┌────────┐ ┌────────────┐
             │ Thanos     │ │ Thanos │ │ Thanos     │
             │ Sidecar    │ │ Store  │ │ Receive    │
             └─────┬──────┘ └───┬────┘ └────────────┘
                   │            │
             ┌─────▼──────┐    ▼
             │ Prometheus  │  Object Storage (S3, GCS, etc.)
             └─────────────┘

14. セキュリティと認証

14.1 TLS 暗号化

# web-config.yml
tls_server_config:
  cert_file: /etc/prometheus/tls/server.crt
  key_file: /etc/prometheus/tls/server.key
  min_version: TLS12

basic_auth_users:
  admin: "$2y$12$..."  # bcrypt ハッシュ

14.2 ベストプラクティス

  1. ファイアウォールでポート(9090)へのアクセスを制限
  2. TLS の有効化
  3. Basic認証、mTLS、またはリバースプロキシでの認証
  4. Kubernetes環境ではNetworkPolicyで通信を制限

15. 高可用性 (HA) 構成

15.1 同一構成の複数 Prometheus

同じ設定を持つ2台以上の Prometheus を稼働させ、ロードバランサーまたは Thanos Query で統合。

15.2 Alertmanager の HA

Gossip プロトコルによるネイティブクラスタリングをサポート。

alertmanager --cluster.peer=alertmanager-1:9094 --cluster.peer=alertmanager-2:9094

15.3 Thanos による HA とデデュプリケーション

global:
  external_labels:
    cluster: "production"
    replica: "A"   # レプリカ識別子
thanos query --store=sidecar-a:10901 --store=sidecar-b:10901 --query.replica-label=replica

16. Kubernetes 環境での Prometheus

16.1 Prometheus Operator

主要な CRD: Prometheus, Alertmanager, ServiceMonitor, PodMonitor, PrometheusRule

helm install kube-prometheus prometheus-community/kube-prometheus-stack \
  --namespace monitoring --create-namespace --values values.yaml

16.2 ServiceMonitor

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-application
spec:
  selector:
    matchLabels:
      app: my-application
  endpoints:
    - port: metrics
      interval: 15s

16.3 PrometheusRule

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: application-rules
spec:
  groups:
    - name: application.rules
      rules:
        - alert: PodCrashLooping
          expr: rate(kube_pod_container_status_restarts_total[15m]) * 60 * 5 > 0
          for: 15m
          labels:
            severity: warning

16.4 Kubernetes 固有のメトリクス

# kube-state-metrics
kube_pod_status_phase{phase="Running"}
kube_deployment_spec_replicas
kube_node_status_condition{condition="Ready", status="true"}

# cAdvisor
rate(container_cpu_usage_seconds_total{image!=""}[5m])
container_memory_working_set_bytes{image!=""}

17. Grafana との連携

17.1 データソース設定

apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    url: http://prometheus:9090
    isDefault: true
    jsonData:
      timeInterval: "15s"

17.2 ダッシュボード設計指針

指針説明
USE メソッドUtilization、Saturation、Errors でリソースを監視
RED メソッドRate、Errors、Duration でサービスを監視
Four Golden SignalsLatency、Traffic、Errors、Saturation(Google SRE Book)

18. パフォーマンスチューニング

18.1 スクレイプ設定の最適化

  • 重要度の高いサービス: 10s 間隔
  • インフラメトリクス: 15s 間隔(標準)
  • 変化が緩やかなメトリクス: 60s 間隔
  • 不要なメトリクスは metric_relabel_configs でドロップ

18.2 クエリパフォーマンスの最適化

  1. Recording Rules の活用
  2. 時間範囲の制限
  3. ラベルフィルタの活用(先にフィルタしてから集約)
  4. rate() の範囲はスクレイプ間隔の少なくとも4倍以上

18.3 リソース見積もり

メモリ ≈ アクティブ時系列数 x 4-8 KB x 1.5-3(係数)
例: 100万時系列 → 約 12 GB

18.4 Prometheus 自身の監視

prometheus_tsdb_head_series                              # アクティブ時系列数
rate(prometheus_tsdb_head_samples_appended_total[5m])    # サンプル取り込みレート
prometheus_tsdb_storage_blocks_bytes                     # ストレージサイズ
scrape_duration_seconds                                  # スクレイプ所要時間
rate(prometheus_notifications_errors_total[5m])          # 通知失敗

19. 運用のベストプラクティス

19.1 メトリクス命名規則

<namespace>_<subsystem>_<name>_<unit>

例:
http_server_requests_total           # Counter
http_server_request_duration_seconds # Histogram
process_resident_memory_bytes        # Gauge

規則:

  • スネークケースを使用
  • 単位をサフィックスに含める(_seconds, _bytes, _total
  • Counter には _total サフィックスを付ける
  • ベース単位を使用(ミリ秒ではなく秒、キロバイトではなくバイト)

19.2 アラート設計の原則

  1. 症状ベースのアラート: 原因ではなく症状に基づく
  2. for 句の活用: 一時的なスパイクを除外
  3. 段階的な severity: critical / warning の使い分け
  4. SLO ベースのアラート: バーンレートアラートの活用
  5. Runbook の紐付け: 各アラートに対応手順書を紐付ける

19.3 設定管理

promtool check config prometheus.yml    # 設定バリデーション
promtool check rules rules/*.yml        # ルールバリデーション
promtool test rules test/*.yml          # ルールのユニットテスト

19.4 設定のリロード

kill -HUP $(pidof prometheus)                   # SIGHUP
curl -X POST http://localhost:9090/-/reload      # HTTP API

19.5 バックアップ

curl -X POST http://localhost:9090/api/v1/admin/tsdb/snapshot

20. まとめ

20.1 Prometheus の強み

  1. シンプルで信頼性の高いアーキテクチャ: 外部依存が少なく、単体で完結
  2. 強力なデータモデルとクエリ言語: ラベルベースの多次元データモデルと PromQL
  3. 豊富なエコシステム: 多数の Exporter、クライアントライブラリ、統合ツール
  4. クラウドネイティブ親和性: Kubernetes との深い統合
  5. 活発なコミュニティ: CNCF Graduated プロジェクトとしての成熟度

20.2 Prometheus の制約

  1. 長期ストレージ: ローカルストレージは長期保存に不向き(Thanos 等で補完)
  2. HA のネイティブ非対応: 外部ツールで補完が必要
  3. ログ収集: メトリクス専用(ログは Loki 等が必要)
  4. 高カーディナリティ: ラベルの組み合わせが多いとリソース消費が増大

20.3 Observability Stack 全体像

┌─────────────────────────────────────────────────────────────────┐
│                    Observability Stack                           │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐       │
│  │ Metrics  │  │  Logs    │  │  Traces  │  │ Profiles │       │
│  │Prometheus│  │  Loki    │  │  Tempo   │  │ Pyroscope│       │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘      │
│       └──────────────┼─────────────┼──────────────┘             │
│                      ▼             ▼                            │
│              ┌───────────────────────────┐                      │
│              │         Grafana           │                      │
│              └───────────────────────────┘                      │
│  長期ストレージ: Thanos / Cortex / Mimir / VictoriaMetrics      │
│  アラート: Alertmanager → Slack / PagerDuty / Email / OpsGenie  │
│  CI/CD: promtool check / promtool test                          │
└─────────────────────────────────────────────────────────────────┘

20.4 今後の展望

  1. Native Histograms: より効率的なヒストグラム実装
  2. UTF-8 メトリクス名: メトリクス名に UTF-8 文字列を使用可能にする拡張
  3. OpenTelemetry との統合深化: OTLP のネイティブサポート
  4. Remote Write 2.0: より効率的なリモート書き込みプロトコル
  5. Out-of-Order Ingestion の改善: 時間順序外のサンプル取り込みの効率化

20.5 学習リソース

リソースURL
公式ドキュメントprometheus.io/docs
GitHub リポジトリgithub.com/prometheus/prometheus
PromCon (年次カンファレンス)promcon.io
Awesome Prometheusgithub.com/roaldnefs/awesome-prometheus
Prometheus: Up & Running (書籍)O'Reilly
SRE Book (Google)sre.google/books

20.6 アーキテクチャ選択ガイド

小規模(〜50万時系列)   → 単一 Prometheus + Grafana
中規模(〜500万時系列)  → Prometheus HA + Thanos Sidecar
大規模(〜5000万時系列) → 複数 Prometheus + Thanos / Mimir
超大規模(1億時系列以上) → Grafana Mimir / VictoriaMetrics + Agent Mode

本稿は 2026年4月時点の情報に基づいている。最新の情報は Prometheus 公式ドキュメント (prometheus.io/docs) を参照されたい。