Contents
Observability 基盤構築ガイド ― Prometheus・Grafana のベストプラクティス
ブランドトーン
本稿は 株式会社○○ テクニカルドキュメントガイドライン(口調:フラットで親しみやすく、専門用語は必要に応じて補足) に準拠しています。
・見出しは簡潔かつ具体的に
・コード例は実装可能な形で提示し、プレースホルダーは必ず# TODO:コメントで明示
・表記揺れを排除し、用語は統一(例:Prometheus Operator、Alertmanager、Grafana)
1. Prometheus のデプロイと HA 設計
| デプロイ方法 | 主な特徴 | HA 実装のポイント |
|---|---|---|
| スタンドアロン (バイナリ) | 小規模・テスト向け。設定ファイルだけで起動可能。 | systemd の Restart=always と外部永続ストレージへの定期バックアップを併用 |
Prometheus Operator (monitoring.coreos.com/v1) |
CRD により宣言的管理、ロールアウト自動化。 | spec.replicas: 2 でインスタンス冗長化、volumeClaimTemplate で PVC を確保 |
Helm Chart (prometheus-community/kube-prometheus-stack) |
パラメータ化されたテンプレート。CI/CD に組み込みやすい。 | values.yaml のprometheus.prometheusSpec.replicaCount: 2persistentVolume.enabled: true を設定 |
実装上の留意点
- レプリカ数は最低 2 にし、Pod が落ちても残りがデータを保持できるようにします。
- 永続化ボリューム (PVC) は
ReadWriteOnceではなく、可能ならReadWriteManyを選択し、障害時の手動復旧コストを削減します。 - 遠隔書き込み (
remote_write)は後述のスケールアウトで必須です。
2. Service Discovery と relabeling の実践
基本方針
- 対象限定:ラベルやタグで絞り込むことで、不要なエンドポイント取得を防止。
- 動的フィルタリング:
relabel_configsでkeep/dropを活用し、収集コストとクエリ遅延を最小化。
設定例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Kubernetes (Pod) 自動検出 + relabeling scrape_configs: - job_name: "k8s-pods" kubernetes_sd_configs: - role: pod relabel_configs: # prod 名前空間だけ取得 - source_labels: [__meta_kubernetes_namespace] regex: ^prod$ action: keep # annotation prometheus.io/scrape=true のみ対象 - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] regex: ^true$ action: keep |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# AWS EC2(認証情報はシークレット管理してください) scrape_configs: - job_name: "ec2-instances" ec2_sd_configs: - region: ap-northeast-1 access_key: ${AWS_ACCESS_KEY_ID} # TODO: シークレットから注入 secret_key: ${AWS_SECRET_ACCESS_KEY} # TODO: シークレットから注入 relabel_configs: - source_labels: [__meta_ec2_tag_Environment] regex: ^prod$ action: keep |
|
1 2 3 4 5 6 7 8 9 10 |
# 静的ターゲット(IP フィルタリング) scrape_configs: - job_name: "static-targets" static_configs: - targets: ["10.0.1.10:9090", "10.0.2.20:9090"] relabel_configs: - source_labels: [__address__] regex: ^10\.0\. action: keep |
注記:
<AWS_ACCESS_KEY>等のプレースホルダーは、実運用では Kubernetes Secret や 外部シークレット管理ツール(HashiCorp Vault, AWS Secrets Manager) から注入してください。
3. Grafana のデータソース自動プロビジョニング
YAML 定義 (datasource.yaml)
|
1 2 3 4 5 6 7 8 9 10 11 |
apiVersion: 1 datasources: - name: Prometheus type: prometheus access: proxy url: http://prometheus-operated.monitoring.svc:9090 isDefault: true jsonData: timeInterval: "30s" secureJsonFields: {} |
CI/CD(GitHub Actions)でのデプロイ例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
name: Deploy Grafana provisioning on: push: paths: - 'grafana/provisioning/**' jobs: deploy-grafana: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Copy provisioning files run: | kubectl cp grafana/provisioning/ default/grafana-pod:/etc/grafana/provisioning/ - name: Reload Grafana configuration env: GRAFANA_TOKEN: ${{ secrets.GRAFANA_API_TOKEN }} run: | curl -X POST http://grafana.default.svc/api/admin/settings/reload \ -H "Authorization: Bearer $GRAFANA_TOKEN" |
ベストプラクティス
プロビジョニングファイルはリポジトリでバージョン管理し、Pull Request でレビューする → 手動ミスを防ぎ、環境ごとの差異も即座に把握できます。
4. Alertmanager と Grafana Unified Alerting の連携
重要:Alertmanager が直接 Grafana の Unified Alerting に Webhook 送信できる公式サポートはありません。
現実的な構成は次のいずれかです。
| 方法 | 概要 |
|---|---|
| Prometheus → Alertmanager → 外部通知 (Slack, Email 等) | 従来通り Alertmanager が通知先を管理。Grafana 側ではデータソースとして Prometheus を参照し、ダッシュボード上でアラートステータスを可視化。 |
| Grafana の Unified Alerting だけを使用 | Grafana が Prometheus クエリから直接アラートルールを評価し、通知・サイレンシングを UI で管理。Alertmanager は不要になるケースもある。 |
推奨フロー(Grafana 側のみで完結)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# Grafana Unified Alerting 用 JSON 設定例(Prometheus データソース利用) { "name": "Critical Pods", "type": "prometheus", "settings": { "url": "http://prometheus-operated.monitoring.svc:9090" }, "rules": [ { "alertRuleTags": {}, "condition": "A", "datasourceUid": "Prometheus", "expression": "up == 0", "for": "2m", "labels": { "severity": "critical" }, "name": "Pod down", "noDataState": "NoData", "notifications": [{ "uid": "slack-notif" }], "executionErrorState": "Alerting" } ] } |
サイレンシング例(Grafana UI)
- フィルタ:environment=dev
- 時間帯: 毎日 02:00‑04:00
この構成により、Grafana の統合アラート管理機能だけで完結し、Alertmanager を併用する場合は 通知先の二重化 に注意してください。
5. セキュリティ強化(TLS / mTLS・OAuth2/OIDC・Auth Proxy)
Prometheus の mTLS 設定例(K8s Secret 経由)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
apiVersion: v1 kind: Secret metadata: name: prometheus-tls type: Opaque data: tls.crt: <base64-encoded-cert> # TODO: 実証明書を格納 tls.key: <base64-encoded-key> ca.crt: <base64-encoded-ca> --- apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: name: prometheus spec: secrets: - prometheus-tls web: TLSConfig: cert_file: /etc/prometheus/tls/tls.crt key_file: /etc/prometheus/tls/tls.key client_ca_file: /etc/prometheus/tls/ca.crt client_auth_type: RequireAndVerifyClientCert # クライアント証明書必須 |
Grafana の OAuth2/OIDC + Auth Proxy 設定例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
apiVersion: v1 kind: ConfigMap metadata: name: grafana-ini data: grafana.ini: | [auth.generic_oauth] enabled = true client_id = ${GRAFANA_OAUTH_CLIENT_ID} client_secret = ${GRAFANA_OAUTH_CLIENT_SECRET} scopes = openid profile email auth_url = https://dex.example.com/auth token_url = https://dex.example.com/token api_url = https://dex.example.com/userinfo [auth.proxy] enabled = true header_name = X-Forwarded-User header_property = username auto_sign_up = true |
ポイント
- TLS は外部からの通信だけでなく、Prometheus ↔ Grafana 間でも適用し、mTLS で相互認証を行うと内部侵入リスクが低減します。
- 認証情報はすべて 環境変数または Secret 経由で注入し、コードに平文を書かないよう徹底してください。
6. スケールアウト戦略 & ダッシュボード管理
(1) remote_write による長期保存・水平スケーリング
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
global: scrape_interval: 15s scrape_configs: - job_name: "k8s-pods" kubernetes_sd_configs: - role: pod remote_write: - url: https://thanos-receiver.example.com/api/v1/receive tls_config: ca_file: /etc/prometheus/certs/ca.crt cert_file: /etc/prometheus/certs/client.crt key_file: /etc/prometheus/certs/client.key queue_config: capacity: 2500 max_shards: 20 |
(2) フェデレーションでリージョン横断クエリ
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
scrape_configs: - job_name: "federate-us-east" honor_labels: true metrics_path: "/federate" params: match[]: - '{job="node"}' - '{__name__=~"^go_.*"}' static_configs: - targets: - us-east-prometheus-0.monitoring.svc:9090 - us-east-prometheus-1.monitoring.svc:9090 |
(3) ダッシュボードのコード管理と CI/CD(GitLab CI 例)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
stages: - validate - deploy validate_dashboard: stage: validate image: grafana/grafana-cli:latest script: - grafana-cli admin check-dashboard dashboard.json # JSON が有効か検証 deploy_dashboard: stage: deploy image: curlimages/curl:7.88.1 variables: GRAFANA_TOKEN: $GRAFANA_API_TOKEN script: - | curl -X POST http://grafana.default.svc/api/dashboards/db \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $GRAFANA_TOKEN" \ --data-binary @dashboard.json |
(4) Self‑monitoring(監視スタック自身の可観測性)
|
1 2 3 4 5 6 |
# Prometheus 自己監視ジョブ scrape_configs: - job_name: "prometheus-self" static_configs: - targets: ["localhost:9090"] |
Grafana のメトリクスは grafana_metrics エンドポイント(例:http://grafana.default.svc/api/datasources/proxy/1/api/v1/query)を Prometheus に追加し、grafana_datasource_up などでヘルスチェックします。
まとめ
| 項目 | 実装のキーポイント |
|---|---|
| HA デプロイ | Operator / Helm のレプリカ+PVC |
| Service Discovery | ラベル/タグで絞り込み、relabel_configs でフィルタリング |
| Grafana プロビジョニング | YAML 管理+CI/CD 自動適用 |
| アラート統合 | Grafana Unified Alerting を主軸にし、Alertmanager は外部通知のみ使用(直接 Webhook 連携は非推奨) |
| セキュリティ | TLS/mTLS + OIDC/Auth Proxy、シークレット管理徹底 |
| スケールアウト | remote_write → Thanos/Cortex/Mimir、フェデレーションでリージョン横断、ダッシュボードは Git 管理 & CI/CD デプロイ |
| Self‑monitoring | Prometheus と Grafana の自身メトリクスを収集し、障害検知の可視化 |
これらのベストプラクティスを組み合わせることで、高可用・安全・拡張性に優れた Observability 基盤 を迅速に構築でき、運用負荷とリスクを大幅に低減できます。