ラベル・リライト実践 - メタラベル・relabel_configs・metric_relabel_configs の活用

はじめに

Part 2-1, 2-2 では Prometheus のスクレイプ設定とサービスディスカバリーを学びました。ここからは、ラベルとリライト(relabel)という高度な機能に取り組みます。ラベルはメトリクスを識別・分類するための最重要要素であり、リライト機能を使うと、スクレイプ段階で柔軟にラベルを操作できます。本記事では、ラベルの設計指針、メタラベルの活用法、そして実践的なリライト設定パターンを具体例を通じて解説します。

ラベル命名規則ガイド

Prometheus では、メトリクスにはさまざまなラベルが付与されます。チーム全体で統一された命名規則を持つことで、ルール作成やクエリが格段に書きやすくなります。

命名の基本原則

キャメルケース、スネークケースのいずれを選ぶか は事前に決めておくべき事項です。Prometheus 公式スタイルガイドではスネークケース(instance_type, node_role)の使用を推奨しています。

ラベル名に含まれるべき情報:

  • 対象の種類: service, job, cluster
  • 環境情報: env, environmentproduction, staging など)
  • 位置情報: region, zone, datacenter
  • 機能分類: tierweb, cache, db)、rolemaster, slave

よくある命名パターン

service=api              # サービス名
job=node-exporter       # スクレイプジョブ名
instance=server1:9100   # 監視対象(自動付与)
env=production          # 環境
region=us-west-1        # リージョン
zone=us-west-1a         # アベイラビリティゾーン
tier=web                # 層

統一されたラベルセットがあれば、後からの集計・フィルタリングが容易になります。例えば sum by (service, env) というようなクエリで、サービスと環境単位での集計が直感的に行えます。

避けるべきパターン

  • 高カーディナリティ: user_id, request_id のように固有値が大量に増えるラベルは避けるべきです。ラベル組み合わせの爆発的増加につながり、メモリ効率と クエリ性能の低下を招きます
  • 冗長性: hostname=server1instance=server1:9100 の両方は不要です。必要な情報をラベルに厳選することが大切です

メタラベル一覧表と活用方法

スクレイプ時、Prometheus は発見したターゲットに対してメタラベル(meta-label)を自動付与します。これは一時的な情報で、リライト設定で操作できます。

メタラベルの全体像

以下は主要なメタラベルの一覧です。メタラベル名は __meta_ で始まり、ディスカバリー方式ごとに異なります。

メタラベル発見元説明
__address__全てスクレイプ対象のホスト:ポート(例: server1:9100
__scheme__全て通信スキーム(http または https
__metrics_path__全てメトリクスエンドポイントのパス(デフォルト: /metrics
__meta_kubernetes_pod_nameKubernetesポッド名
__meta_kubernetes_pod_namespaceKubernetesポッド所属ネームスペース
__meta_kubernetes_pod_annotation_prometheus_io_scrapeKubernetesprometheus.io/scrape アノテーション値
__meta_kubernetes_pod_annotation_prometheus_io_pathKubernetesポッドアノテーション prometheus.io/path の値
__meta_kubernetes_pod_annotation_prometheus_io_portKubernetesポッドアノテーション prometheus.io/port の値
__meta_ec2_instance_idEC2EC2 インスタンス ID
__meta_ec2_tag_NameEC2EC2 タグ Name の値
__meta_ec2_instance_typeEC2EC2 インスタンスタイプ(t3.micro など)
__meta_ec2_availability_zoneEC2アベイラビリティゾーン
__meta_consul_serviceConsulConsul サービス名
__meta_consul_nodeConsulConsul ノード名
__meta_consul_tag_*ConsulConsul タグ(* は タグキー)
__meta_dns_nameDNSDNS 名前解決の結果

これらのメタラベルはリライト設定で参照でき、最終的なラベルセットを自由に構成できます。

relabel_configs ケース別実装例

relabel_configs はスクレイプ前段階で、メタラベルと既存ラベルを使ってラベルを操作します。主要なアクションは keep, drop, replace, labelmap, labeldrop, labelkeep です。

ケース 1: Kubernetes アノテーションベースのターゲットフィルタリング

Kubernetes 環境では、ポッドのアノテーション prometheus.io/scrape: true があるポッドのみを監視対象にするパターンが一般的です。

yaml
scrape_configs:
  - job_name: 'kubernetes-pods'
    kubernetes_sd_config:
      - role: 'pod'
    
    relabel_configs:
      # prometheus.io/scrape が true のポッドのみを keep
      - 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_pod_name]
        action: 'replace'
        target_label: pod
      
      # ネームスペースをラベルに設定
      - source_labels: [__meta_kubernetes_pod_namespace]
        action: 'replace'
        target_label: namespace

このパターンでは、Kubernetes API に登録された全ポッドの中から、特定のアノテーションを持つものだけを自動フィルタリングしています。

ケース 2: EC2 タグをラベルとして活用

AWS 環境では、EC2 インスタンスのタグが豊富に付与できます。これらを Prometheus ラベルとして流用するパターンです。

yaml
scrape_configs:
  - job_name: 'ec2-instances'
    ec2_sd_config:
      - region: 'us-west-1'
        access_key: '...'
        secret_key: '...'
    
    relabel_configs:
      # Environment タグをラベルに昇格
      - source_labels: [__meta_ec2_tag_Environment]
        action: 'replace'
        target_label: env
      
      # Name タグからホスト名を抽出
      - source_labels: [__meta_ec2_tag_Name]
        action: 'replace'
        target_label: hostname
      
      # アベイラビリティゾーンをラベルに
      - source_labels: [__meta_ec2_availability_zone]
        action: 'replace'
        target_label: zone
      
      # Application タグがある場合のみ keep
      - source_labels: [__meta_ec2_tag_Application]
        action: 'keep'
        regex: '.+'
      
      # メタラベルは出力から削除
      - action: 'labelmap'
        regex: '__meta_ec2_tag_(.+)'
        replacement: 'tag_${1}'

labelmap アクションを使用すると、複数のメタラベルを一度にラベルに変換できます。

ケース 3: DNS 解析による逆引きとホスト名抽出

IP アドレスからホスト名を逆引きし、最初の要素(サーバー識別名)をラベルとして使用するパターンです。

yaml
scrape_configs:
  - job_name: 'static-targets'
    static_configs:
      - targets: ['10.0.1.5:9100', '10.0.1.6:9100']
    
    relabel_configs:
      # __address__ から IP アドレスを抽出
      - source_labels: [__address__]
        action: 'replace'
        regex: '([^:]+):.*'
        replacement: '${1}'
        target_label: __tmp_ip
      
      # 例: DNS 逆引き結果の FQDN から最初の要素を抽出
      # (注: 実際の逆引きは外部ツール等を組み合わせるか、__meta_dns_name が使える環境での運用)
      - source_labels: [__tmp_ip]
        action: 'replace'
        regex: '10\.0\.1\.(\d+)'
        replacement: 'server${1}'
        target_label: hostname

ケース 4: 環境別フィルタリングと自動ジョブ名変更

複数の環境(production, staging, dev)を同じスクレイプ設定で管理し、ターゲットの属性に基づいて自動的にジョブ名やラベルを付与するパターンです。

yaml
scrape_configs:
  - job_name: 'multi-env'
    static_configs:
      - targets: ['api-prod-1:9090', 'api-prod-2:9090']
        labels:
          env: 'production'
          tier: 'api'
      - targets: ['api-staging-1:9090']
        labels:
          env: 'staging'
          tier: 'api'
      - targets: ['db-prod-1:9104', 'db-prod-2:9104']
        labels:
          env: 'production'
          tier: 'database'
    
    relabel_configs:
      # env と tier からジョブ名を再構成(可読性向上)
      - source_labels: [env, tier]
        action: 'replace'
        target_label: job
        regex: '(.+);(.+)'
        replacement: '${1}-${2}'
      
      # staging 環境のみを残す場合
      # - source_labels: [env]
      #   action: 'keep'
      #   regex: 'staging'

複数の source_labels を指定した場合、separator(デフォルトはセミコロン;)で結合されます。このケースではセミコロンで結合された "production;api" を regex でキャプチャグループに分割し、最終的に ${1}-${2}"production-api" に置換しています。

ケース 5: メトリクスパスの動的な割り当て

同じホスト上で複数のエクスポーターが異なるパスで動作している場合、リライト設定で パスを動的に割り当てるパターンです。

yaml
scrape_configs:
  - job_name: 'multi-exporter'
    static_configs:
      - targets: ['localhost:9090']
        labels:
          exporter_type: 'prometheus'
          metrics_path: '/metrics'
      - targets: ['localhost:9100']
        labels:
          exporter_type: 'node'
          metrics_path: '/metrics'
      - targets: ['localhost:3000']
        labels:
          exporter_type: 'app'
          metrics_path: '/custom-metrics'
    
    relabel_configs:
      # labels の metrics_path メタラベルから __metrics_path__ を構成
      - source_labels: [metrics_path]
        action: 'replace'
        target_label: __metrics_path__
        regex: '(.+)'
      
      # exporter_type ラベルをそのまま保持
      - source_labels: [exporter_type]
        action: 'replace'
        target_label: exporter

metric_relabel_configs の活用

metric_relabel_configs はスクレイプ後段階で、実際に取得したメトリクスに対して作用します。relabel_configs と異なり、メトリクスの集計値そのものには影響せず、ラベル層での操作です。

用途の差し分け

機能実行時期操作対象用途例
relabel_configsスクレイプ前メタラベル + 既存ラベルターゲット発見後のフィルタリング、ジョブ名変更
metric_relabel_configsスクレイプ後実メトリクスのラベル不要なメトリクスの削除、高カーディナリティラベルの削除、機密情報のマスク

実装例:不要なメトリクスの削除

スクレイプしたメトリクスの中には、保存が不要なものが含まれることがあります。metric_relabel_configs で削除することで、ストレージ効率が向上します。

yaml
scrape_configs:
  - job_name: 'node-exporter'
    static_configs:
      - targets: ['server1:9100']
    
    metric_relabel_configs:
      # テンポラリなメトリクスは削除
      - source_labels: [__name__]
        action: 'drop'
        regex: '.*_temp$'
      
      # node_textfile_mtime は保存不要な場合
      - source_labels: [__name__]
        action: 'drop'
        regex: 'node_textfile_mtime'
      
      # ファイルシステムメトリクスから tmpfs を除外
      - source_labels: [__name__, fstype]
        action: 'drop'
        regex: 'node_filesystem_.*;tmpfs'

実装例:高カーディナリティラベルの制限

ディバイス名やマウントポイント数が多い場合、メトリクス数が爆発的に増えます。必要なものだけに制限する例です。

yaml
scrape_configs:
  - job_name: 'node-exporter'
    static_configs:
      - targets: ['server1:9100']
    
    metric_relabel_configs:
      # ディスク関連メトリクスで sda, sdb のみを保持
      - source_labels: [__name__, device]
        action: 'keep'
        regex: 'node_disk_.*;(sda|sdb)'
      
      # その他のメトリクスはすべて keep
      - source_labels: [__name__]
        action: 'keep'
        regex: '(?!node_disk_).*'

ベストプラクティスと注意点

ベストプラクティス

  1. ラベル設計は事前に統一: ラベル命名規則をドキュメント化し、チーム全体で共有しましょう。後からの変更は大変です。

  2. メタラベルの活用を優先: EC2 タグや Kubernetes アノテーションなど、既存の管理情報を活用することで、重複管理を避けられます。

  3. 正規表現テストを入念に: 正規表現のミスはフィルタリング漏れやマッチ誤りの原因になります。テスト環境で動作確認してから本番適用しましょう。

  4. パフォーマンス監視: 高カーディナリティラベルが含まれていないか、定期的に確認してください。cardinalitytsdb コマンドでメトリクス数を可視化できます。

  5. セキュリティに配慮: パスワードや機密情報をラベルに含めないよう注意。metric_relabel_configs で機密情報を持つメトリクスは早期に削除しましょう。

  6. 正規表現のキャプチャグループ活用: キャプチャグループ (...) で抽出した値は、replacement で $1, $2 または ${1}, ${2} で参照できます。非キャプチャグループ (?:...) はマッチ対象に含まれますがキャプチャ値には含まれません。ケース 1 の例では (?::\d+)? で既存ポート番号をマッチ対象から除外しています。

よくある落とし穴

  • 正規表現の regex フィールド忘却: source_labels を指定しても、regex がないと全文マッチとなり、想定外の動作につながります。
  • 置換の replacement 順序: 複数の relabel_configs を連鎖させる際は、順序が影響します。上から順に処理されるため、後の設定に依存する場合は特に注意が必要です。
  • メタラベルの存在確認忘れ: ディスカバリー方式によってメタラベルの有無が異なります。存在しないメタラベルへのアクセスはマッチ失敗につながります。

ナビゲーション

前パートの学習に戻る:スクレイプ設定パターン集 - 実践的な設定方法

Prometheus Part 2 概要に戻る:Part 2 - スクレイプ・サービスディスカバリー・ラベル・リライト

Part 3(ルール・アラート)へ:アラートルール・記録ルール - 実装パターン