PrometheusとGrafanaによるHashiCorp Vault監視ガイド:トークンリース、リクエストレイテンシ、Unseal状態の可視化

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

HashiCorp Vaultを監視する3つのアプローチ

本番環境において、Vaultの停止はシステム全体の麻痺を意味します。バックエンド、ワーカー、CI/CDパイプラインに至るまで、すべてのサービスがデータベースの認証情報やAPIキーを取得できなくなってしまいます。そのため、「Vaultクラスタをどのように監視するのが最適か」という点が極めて重要な課題となります。実際の現場では、DevOpsエンジニアは主に次の3つのアプローチを検討します。

  • アプローチ1:HTTPエンドポイントによる定期的なヘルスチェック — Prometheus Blackbox Exporterや外部の監視サービスを使用して、/v1/sys/healthエンドポイントを継続的にポーリングする方法です。この方法は、ステータスコードが200(active)、429(standby)、503(sealed)のいずれであるかを確認するだけのシンプルな仕組みです。
  • アプローチ2:監査ログ(Audit Log)のSIEM/ELK集約 — 監査デバイス(ファイルまたはsyslog)を有効化し、ログをすべてLokiやElasticsearchに転送する方法です。主な目的は、リクエスト数の集計や不正アクセスの追跡・監査です。
  • アプローチ3:Prometheus & GrafanaによるネイティブTelemetryの有効化 — Vaultに標準搭載されているTelemetryエンジンを活用する方法です。各ノードが/v1/sys/metricsエンドポイントを通じて、OpenMetrics仕様に準拠したメトリクスを直接出力します。

各アプローチのメリットとデメリット

これら3つのアプローチには、それぞれ異なる目的と得手不得手があります。

1. HTTPヘルスチェック(Blackbox監視)

  • メリット:極めて簡単に導入できます。Vaultの設定ファイルを変更することなく、外部から5分程度で設定可能です。
  • デメリット:内部の動作状況が完全に「ブラックボックス」となります。Vaultが5万件のトークンリースを抱えているのか50万件なのか、Raftストレージへの書き込みレイテンシがどれくらいか、スタンバイノードのレプリケーション遅延が発生していないかなどを把握することはできません。

2. 監査ログ(Audit Log)の分析

  • メリット:「どのトークンが、どのパスに対して、どのIPから、何時何分にアクセスしたか」という詳細なアイデンティティ情報を正確に記録できます。コンプライアンスやセキュリティ監査には不可欠なデータです。
  • デメリット:ディスクI/Oとネットワーク帯域を激しく消費します。さらに注意すべきは、Vaultの安全設計(フェイルセーフ機構)です。ディスクフルやログフォワーダーのハングなどにより監査デバイスの書き込みがブロックされると、Vaultは情報漏洩を防ぐためにすべてのリクエストの受付を拒否します。そのため、ログをリアルタイムのアラート用途として利用することには大きなリスクが伴います。

3. PrometheusによるネイティブTelemetry

  • メリット:軽量かつ安全です。メトリクスはメモリ上で直接集計され、Prometheusによる定期的なスクレイピング(通常15秒〜30秒間隔)を待つだけです。Unseal状態、p99レイテンシの分布、期限切れ間近のリース数、さらにはRaftバックエンドのスナップショット状態まで、システムの死活に関わるあらゆる指標を把握できます。
  • デメリット:機微なメトリクスが意図せずインターネット上に公開されないよう、Prometheusが安全にデータを収集できる適切なアクセス制御を設計する必要があります。

本番環境におけるベストプラクティス構成

実際の運用経験から言えば、最も推奨される構成はPrometheus + GrafanaによるネイティブTelemetryを主軸の監視基盤とし、VPC外部からのシンプルなHTTPチェックジョブをネットワーク障害検知用のフォールバックとして併用する構成です。

以前、統合ダッシュボードを導入していなかった頃、冷や汗をかくようなインシデントを経験しました。あるワーカーノードが再起動した後にVaultがsealed状態(ロック状態)になり、そのことに誰も気付かないまま3日間放置されてしまったのです。その後、アクティブノードの高負荷に伴うフェイルオーバーが発生した際、切り替え先のスタンバイノードがunsealされていなかったため、決済システム全体がダウンしてしまいました。PrometheusのメトリクスをもとにSlackへアラートを通知する仕組みがあれば、初動の1分で防げたトラブルでした。

実践導入ステップ

ステップ1:HashiCorp VaultでTelemetryを有効化する

クラスタ内の各Vaultノード(通常はIntegrated Storage – Raftを採用した3ノードまたは5ノードのクラスタ)にSSH接続し、設定ファイルを開きます。

sudo nano /etc/vault.d/vault.hcl

telemetryブロックを追加し、内部ネットワークからのメトリクスエンドポイントへの未認証アクセスを許可します。

telemetry {
  prometheus_retention_time = "30s"
  disable_hostname          = true
}

# 内部接続を受け付けるリスナー設定
listener "tcp" {
  address         = "0.0.0.0:8200"
  cluster_address = "0.0.0.0:8201"
  tls_disable     = 0
  tls_cert_file   = "/etc/vault.d/tls/vault.crt"
  tls_key_file    = "/etc/vault.d/tls/vault.key"
  
  # トークンなしでのメトリクスアクセスを有効化(プライベートサブネット内でのみ安全)
  telemetry {
    unauthenticated_metrics_access = true
  }
}

ファイルを保存し、トラフィックを中断させずにVaultプロセスをリロードします。

sudo systemctl reload vault
# ノードローカルからcurlで疎通テスト
curl -k https://127.0.0.1:8200/v1/sys/metrics?format=prometheus

複数のサーバーを複雑な設定で管理していると、HCL、JSON、PrometheusのYAMLフォーマット間で構文の混乱が起きがちです。構文チェックやフォーマットの相互変換を素早く行いたい場合は、ToolCraftのYAML ↔ JSON ConverterやJSON Formatterを活用すると便利です。ブラウザ上のJavaScriptのみで完結して動作するため、機密データが外部サーバーへ送信される心配もありません。

ステップ2:PrometheusのScrape Jobを設定する

prometheus.ymlにスクレイプターゲットの設定を追加します。アクティブノードとスタンバイノードの両方を漏れなく監視できるよう、クラスタ内の全ノードをリストアップしてください。

scrape_configs:
  - job_name: 'hashicorp_vault'
    metrics_path: '/v1/sys/metrics'
    params:
      format: ['prometheus']
    scheme: 'https'
    tls_config:
      insecure_skip_verify: true # プライベートCAを使用している場合はca_fileに変更
    static_configs:
      - targets:
          - '10.0.1.10:8200'
          - '10.0.1.11:8200'
          - '10.0.1.12:8200'

設定ファイルの構文を検証した後、Prometheusサービスをリロードします。

promtool check config /etc/prometheus/prometheus.yml
curl -X POST http://localhost:9090/-/reload

ステップ3:GrafanaでPromQLクエリを作成しダッシュボードを構築する

Grafanaを開いて新規ダッシュボードを作成し、特に重要な以下の3つのメトリクスグループに焦点を当てて可視化します。

1. Unseal状態とノードロール(Active/Standby)

メトリクスvault_core_unsealedは、正常であれば1、ノードがロック状態(sealed)であれば0を返します。Statパネルを用いて次のクエリを設定します。

vault_core_unsealed{job="hashicorp_vault"}

書き込み処理を担当するLeaderノードを特定するには、以下のクエリを使用します。

vault_core_active{job="hashicorp_vault"}

正常なクラスタでは、このメトリクスで値1を返すノードが常に1台のみ存在する必要があります。

2. リクエストレイテンシ(処理遅延)の計測

シークレットエンジンのレスポンス低下は、アプリケーションの起動遅延やAPI全体の処理時間増大に直結します。以下のクエリは、直近5分間における平均リクエスト処理時間を算出します。

rate(vault_core_handle_request_sum[5m]) / rate(vault_core_handle_request_count[5m])

通常は5ms〜15ms程度ですが、レイテンシが継続して100msを超える場合は、Raftデータを格納しているストレージのIOPS枯渇や、ノード間のネットワーク輻輳を直ちに調査してください。

3. トークンリークとアクティブリースの監視

トークンリークは、Vaultのメモリを枯渇させる最も典型的な原因です。マイクロサービスのPod群が新しいトークンを継続的に取得しながらも、それらを破棄(revoke)せず再利用もしない場合に発生します。Time Seriesパネルで以下の2つのメトリクスを注視してください。

# システム内でアクティブなリースの総数
vault_expire_num_leases

# 現在有効なトークン数
vault_token_count

vault_expire_num_leasesが階段状に右肩上がりで増加し、10万件を超えても減少傾向が見られない場合は、アプリケーション側でトークンリークが発生しているか、TTLが過剰に長く設定されている可能性が高いと言えます。

ステップ4:Alertmanagerによるアラートルールの設定

障害が発生してからGrafanaを開くのでは手遅れです。異常を検知した瞬間にSlackやTelegramへ即座に通知するようアラートを設定しましょう。

groups:
  - name: vault_alerts
    rules:
      - alert: VaultNodeSealed
        expr: vault_core_unsealed == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "VaultノードがSealed状態です: {{ $labels.instance }}"
          description: "ノード {{ $labels.instance }} が1分以上Sealed状態のままです。直ちにSSH接続してUnsealを実施してください。"

      - alert: VaultHighRequestLatency
        expr: (rate(vault_core_handle_request_sum[5m]) / rate(vault_core_handle_request_count[5m])) > 0.1
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Vaultのレイテンシが高騰しています(>100ms)"
          description: "{{ $labels.instance }} の平均応答時間が過去5分間にわたり100msを超過しています。"

Unseal状態、読み書きレイテンシ、そしてトークンリースの増加傾向をしっかりと抑えておくことで、HashiCorp Vaultクラスタにおける予期せぬダウンタイムリスクの95%を未然に排除できます。

Share: