Prometheus
Prometheus 完全ガイド: 機能・アーキテクチャ・設定の全容
目次
- はじめに
- Prometheus とは何か
- コアコンセプトとデータモデル
- アーキテクチャ概要
- メトリクス収集 (Scraping)
- PromQL (Prometheus Query Language)
- ストレージエンジン (TSDB)
- アラートルールと Alertmanager
- サービスディスカバリ
- Exporter エコシステム
- Pushgateway
- Recording Rules
- Federation と Remote Storage
- セキュリティと認証
- 高可用性 (HA) 構成
- Kubernetes 環境での Prometheus
- Grafana との連携
- パフォーマンスチューニング
- 運用のベストプラクティス
- まとめ
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 は以下の現代的な課題に対応する。
- 動的な環境への適応: コンテナやクラウド環境では、監視対象が頻繁に増減する。Prometheus のサービスディスカバリ機能により、これに自動的に追従できる。
- 高カーディナリティのメトリクス: ラベルベースのデータモデルにより、HTTP ステータスコード別、エンドポイント別、リージョン別など、多次元的な分析が可能。
- アプリケーションレベルの監視: アプリケーション固有のビジネスメトリクスやパフォーマンスメトリクスの収集に適している。
- 信頼性の高い監視: 外部の分散ストレージに依存しないため、監視対象のインフラに障害が発生しても監視システム自体は稼働し続ける。
2.3 タイムライン
| 年 | イベント |
|---|---|
| 2012 | SoundCloud で開発開始 |
| 2015 | 公式に公開リリース |
| 2016 | CNCF に参加(2番目のプロジェクト) |
| 2017 | Prometheus 2.0 リリース(新ストレージエンジン) |
| 2018 | CNCF Graduated プロジェクトに昇格 |
| 2019 | OpenMetrics 標準の策定 |
| 2021 | Prometheus Agent Mode の導入 |
| 2023 | Native Histograms のサポート |
| 2024 | UTF-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 の比較
| 特性 | Histogram | Summary |
|---|---|---|
| パーセンタイル計算 | サーバ側 (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 データフロー
- サービスディスカバリ がターゲットリストを生成
- Retrieval が各ターゲットの
/metricsを HTTP GET で取得 - メトリクスが TSDB に書き込まれる
- Recording Rules が評価され、結果が新しい時系列として保存される
- Alert Rules が評価され、条件合致時に Alertmanager に通知される
- 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_configs | Kubernetes API ベース |
consul_sd_configs | Consul サービスレジストリ |
dns_sd_configs | DNS ベース(SRV/A/AAAA レコード) |
ec2_sd_configs | AWS EC2 インスタンス |
gce_sd_configs | GCP Compute Engine |
azure_sd_configs | Azure VM |
http_sd_configs | HTTP エンドポイント |
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_exporter | 9100 | Linux/macOS OS メトリクス |
| blackbox_exporter | 9115 | HTTP/TCP/ICMP/DNS 外形監視 |
| mysqld_exporter | 9104 | MySQL |
| postgres_exporter | 9187 | PostgreSQL |
| redis_exporter | 9121 | Redis |
| kafka_exporter | 9308 | Apache Kafka |
| nginx_exporter | 9113 | NGINX |
| snmp_exporter | 9116 | SNMP デバイス |
| cadvisor | 8080 | コンテナリソース |
| kube-state-metrics | 8080 | Kubernetes オブジェクト状態 |
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 | マルチテナント、水平スケーラブル |
| Mimir | Cortex のフォーク、高パフォーマンス |
| 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 ベストプラクティス
- ファイアウォールでポート(9090)へのアクセスを制限
- TLS の有効化
- Basic認証、mTLS、またはリバースプロキシでの認証
- 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 Signals | Latency、Traffic、Errors、Saturation(Google SRE Book) |
18. パフォーマンスチューニング
18.1 スクレイプ設定の最適化
- 重要度の高いサービス: 10s 間隔
- インフラメトリクス: 15s 間隔(標準)
- 変化が緩やかなメトリクス: 60s 間隔
- 不要なメトリクスは
metric_relabel_configsでドロップ
18.2 クエリパフォーマンスの最適化
- Recording Rules の活用
- 時間範囲の制限
- ラベルフィルタの活用(先にフィルタしてから集約)
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 アラート設計の原則
- 症状ベースのアラート: 原因ではなく症状に基づく
for句の活用: 一時的なスパイクを除外- 段階的な severity: critical / warning の使い分け
- SLO ベースのアラート: バーンレートアラートの活用
- 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 の強み
- シンプルで信頼性の高いアーキテクチャ: 外部依存が少なく、単体で完結
- 強力なデータモデルとクエリ言語: ラベルベースの多次元データモデルと PromQL
- 豊富なエコシステム: 多数の Exporter、クライアントライブラリ、統合ツール
- クラウドネイティブ親和性: Kubernetes との深い統合
- 活発なコミュニティ: CNCF Graduated プロジェクトとしての成熟度
20.2 Prometheus の制約
- 長期ストレージ: ローカルストレージは長期保存に不向き(Thanos 等で補完)
- HA のネイティブ非対応: 外部ツールで補完が必要
- ログ収集: メトリクス専用(ログは Loki 等が必要)
- 高カーディナリティ: ラベルの組み合わせが多いとリソース消費が増大
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 今後の展望
- Native Histograms: より効率的なヒストグラム実装
- UTF-8 メトリクス名: メトリクス名に UTF-8 文字列を使用可能にする拡張
- OpenTelemetry との統合深化: OTLP のネイティブサポート
- Remote Write 2.0: より効率的なリモート書き込みプロトコル
- Out-of-Order Ingestion の改善: 時間順序外のサンプル取り込みの効率化
20.5 学習リソース
| リソース | URL |
|---|---|
| 公式ドキュメント | prometheus.io/docs |
| GitHub リポジトリ | github.com/prometheus/prometheus |
| PromCon (年次カンファレンス) | promcon.io |
| Awesome Prometheus | github.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) を参照されたい。