Skip to content
Published on

[Prometheus] サービスディスカバリメカニズム完全分析

Authors

1. 概要

Prometheusのサービスディスカバリ(Service Discovery)はモニタリングターゲットを自動的に発見・管理するコアサブシステムです。クラウドネイティブ環境ではサービスインスタンスが動的に生成/削除されるため、静的設定だけでは全ターゲットを追跡できません。

この記事ではDiscovery Managerのアーキテクチャ、Providerインターフェース、各SD実装の動作方式、リラベリングメカニズム、ターゲットライフサイクルをソースコードレベルで分析します。

2. Discovery Managerアーキテクチャ

2.1 全体構造

prometheus.ymlのscrape_configs
        |
        v
+-------------------+
| Discovery Manager |
|                   |
|  +-- Provider 1 (kubernetes_sd)  -- goroutine
|  +-- Provider 2 (consul_sd)     -- goroutine
|  +-- Provider 3 (file_sd)       -- goroutine
|  +-- Provider 4 (static_config) -- goroutine
|                   |
+--------+----------+
         |
    Target Groups Channel
         |
         v
+-------------------+
| Scrape Manager    |
+-------------------+

2.2 Discovery Managerの役割

  1. プロバイダ管理: 各サービスディスカバリプロバイダのライフサイクル管理
  2. 更新収集: プロバイダからターゲットグループ変更を収集
  3. 一括配信: 変更をバッファリングしてScrape Managerに一括配信
  4. 設定リロード: 新設定適用時にプロバイダを再生成

2.3 更新フロー

Provider変更検知
    |
    v
更新を内部チャネルに送信
    |
    v
Discovery Managerが受信
    |
    v
5秒間追加更新を待機(デバウンシング)
    |
    v
全プロバイダの最新ターゲットグループをマージ
    |
    v
Scrape Managerに全ターゲットマップを配信

3. Providerインターフェース

3.1 Discovererインターフェース

すべてのサービスディスカバリプロバイダはDiscovererインターフェースを実装します:

type Discoverer interface {
    Run(ctx context.Context, up chan<- []*targetgroup.Group)
}

Runメソッドの契約:

  • contextがキャンセルされるまで実行を維持
  • ターゲットグループ変更時にupチャネルに全グループリストを送信
  • 初回実行時に現在認識している全ターゲットを送信

3.2 TargetGroup構造

TargetGroup:
  Source: "kubernetes/pod/default/nginx-abc123"(一意識別子)
  Targets:
    - __address__: "10.0.1.5:8080"
    - __address__: "10.0.1.6:8080"
  Labels:
    __meta_kubernetes_namespace: "default"
    __meta_kubernetes_pod_name: "nginx-abc123"
    ...

4. Kubernetes SD

4.1 kubernetes_sd概要

Kubernetes SDはPrometheusで最も多く使用されるサービスディスカバリです。Kubernetes APIサーバーのWatchメカニズムを使用してリソース変更をリアルタイムで検知します。

4.2 ロール(Role)タイプ

kubernetes_sdは6つのロールタイプをサポートします:

1. node: Kubernetesノードリスト
2. service: Kubernetes Serviceリスト
3. pod: Kubernetes Podリスト
4. endpoints: Kubernetes Endpointsリスト
5. endpointslice: Kubernetes EndpointSliceリスト(大規模クラスタでより効率的)
6. ingress: Kubernetes Ingressリスト

4.3 Watchメカニズム

Kubernetes SD Watch動作:

1. 初期同期:
   a. List APIで全リソースリストを取得
   b. 全リソースをTargetGroupに変換
   c. 全リストをDiscovery Managerに送信

2. Watch開始:
   a. Watch APIでイベントストリームに接続
   b. resourceVersionベースの増分更新

3. イベント処理:
   ADDED    -> 新TargetGroup作成
   MODIFIED -> 既存TargetGroup更新
   DELETED  -> 空TargetsでTargetGroup更新

4. エラー処理:
   Watch切断       -> 自動再接続
   410 Goneエラー  -> 全再リスト化
   タイムアウト    -> Watch再起動

4.4 Informer/Reflectorパターン

kubernetes_sdはclient-goのInformerパターンを活用します:

Informer構造:
  Reflector
    |-- List: 初期全同期
    |-- Watch: 増分更新受信
    |-- Store: ローカルキャッシュに保存
    v
  Informer
    |-- EventHandler: イベントコールバック登録
    |-- Indexer: 効率的検索のためのインデックス
    v
  Prometheus SD
    |-- イベントをTargetGroupに変換
    |-- Discovery Managerに配信

4.5 __metaラベル

kubernetes_sdは豊富なメタラベルを提供します:

共通:
  __meta_kubernetes_namespace

Podロール:
  __meta_kubernetes_pod_name
  __meta_kubernetes_pod_ip
  __meta_kubernetes_pod_container_name
  __meta_kubernetes_pod_label_*
  __meta_kubernetes_pod_annotation_*
  __meta_kubernetes_pod_node_name
  __meta_kubernetes_pod_ready
  __meta_kubernetes_pod_phase

Nodeロール:
  __meta_kubernetes_node_name
  __meta_kubernetes_node_label_*
  __meta_kubernetes_node_address_*

Serviceロール:
  __meta_kubernetes_service_name
  __meta_kubernetes_service_port_name
  __meta_kubernetes_service_label_*
  __meta_kubernetes_service_annotation_*

5. リラベリングメカニズム

5.1 リラベリング概要

リラベリングはターゲットのラベルを変換する強力なメカニズムです。2段階で適用されます:

段階1: relabel_configs(スクレイピング前)
  - ディスカバリからの__meta_*ラベル処理
  - ターゲットラベル決定(job、instanceなど)
  - ターゲット保持/削除決定

段階2: metric_relabel_configs(スクレイピング後)
  - 収集されたメトリクスのラベル変換
  - 不要なメトリクス削除
  - ラベル名/値変換

5.2 リラベリングアクション

replace:     ソースラベル値を正規表現マッチ後ターゲットラベルに設定
keep:        正規表現にマッチしないターゲットを削除
drop:        正規表現にマッチするターゲットを削除
hashmod:     ソースラベルのハッシュ値をモジュロ演算してターゲットラベルに設定
labelmap:    正規表現にマッチするラベル名を変換
labeldrop:   正規表現にマッチするラベルを削除
labelkeep:   正規表現にマッチしないラベルを削除
lowercase:   ターゲットラベル値を小文字に変換
uppercase:   ターゲットラベル値を大文字に変換

5.3 リラベリング処理フロー

__meta_*ラベル + __address__ + __scheme__ + __metrics_path__
                    |
                    v
          relabel_configsを順次適用
                    |
                    v
          __address__ -> instanceラベルにコピー
          __scheme__、__metrics_path__など内部ラベル除去
                    |
                    v
          最終ターゲットラベルセット決定

5.4 一般的なリラベリングパターン

Podアノテーションベースのスクレイピング:

relabel_configs:
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
    action: keep
    regex: true
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
    action: replace
    target_label: __address__
    regex: (.+)
    replacement: __meta_kubernetes_pod_ip:$1
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
    action: replace
    target_label: __metrics_path__
    regex: (.+)

ネームスペースフィルタリング:

relabel_configs:
  - source_labels: [__meta_kubernetes_namespace]
    action: keep
    regex: production|staging

6. ファイルベースSD

6.1 概要

File SDはJSONまたはYAMLファイルからターゲットを読む最もシンプルな動的ディスカバリです:

scrape_configs:
  - job_name: 'file_sd'
    file_sd_configs:
      - files:
          - '/etc/prometheus/targets/*.json'
        refresh_interval: 5m

6.2 ターゲットファイル形式

[
  {
    "targets": ["10.0.1.1:9090", "10.0.1.2:9090"],
    "labels": {
      "env": "production",
      "team": "backend"
    }
  }
]

6.3 ファイル監視メカニズム

File SD動作:
1. 初期ロード:パターンにマッチする全ファイル読み込み
2. inotify監視:Linuxでファイル変更イベントを購読
3. 定期ポーリング:refresh_interval(デフォルト5分)ごとに全再ロード
4. ファイル変更時:変更ファイルのみ再パースしてTargetGroup更新
5. ファイル削除時:該当ファイルの全ターゲットを除去

6.4 カスタムSDブリッジパターン

File SDはカスタムサービスディスカバリのブリッジとして活用されます。Prometheus直接統合されていないサービスレジストリ(Zookeeper、etcdなど)との連携に有用です。

7. HTTP SD

HTTP SDはHTTPエンドポイントからターゲットリストを定期的にポーリングします:

scrape_configs:
  - job_name: 'http_sd'
    http_sd_configs:
      - url: 'http://service-registry:8080/targets'
        refresh_interval: 30s
HTTP SD処理:
1. refresh_intervalごとにURLにGETリクエスト
2. レスポンスJSONをパース
3. TargetGroupに変換
4. Discovery Managerに配信
5. HTTPエラー時は前回結果を維持

8. その他のSD実装

8.1 Consul SD

Consul SDはConsulのService Catalog APIを使用し、Watch/Blocking Queryで変更を検知します。サービス名、タグ、データセンターベースのフィルタリングをサポートします。

8.2 EC2 SD

EC2 SDはAWS EC2 DescribeInstances APIを使用し、リージョン、アベイラビリティゾーン、タグベースのフィルタリングをサポートします。IAMロールまたはアクセスキー認証に対応します。

8.3 DNS SD

DNS SDはDNS SRVまたはA/AAAAレコードルックアップを行う定期ポーリング方式です。シンプルな環境で有用です。

9. ターゲットライフサイクル

9.1 ターゲット状態遷移

ターゲットライフサイクル:
  Discovered(発見)
      |
      v
  Relabeled(ラベル適用)
      |
      +-- 削除決定 --> Dropped(削除)
      |
      v
  Active(アクティブ、スクレイピング開始)
      |
      +-- スクレイピング成功 --> up=1
      +-- スクレイピング失敗 --> up=0
      |
      v
  Disappeared(消失)
      |
      v
  Stale(stale marker追加)
      |
      v
  Removed(Scrape Loop終了)

9.2 Droppedターゲット

ターゲットがドロップされる条件:

1. relabel_configsでdropアクション適用
2. relabel_configsでkeepアクションにマッチしない
3. __address__ラベルが空
4. 重複ターゲット(同一ラベルセット)

ドロップされたターゲットは/targets UIの"Dropped Targets"セクションに表示され、
ディスカバリとリラベリング設定のデバッグに活用できます。

9.3 ターゲット健全性モニタリング

組み込みメトリクス:
  up: 0または1(スクレイピング成功可否)
  scrape_duration_seconds: スクレイピング所要時間
  scrape_samples_scraped: 収集されたサンプル数
  scrape_samples_post_metric_relabeling: リラベリング後のサンプル数
  scrape_series_added: 新たに追加された時系列数

10. パフォーマンス考慮事項

10.1 大規模クラスタでの最適化

Kubernetes SDパフォーマンスのヒント:
1. ネームスペース制限: namespacesフィールドで監視範囲を縮小
2. ラベルセレクタ: selectorsフィールドでリソースフィルタリング
3. attach_metadata: 不要なら無効化
4. EndpointSlice使用: 大規模クラスタでEndpointsより効率的

10.2 ディスカバリ負荷モニタリング

主要メトリクス:
  prometheus_sd_discovered_targets: 発見されたターゲット数(SDタイプ別)
  prometheus_sd_received_updates_total: 受信した更新数
  prometheus_sd_updates_total: 配信した更新数
  prometheus_sd_updates_delayed_total: 遅延した更新数

11. デバッグとトラブルシューティング

11.1 一般的な問題

1. ターゲットが発見されない:
   - SD設定確認(namespace、selectorなど)
   - PrometheusログでSDエラー確認
   - /service-discovery UIで発見されたターゲット確認

2. ターゲットがDropped状態:
   - relabel_configsルール順序確認
   - keep/dropアクションのregex検証
   - /targetsページでDropped Targets確認

3. ターゲットラベルが予想と異なる:
   - __meta_*ラベル確認(/service-discoveryページ)
   - relabel_configsのreplaceルール確認
   - ラベル競合時のhonor_labels設定確認

12. まとめ

Prometheusのサービスディスカバリはプラグインアーキテクチャを通じて多様なインフラ環境をサポートします。Kubernetes SDのWatchメカニズム、リラベリングの強力なラベル変換、File SD/HTTP SDによるカスタム拡張がコアです。

次の記事ではPrometheusのアラートパイプラインを分析します。Rule Managerの評価メカニズム、Alert状態マシン、Alertmanagerのルーティングとアラート配信プロセスを解説する予定です。