Kubernetes上のLonghorn監視:PrometheusとGrafanaの構築および実践的トラブルシューティング

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

ストレージクラスタが静かに「ストライキ」を起こすとき

Kubernetes上でPostgreSQL、MySQL、Kafkaなどを運用する際、常に課題となるのがストレージの選定です。多くのチームにとって、Longhornは最有力候補の一つでしょう。この分散ブラックスストレージソリューションはHelm経由で手軽にインストールでき、直感的な管理UIを備え、ノード停止時にもレプリカを自動で再構築してくれます。

しかし、分散ストレージには危険な落とし穴があります。それは「サイレントに障害が進行する」という点です。Podがクラッシュすれば、Lensやk9sですぐに異常を検知できます。しかし、レプリカが1つ失われてLonghornボリュームがdegraded状態になっても、アプリケーションは通常どおり読み書きを継続できてしまいます。すべて順調に見えていても、2台目のノードに障害が発生した瞬間、ボリューム全体がFaulted状態へ転落します。その結果、データベースは停止し、データへのアクセスが完全に遮断されてしまいます。

もう一つのリスクはDisk I/Oのボトルネックです。書き込みレイテンシが3msから250msへと跳ね上がり、データベースが停滞しているにもかかわらず、ノードのCPUやRAM使用率は正常値(グリーン)のままというケースです。安定運用を実現するには、クラスタ構築直後からLonghornに特化した監視環境を整えておく必要があります。

Longhornはどのようにメトリクスを出力するのか?

Longhorn managerは各ノード上でDaemonSetとして動作しています。このコンポーネントはPrometheus標準に準拠した/metricsエンドポイントをポート9500で公開しています。監視ダッシュボードに組み込むべき最重要メトリクス群は以下の4つです:

  • Volume Robustness(堅牢性):メトリクスlonghorn_volume_robustnessはボリュームの健全性を表します。値1はHealthy(レプリカが正常)、2はDegraded(レプリカ欠落・再構築中)、3はFaulted(完全破損・マウント不可)を意味します。
  • レプリカの状態:longhorn_replica_stateとlonghorn_node_storage_capacity_bytesを組み合わせることで、ディスク容量不足や内部ネットワーク障害によるレプリカ切断を迅速に検知できます。
  • 読み書きパフォーマンス(IOPS & スループット):longhorn_volume_read_ops、longhorn_volume_write_ops、およびバイトレートメトリクスにより、物理ディスクを圧迫しているワークロードを特定できます。
  • オーバープロビジョニング率:Longhornはデフォルトで最大200%のオーバープロビジョニングを許可しています。物理SSDが1TBの場合、最大2TB分のPVCを割り当て可能です。各サービスが一斉に書き込みを行い合計1TBを超えると、OSからアラートが上がる前にクラスタ全体のディスク容量が枯渇してしまいます。

実践:Prometheus OperatorによるLonghorn監視の設定

クラスタにkube-prometheus-stackが導入済みであれば、以下の3ステップでメトリクスのスクレイピングとアラート設定を自動化できます。

ステップ1:Longhorn Manager用のServiceMonitorを作成

longhorn-servicemonitor.yamlを作成し、Prometheusがlonghorn-system名前空間から30秒間隔でメトリクスを収集できるように指定します:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: longhorn-prometheus-servicemonitor
  namespace: longhorn-system
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app: longhorn-manager
  namespaceSelector:
    matchNames:
      - longhorn-system
  endpoints:
  - port: manager
    path: /metrics
    interval: 30s
    scrapeTimeout: 10s

マニフェストを適用します:

kubectl apply -f longhorn-servicemonitor.yaml

約1分待機した後、PrometheusのUIを開いてlonghorn_volume_actual_size_bytesを検索してみてください。グラフ上にデータが描画されれば、パイプラインは正常に機能しています。

ステップ2:Grafanaダッシュボードの導入

ダッシュボードをゼロから自作する必要はありません。Longhornコミュニティから完成度の高いテンプレートが公開されています。

  1. Grafanaにアクセスし、メニューからDashboards > New > Importを選択します。
  2. ダッシュボードIDに13032(Longhorn公式概要)または13437を入力し、Loadをクリックします。
  3. 対象クラスタのPrometheusデータソースを選択し、Importを実行します。

このダッシュボードにより、実際の使用容量と割り当て容量の比較、各ボリュームのリアルタイムRead/Write IOPSグラフ、障害が発生しているレプリカの一覧などを即座に把握できます。

ステップ3:障害を防ぐアラートルールの設定

ダッシュボードは能動的に確認する際に役立ちますが、深夜2時の障害からシステムを救うのは自動アラートです。longhorn-alerts.yamlを作成します:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: longhorn-alerts
  namespace: longhorn-system
  labels:
    release: prometheus
spec:
  groups:
  - name: longhorn.rules
    rules:
    - alert: LonghornVolumeDegraded
      expr: longhorn_volume_robustness == 2
      for: 10m
      labels:
        severity: warning
      annotations:
        summary: "ボリューム {{ $labels.volume }} がDegraded状態です"
        description: "ボリューム {{ $labels.volume }} のレプリカが1つ以上欠落した状態が10分以上続いています。ディスクまたはストレージノードを確認してください。"

    - alert: LonghornVolumeFaulted
      expr: longhorn_volume_robustness == 3
      for: 1m
      labels:
        severity: critical
      annotations:
        summary: "ボリューム {{ $labels.volume }} でFAULTEDが発生しました!"
        description: "ボリュームの全レプリカが失われたか、マウントできません。データアクセスが停止しています!"

    - alert: LonghornDiskUsageHigh
      expr: (longhorn_node_storage_usage_bytes / longhorn_node_storage_capacity_bytes) * 100 > 85
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "ノード {{ $labels.node }} のディスク使用率が85%を超過しました"
        description: "ノード {{ $labels.node }} のLonghorn使用容量が {{ $value | printf `%.1f` }}% に達しました。ディスクの追加またはスナップショットのクリーンアップが必要です。"

ルールをクラスタにデプロイします:

kubectl apply -f longhorn-alerts.yaml

実践ノウハウ:誤検知を防ぐチューニング

1. ノード再起動に伴うアラート疲れ(Alert Fatigue)の防止

運用初期には、longhorn_volume_robustness == 2のアラート発動条件を「1分後」に設定してしまいがちです。その結果、ローリングアップデートやカーネルパッチ適用でワーカーノードを再起動するたびに、50GBのボリューム再同期に3〜7分を要し、TelegramやSlackに不要なアラートが乱発することになります。

解決策としては、warningレベルの遅延条件for:を10m〜15m程度に引き上げることです。10分経過しても再同期が完了しない場合は、不良セクタ、ネットワーク断片化、ファイルシステムのリードオンリー化など、物理的・本格的なトラブルが発生していると判断できます。

2. IOPSメトリクスによるNoisy Neighborの検知

APIのレスポンスタイムが突如悪化した際、CPU使用率の確認だけで終わらせてはいけません。GrafanaのIOPSタブを開き、以下のPromQLクエリを実行します:

topk(5, rate(longhorn_volume_read_ops[5m]) + rate(longhorn_volume_write_ops[5m]))

このクエリにより、I/Oリソースを最も消費している上位5つのボリュームが即座に浮き彫りになります。実際、インデックスが不足した集計クエリがMySQLでフルテーブルスキャンを走らせ、3,500 IOPSを消費し続けただけで、同一ノード上でSATA SSD(上限約500〜600 IOPS)を共有していた他のコンテナが全滅した事例もあります。

3. 不要な「ゾンビ」スナップショットの抑制

Longhornの定期スナップショット(recurring snapshot)機能は強力ですが、適切な保持ポリシー(retain)を設定しないと、スナップショットデータがディスク容量を食いつぶしてしまいます。longhorn_volume_actual_size_bytesとPersistentVolumeClaim(PVC)で要求された容量を比較するグラフをダッシュボードに用意しておくと便利です。

20GBのボリュームがディスク上で実際には60GB消費している場合、古いスナップショットがパージされずに残留している可能性が高いです。定期的なsnapshot purgeを行うCronJobを導入するか、保持世代数を適切に制限(直近3〜5世代のみ保持など)して、余剰なストレージブロックを解放しましょう。

まとめ

Kubernetesにおけるストレージ運用では、曖昧な推測に頼ることは許されません。ServiceMonitor、Grafanaダッシュボード(ID: 13032)、そして適切なアラート閾値を組み合わせることで、読み書きパフォーマンス、実使用容量、レプリカの健全性を完全に可視化できます。まずはステージング環境に導入し、擬似的にノード停止を起こしてLonghornの再構築プロセスを観察した上で、本番環境へと展開することをおすすめします。

Share: