Prometheus入門: 明日から使えるDockerセットアップ実践ガイド
一言まとめ: Prometheusとは、システムやアプリのメトリクスをPull型で収集し、ラベル付き時系列として保存・可視化・アラートできるオープンソース監視プラットフォームである。
目次
0. ゴールと前提
ゴール: 「Prometheusで何ができるか」を理解し、自分のマシン(Docker)で最小構成を立ち上げ、メトリクスが取れてアラートの仕組みがある状態まで到達する。
読者前提:
- Docker / docker compose を扱える中級エンジニア
- Linuxコマンド・YAMLに抵抗なし
- 監視ツール経験は問いません(Zabbix/Nagios経験あれば比較しやすい)
この記事で扱わない(軽く触れるのみ)範囲: 分散ストレージ(Thanos/Mimir)、Kubernetes本番設計、マルチテナント大規模設計。
1. なぜPrometheusか?監視にありがちな課題
実務で遭遇する典型的な監視課題:
- サーバ台数が増えると監視設定がスケールしない
- 動的に増減するコンテナ/Podを自動追跡できない
- メトリクス粒度が粗く、根因調査に時間がかかる
- グラフとアラートが別システムで二重管理
- 商用SaaSコストが高い/ベンダーロックインが気になる
Prometheusの価値: 「自己ホスト可能」「ディメンショナル(ラベル)データモデル」「スクレイプ自動化(Service Discovery)」「PromQLによる柔軟分析」「Alertmanager統合」でこれらをまとめて解消しやすい。
2. Prometheusとは
Prometheusはオープンソースの監視&アラートツールキット。単体バイナリ(またはDockerコンテナ)で動作し、HTTPエンドポイントからメトリクスを定期的に**Pull(スクレイプ)**してローカルの時系列DBに保存します。保存したメトリクスは内蔵UIまたはGrafanaで可視化でき、PromQLで柔軟な集計・レート計算・パーセンタイル推定などが可能。閾値や条件をルール化するとAlertmanager経由で通知が飛びます。
キーワード: Pull型 / ラベル / 時系列DB / PromQL / Alertmanager。
3. Prometheusでできること(主なユースケース)
- インフラ監視: CPU, メモリ, ディスク, ネットワーク(Node Exporter)。
- コンテナ監視: cAdvisor, kube-state-metrics, kubeletメトリクス等でKubernetesクラスタ可視化。
- アプリ内部メトリクス: APIリクエスト数, エラーレート, 処理遅延, キュー長, 業務KPI。
- 外形監視(ブラックボックス): HTTP, TCP, ICMP可用性チェック(Blackbox Exporter)。
- アラート連携: SLA逸脱、インスタンスダウン、エラーレート増加などでSlack/PagerDuty通知。
- 集計・傾向分析: レート、移動平均、分位点、最大・最小、環境/リージョン別比較。
4. コアコンセプト5選
以下の5つを押さえればPrometheusの仕組みはほぼ理解できます。
-
Pull型スクレイプ – Prometheusサーバが対象の
/metrics
を定期取得。 -
ラベル付きディメンショナルモデル –
http_requests_total{method="GET",status="200"}
のように複数次元で区別。 - 内蔵時系列DB (TSDB) – ローカルディスクに効率格納。保持期間設定可。
-
PromQL – ラベルを軸に集計・演算。
rate()
,sum by()
,histogram_quantile()
等。 - Alertmanager連携 – ルール評価 → 通知ルーティング / グループ化 / サイレンス。
5. メトリクスタイプ比較表
タイプ | 特性 | 典型用途 | 注意点 | よく使うPromQL関数例 |
---|---|---|---|---|
Counter | 単調増加(リセットあり) | リクエスト数, エラー数, バイト送信累計 | 減少しない前提。リセットに注意(rate() で補正)。 |
rate() , increase()
|
Gauge | 上下する現在値 | メモリ使用量, 接続数 | スナップショット。短周期変動を平滑化するならavg_over_time() 。 |
avg , max , avg_over_time()
|
Histogram | バケット分布(累積) | レイテンシ, サイズ分布 | バケット設計が重要。集計時は*_bucket をsum by (le)。 |
histogram_quantile() |
Summary | クライアント側で分位点計算 | 軽量サービス, 単一Pod統計 | 分散集計に不向き(quantile合成不可)。 | 直接メトリクス参照 |
6. Pull型 vs Push型 比較表(なぜPrometheusはPullか)
観点 | Pull型(Prometheus) | Push型(StatsD的 / Push収集) | 実務メモ |
---|---|---|---|
接続方向 | サーバ→ターゲット | クライアント→集約サーバ | ファイアウォール設計に影響 |
設定管理 | 中央で一元 | 各アプリ側に送信設定 | 規模大でPullの一元化が楽な場合多い |
欠測検出 | スクレイプ失敗で即検知 | データ途絶の推測が必要 | インスタンスDown検知はPullが得意 |
負荷制御 | スクレイプ間隔で調整 | クライアント側制御 | 高頻度送信が氾濫しがち |
短命ジョブ | 苦手(終了前に消える) | 得意 | Pushgatewayで補完可能 |
7. はじめてのアーキテクチャ全体像(図)
シンプルな学習用構成:PrometheusサーバがExporter群をスクレイプし、ルール評価でAlertmanagerへ通知。GrafanaはPrometheusをデータソースとして可視化。
8. Docker Composeで最小監視スタックを立ち上げる
ここではローカル学習用として以下コンポーネントを使います:
- prometheus: メトリクス収集・クエリ
- node-exporter: ホスト系メトリクス
- cadvisor: コンテナメトリクス(任意)
- alertmanager: アラート通知中継(メール/Slack設定はダミー)
- grafana: ダッシュボード(任意だが便利)
8.1 ディレクトリ構成例
prometheus-lab/
├─ docker-compose.yml
├─ prometheus/
│ ├─ prometheus.yml
│ └─ rules/
│ └─ example.rules.yml
├─ alertmanager/
│ └─ alertmanager.yml
├─ grafana/ # 任意(プロビジョニングファイル等)
└─ data/ # 永続化(.gitignore推奨)
8.2 docker-compose.yml サンプル
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./prometheus/rules:/etc/prometheus/rules:ro
- ./data/prometheus:/prometheus
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --storage.tsdb.retention.time=15d
- --web.enable-lifecycle
ports:
- "9090:9090"
depends_on:
- node-exporter
- cadvisor
- alertmanager
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
pid: host
network_mode: host
restart: unless-stopped
# hostネットワークで起動する場合、Compose v2ではservice名ではなくlocalhost:9100でアクセス
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
volumes:
- ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
command:
- --config.file=/etc/alertmanager/alertmanager.yml
ports:
- "9093:9093"
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- ./grafana:/etc/grafana/provisioning
depends_on:
- prometheus
volumes: {}
メモ:
node-exporter
をnetwork_mode: host
で動かすとホストメトリクスが取りやすい反面、他コンテナからの名前解決が変わるのでscrape_configs
側でエンドポイントを調整してください。ローカル学習ならlocalhost:9100
でOK。
8.3 prometheus.yml サンプル(スクレイプ設定)
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
rule_files:
- /etc/prometheus/rules/*.yml
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['prometheus:9090']
- job_name: 'node'
static_configs:
- targets: ['host.docker.internal:9100'] # Mac/Win Docker Desktop用
labels:
instance: 'local-node'
# LinuxネイティブDockerの場合は ['node-exporter:9100'] などに変更
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
例: 最小アラートルール example.rules.yml
groups:
- name: instance-health
rules:
- alert: InstanceDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }} is down"
description: "Prometheus target {{ $labels.job }} / {{ $labels.instance }} unreachable for >2m"
8.4 alertmanager.yml サンプル(通知ダミー)
通知先は環境に合わせて差し替えてください。Slack Webhook例(実際のURLはSecrets管理)。
global:
resolve_timeout: 5m
route:
receiver: 'slack-default'
group_by: ['alertname', 'severity']
group_wait: 30s
group_interval: 5m
repeat_interval: 3h
receivers:
- name: 'slack-default'
slack_configs:
- api_url: 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXX'
channel: '#alerts'
send_resolved: true
title: '{{ .CommonAnnotations.summary }}'
text: '{{ range .Alerts }}*{{ .Labels.alertname }}* ({{ .Labels.severity }})\n{{ .Annotations.description }}\n{{ end }}'
TIP: 本番ではSlack URLを環境変数や外部Secretに分離。Alertmanagerのテンプレ機能で柔軟な本文整形が可能。
8.5 Grafana プロビジョニング(任意)
最初からPrometheusをデータソース登録するには、grafana/provisioning/datasources/ds.yml
を用意。
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
9. 動作確認ステップ
- ディレクトリ作成&YAML配置。
-
docker compose up -d
。 - ブラウザで
http://localhost:9090
→ Status > Targets で UP を確認。 -
http://localhost:9090/graph
でup
をクエリ実行。 - Nodeメトリクスを確認:
node_load1
,node_memory_MemAvailable_bytes
など。 - cAdvisor導入時は
container_cpu_usage_seconds_total
等を確認。 - アラートテスト: node-exporterを停止して
up == 0
で発火するか。 - Alertmanager UI
http://localhost:9093
で受信確認。 - Grafana
http://localhost:3000
(初期admin/admin)→ ダッシュボード作成 → PromQL入力。
10. 明日から使うための最初のチェックリスト
-
Docker Compose環境が起動し、Targetsがすべて
UP
。 - 任意メトリクスを1つPromQLで可視化できた。
-
アラートルール
InstanceDown
が機能する。 - GrafanaからPrometheusに接続できる。
- メトリクスタイプ(Counter/Gauge)が理解できた。
-
ラベルで
環境(prod/stg)
やインスタンス
を区別できる設定にした。
11. よくあるハマりどころと回避策
① ターゲットがDOWNになる
→ コンテナ間ネットワーク名 / ポート番号 / hostモードの整合を確認。
② メトリクス名の乱立
→ 命名規約を決める(<app>_<resource>_<unit>
)。単位はsuffixで(_seconds
, _bytes
)。
③ カーディナリティ爆発
→ ラベルにユーザIDやリクエストIDを入れない。数百~数千で収まる粒度に。
④ Pushgateway乱用
→ バッチジョブ以外では避ける。状態が残り続け誤アラート原因。
⑤ ストレージ不足
→ --storage.tsdb.retention.time
で保持期間を短く。遠隔保管はremote_write検討。
12. 次のステップ(発展)
以下は本記事の次に学ぶと理解が深まるトピック:
- Kubernetes Service DiscoveryでPod自動監視
- Recording Rulesで重いPromQLを事前集計
- Multi-instance高可用構成(ステートレススクレイプ + オブジェクトストレージ)
- 長期保存: Thanos / Mimir / Cortex / VictoriaMetrics 比較
- ログ・トレースと統合(Prometheusはメトリクス担当)→ OpenTelemetry連携へ
付録A: PromQL超ミニチートシート
# 5分間の平均QPS (job別)
sum by (job) (rate(http_requests_total[5m]))
# メモリ使用率(使用/合計)
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)
/ node_memory_MemTotal_bytes
# CPU使用時間の増加(コンテナ別)
sum by (container) (rate(container_cpu_usage_seconds_total[5m]))
# 95パーセンタイルレイテンシ(Histogram)
histogram_quantile(0.95,
sum by (le) (rate(http_request_duration_seconds_bucket[5m]))
)
付録B: 手早くメトリクスを公開するPythonサンプル
最小カスタムメトリクスを出すFlask風サンプル。pip install prometheus-client flask
。
from flask import Flask
from prometheus_client import Counter, Histogram, generate_latest, CONTENT_TYPE_LATEST
import time, random
app = Flask(__name__)
REQ_TOTAL = Counter('demo_requests_total', 'Total requests', ['endpoint'])
LATENCY = Histogram('demo_request_seconds', 'Request latency', ['endpoint'])
@app.route('/')
def index():
start = time.time()
# ダミー処理
time.sleep(random.random() * 0.2)
duration = time.time() - start
REQ_TOTAL.labels(endpoint='/').inc()
LATENCY.labels(endpoint='/').observe(duration)
return 'OK' # 実際のレスポンス
@app.route('/metrics')
def metrics():
return generate_latest(), 200, {'Content-Type': CONTENT_TYPE_LATEST}
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Prometheus側 scrape_configs
に targets: ['your-app:5000']
を追加すれば計測開始。
まとめの再掲
Prometheusとは、メトリクスをPull型で収集し、ラベル付き時系列として保存・可視化・アラートできるオープンソース監視プラットフォームである。
これで「何ができるか」「どう始めるか」「Dockerで最小環境を立ち上げる手順」が揃いました。必要であればこのドキュメントをもとに即日PoCを始めてみてください。追加でGrafanaダッシュボードの例やKubernetes連携を知りたい場合は声をかけてください!