- Authors

- Name
- Youngju Kim
- @fjvbn20031
- はじめに
- 1. VMI statusは最も重要な運用面である
- 2. phaseだけでは不十分でconditionsを一緒に見る必要がある
- 3. activePodsはマイグレーション時に特に重要
- 4. ネットワーク状態はPodアノテーションとゲスト情報が合わさる
- 5. ゲストエージェントはゲスト内部情報を引き出す窓口
- 6. domain statsはホスト可観測性とゲスト可観測性の中間層
- 7. Prometheusメトリクスはvirt-handlerから多く出る
- 8. ゲストエージェントがないと何が減るか
- 9. デバッグはコントロールプレーン、ノード、ゲストを分けて見るべき
- 10. statusは常にすぐに真実を反映するわけではない
- 運用者が覚えるべき要点
- まとめ
はじめに
KubeVirtを運用していると最も難しい質問はこれである。「今このVMは本当にどこまで生きているか?」PodはRunningなのにゲストは止まっているかもしれないし、ゲストは生きていてもマイグレーションが失敗寸前かもしれない。そのためKubeVirtは状態を一箇所ではなく複数の層で収集する。
- Kubernetesオブジェクト状態
- libvirtドメイン状態
- ゲストエージェントが教えてくれるゲスト内部情報
- ネットワークstatusとマイグレーションstatus
- Prometheusメトリクス
本記事ではこの観測レイヤーがどうつながるかを見る。
1. VMI statusは最も重要な運用面である
staging/src/kubevirt.io/api/core/v1/types.goのVirtualMachineInstanceStatusを見ると運用者が見たい情報がかなり多く含まれている。
phaseconditionsinterfacesguestOSInfomigrationStateqosClassactivePodsselinuxContextmemorycurrentCPUTopology
この型を読むだけでKubeVirtが状態を単に「オンまたはオフ」で見ていないことがわかる。VM状態はKubernetesフェーズとゲスト内部情報、マイグレーション進捗度、ネットワークインターフェース状態が合わさった結果である。
2. phaseだけでは不十分でconditionsを一緒に見る必要がある
phaseは上位の流れを要約する。Pending、Scheduling、Scheduled、Running、Succeeded、Failed、Unknownのような値は大きな方向を示す。
しかし実際の運用判断はconditionsとreason、messageから来る。API型には以下のようなconditionとreasonが事前定義されている。
LiveMigratableStorageLiveMigratableMigrationRequiredEvictionRequestedDataVolumesReadyDisksNotLiveMigratableInterfaceNotLiveMigratableHostDeviceNotLiveMigratableSEVNotLiveMigratableSecureExecutionNotLiveMigratable
つまり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.goのDomainManagerインターフェースを見るとゲスト関連メソッドがかなり多い。
GetGuestInfoGetUsersGetFilesystemsGetGuestOSInfoGuestPing
これは重要なシグナルである。KubeVirtはlibvirtとQEMUレベルの状態だけでは不十分と考え、ゲストエージェントを通じてOS内部の情報を別途収集している。
pkg/virt-handler/rest/lifecycle.goはこのデータをlauncherクライアントを通じて受け取りAPIレスポンスとして出力する。つまり運用者が見るゲスト情報は結局:
- virt-handler RESTエンドポイント
- launcherクライアントRPC
- virt-launcher内部ドメインマネージャー
- QEMUゲストエージェント
を経由した結果である。
6. domain statsはホスト可観測性とゲスト可観測性の中間層
同じDomainManagerインターフェースにはGetDomainStatsとGetDomainDirtyRateStatsもある。これはゲストエージェントとは別に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 conditionsmigrationStateactivePods- イベントと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だけでは不十分である。conditions、reason、migrationStateを一緒に見る必要がある。activePodsはマイグレーション中のソースとターゲットPodを読むのに重要。- ネットワーク状態はMultus、ドメイン、ゲストエージェント情報が合わさった結果。
- ゲストエージェントとdomain statsは互いの代替ではなく補完関係。
まとめ
KubeVirtの可観測性は単一の状態値ではなく複数レイヤーの情報を合わせて作られる。VMI statusはKubernetesリソース観点の現在状態を示し、ゲストエージェントはゲスト内部の意味を明らかにし、domain statsとPrometheusメトリクスは実際の実行データプレーンを観察可能にする。そのためKubeVirt運用は「VMが起動したか」を問う作業より、「どのレイヤーでどのシグナルが壊れたか」を区別する作業に近い。
次の記事では、この観測モデルを基に、drain、eviction、マイグレーション障害、non-migratable conditionなどの実際の障害モードを整理する。