Skip to content
Published on

VMI status、メトリクス、ゲストエージェント、デバッグ:KubeVirtは内部状態をどう見せるか

Authors

はじめに

KubeVirtを運用していると最も難しい質問はこれである。「今このVMは本当にどこまで生きているか?」PodはRunningなのにゲストは止まっているかもしれないし、ゲストは生きていてもマイグレーションが失敗寸前かもしれない。そのためKubeVirtは状態を一箇所ではなく複数の層で収集する。

  • Kubernetesオブジェクト状態
  • libvirtドメイン状態
  • ゲストエージェントが教えてくれるゲスト内部情報
  • ネットワークstatusとマイグレーションstatus
  • Prometheusメトリクス

本記事ではこの観測レイヤーがどうつながるかを見る。

1. VMI statusは最も重要な運用面である

staging/src/kubevirt.io/api/core/v1/types.goVirtualMachineInstanceStatusを見ると運用者が見たい情報がかなり多く含まれている。

  • phase
  • conditions
  • interfaces
  • guestOSInfo
  • migrationState
  • qosClass
  • activePods
  • selinuxContext
  • memory
  • currentCPUTopology

この型を読むだけでKubeVirtが状態を単に「オンまたはオフ」で見ていないことがわかる。VM状態はKubernetesフェーズとゲスト内部情報、マイグレーション進捗度、ネットワークインターフェース状態が合わさった結果である。

2. phaseだけでは不十分でconditionsを一緒に見る必要がある

phaseは上位の流れを要約する。Pending、Scheduling、Scheduled、Running、Succeeded、Failed、Unknownのような値は大きな方向を示す。

しかし実際の運用判断はconditionsreasonmessageから来る。API型には以下のようなconditionとreasonが事前定義されている。

  • LiveMigratable
  • StorageLiveMigratable
  • MigrationRequired
  • EvictionRequested
  • DataVolumesReady
  • DisksNotLiveMigratable
  • InterfaceNotLiveMigratable
  • HostDeviceNotLiveMigratable
  • SEVNotLiveMigratable
  • SecureExecutionNotLiveMigratable

つまりKubeVirtは「できない」とだけ言うのではなく、なぜライブマイグレーションができないかまで型システムに標準化している。

3. activePodsはマイグレーション時に特に重要

VirtualMachineInstanceStatus.ActivePodsはPod UIDとノード名のマッピングである。コメントにも書かれている通り、マイグレーション中は一つのVMIに複数のPodが同時にかかる場合がある。

このフィールドは「現在どのvirt-launcher Podがソースでターゲットか」を読むのに重要である。実際の運用でマイグレーションタイミングの混乱は大部分ここから始まる。単一VMだと思っていたが、コントロールプレーンの立場からはソースlauncherとターゲットlauncherが同時に存在する短い区間があるからである。

つまりactivePodsはマイグレーションデバッグにおける隠れた重要フィールドである。

4. ネットワーク状態はPodアノテーションとゲスト情報が合わさる

pkg/network/controllers/vmi.goを見るとVMI statusのinterfacesは一箇所からだけ来るのではない。

  • Multusネットワークstatusからpodインターフェース名を読み
  • プライマリとセカンダリインターフェースを計算し
  • 既存statusの中でspecにない項目も保存する

また API型のVirtualMachineInstanceNetworkInterfaceには以下が含まれる。

  • ゲストIP
  • MAC
  • ネットワーク名
  • Podインターフェース名
  • VM内部インターフェース名
  • info source

特にinfoSourceはこの情報がゲストエージェントから来たか、ドメインから来たか、multus-statusから来たかを区別する。この設計のおかげで運用者は「このIPはゲスト内部から報告された値か、CNIが報告した値か」を見分けられる。

5. ゲストエージェントはゲスト内部情報を引き出す窓口

pkg/virt-launcher/virtwrap/manager.goDomainManagerインターフェースを見るとゲスト関連メソッドがかなり多い。

  • GetGuestInfo
  • GetUsers
  • GetFilesystems
  • GetGuestOSInfo
  • GuestPing

これは重要なシグナルである。KubeVirtはlibvirtとQEMUレベルの状態だけでは不十分と考え、ゲストエージェントを通じてOS内部の情報を別途収集している。

pkg/virt-handler/rest/lifecycle.goはこのデータをlauncherクライアントを通じて受け取りAPIレスポンスとして出力する。つまり運用者が見るゲスト情報は結局:

  • virt-handler RESTエンドポイント
  • launcherクライアントRPC
  • virt-launcher内部ドメインマネージャー
  • QEMUゲストエージェント

を経由した結果である。

6. domain statsはホスト可観測性とゲスト可観測性の中間層

同じDomainManagerインターフェースにはGetDomainStatsGetDomainDirtyRateStatsもある。これはゲストエージェントとは別にlibvirtが報告するドメインレベル統計を引き出すことを意味する。

この階層はゲスト内部でエージェントが応答しなくてもまだ見られる情報が多い。

  • CPU使用量
  • メモリ状態
  • ブロックI/O
  • ネットワークトラフィック
  • ダーティページ率

つまりゲストエージェントはゲスト内部の意味を教え、domain statsはハイパーバイザーが観察した実行事実を教える。両者は競合関係ではなく相互補完関係である。

7. Prometheusメトリクスはvirt-handlerから多く出る

pkg/monitoring/metrics/virt-handler/domainstatsを見ると、CPU、メモリ、ブロック、vcpuなどのドメイン統計をPrometheusメトリクスに変換するcollectorがある。

この構造はかなり現実的である。

  • 実際のVMプロセスに最も近い場所はノードである。
  • ノードからdomain statsを収集するのが最も容易である。
  • そのためメトリクスexportもvirt-handlerに近く付く。

つまりKubeVirtの可観測性は中央controllerよりnode-localエージェントでより多くの実行事実を収集する構造に近い。

8. ゲストエージェントがないと何が減るか

ゲストエージェントがなくてもVMが起動しないわけではない。しかし運用者が見られる意味のある情報がかなり減る。

  • ゲスト内部ユーザーリスト
  • ファイルシステムリスト
  • OS pretty name
  • インターフェース名と一部のゲストIP情報

つまりゲストエージェントは必須のブート依存関係ではなく、運用可視性と自動化を豊かにする拡張レイヤーである。

そのため「Podは正常なのにVM内部が見えない」という状況ではゲストエージェントのインストールと接続状態をまず疑うべきである。

9. デバッグはコントロールプレーン、ノード、ゲストを分けて見るべき

KubeVirt問題を見るとき最もよくある間違いはレイヤーを混ぜることである。次のように分けて見るほうがよい。

コントロールプレーンで見ること

  • VMI phase
  • conditions
  • migrationState
  • activePods
  • イベントとmigration CR状態

ノードで見ること

  • virt-handlerログ
  • virt-launcherログ
  • libvirtドメイン状態
  • domain stats
  • Podネットワークとtap状態

ゲストで見ること

  • QEMUゲストエージェント応答の有無
  • ゲストOS info
  • ユーザー
  • ファイルシステム
  • 実際のサービスヘルス

つまりKubeVirtデバッグは結局「どのレイヤーのtruthを見ているか」を区別する作業である。

10. statusは常にすぐに真実を反映するわけではない

API型コメントにすでに書かれている通り、VirtualMachineInstanceStatusは実際のシステム状態を後追いする場合がある。これは非常に重要な運用ポイントである。

なぜならstatusはinformer、controller、launcher、libvirt、ゲストエージェントを経て更新されるからである。したがって非常に短い瞬間には:

  • Podはすでに変わったがstatusが遅れる場合がある
  • マイグレーションターゲットは立ち上がったがphaseがまだ以前の値の場合がある
  • ゲストエージェントは死んでいるがドメインはRunningの場合がある

つまりKubeVirtは強い一貫性ではなく、複数の観測面を組み合わせて判断すべきシステムである。

運用者が覚えるべき要点

  • phaseだけでは不十分である。conditionsreasonmigrationStateを一緒に見る必要がある。
  • activePodsはマイグレーション中のソースとターゲットPodを読むのに重要。
  • ネットワーク状態はMultus、ドメイン、ゲストエージェント情報が合わさった結果。
  • ゲストエージェントとdomain statsは互いの代替ではなく補完関係。

まとめ

KubeVirtの可観測性は単一の状態値ではなく複数レイヤーの情報を合わせて作られる。VMI statusはKubernetesリソース観点の現在状態を示し、ゲストエージェントはゲスト内部の意味を明らかにし、domain statsとPrometheusメトリクスは実際の実行データプレーンを観察可能にする。そのためKubeVirt運用は「VMが起動したか」を問う作業より、「どのレイヤーでどのシグナルが壊れたか」を区別する作業に近い。

次の記事では、この観測モデルを基に、drain、eviction、マイグレーション障害、non-migratable conditionなどの実際の障害モードを整理する。