- Authors

- Name
- Youngju Kim
- @fjvbn20031
- はじめに
- 1. KubeVirtはdrainを直ちにkillとして処理しない
- 2. EvictionRequestedとEvacuationNodeNameは運用者が必ず確認すべき
- 3. ライブマイグレーション不可の理由を事前にreasonとして残す
- 4. MigrationStateは障害分析の中心軸である
- 5. pre-copyは失敗しても回復の余地があるが、post-copyはより危険
- 6. abortも一つの状態マシンである
- 7. マイグレーション障害はコントロールプレーンとデータプレーンの両方で発生する
- 8. セキュリティ機能はマイグレーションの柔軟性と衝突することが多い
- 9. マイグレーション中の複数Pod存在は障害分析をより困難にする
- 10. drain運用戦略はワークロード特性に応じて変えるべき
- 運用者が覚えるべき要点
- まとめ
はじめに
運用の観点から、KubeVirtの本当の難しさはVMを起動する瞬間ではなく、障害を扱う瞬間に現れる。Podは再スケジューリングすれば済むことが多いが、VMはメモリ状態、ディスク、ネットワークセッション、ゲストの実行コンテキストまで一緒に考慮する必要がある。そのためdrainとeviction、マイグレーション障害はKubeVirtの内部設計を最もよく示す場面である。
本記事では「何が障害と見なされるか」と「障害をKubeVirtがどう標準化して表面化するか」を見ていく。
1. KubeVirtはdrainを直ちにkillとして処理しない
API型のEvictionStrategyアノテーションを見ると、node drainの状況でどの戦略を使うか定義されている。つまりKubeVirtはdrainを単純なKubernetes evictionイベントとして見ず、VM専用のポリシー判断が必要なイベントとして扱っている。
その理由は明確である。
- migratableであればまず移すほうがよい。
- non-migratableであれば中断や保留が必要かもしれない。
- 外部コントローラが所有するVMであれば別の処理モデルが必要かもしれない。
つまりKubeVirtにおいてdrainは「Pod一つを空ける」ことではなく、「このVMをどの方法で退避させるか」という問いである。
2. EvictionRequestedとEvacuationNodeNameは運用者が必ず確認すべき
VirtualMachineInstanceStatusにはEvacuationNodeNameがあり、conditionタイプにはEvictionRequestedが定義されている。これはevictionが単なるイベントログに残るだけでなく、VMI statusに構造化されたシグナルとして残ることを意味する。
運用者がこの値を見るべき理由は以下の通り。
- drainが始まったか
- どのノードからevacuateしようとしているか
- その後マイグレーションが続くべきか
- 外部コントローラがフォローアップアクションを取るべきか
つまりKubeVirtはdrainをstatus-first方式で表面化する。
3. ライブマイグレーション不可の理由を事前にreasonとして残す
KubeVirt API型にはnon-migratable reasonが非常に多く定義されている。
DisksNotLiveMigratableInterfaceNotLiveMigratableHotplugNotLiveMigratableVirtIOFSNotLiveMigratableHostDeviceNotLiveMigratableSEVNotLiveMigratableSecureExecutionNotLiveMigratableTDXNotLiveMigratableHypervPassthroughNotLiveMigratablePersistentReservationNotLiveMigratable
この設計が優れているのは、障害を事後のランタイムエラーとしてのみ見ないからである。KubeVirtはcondition reasonで事前に「なぜこのVMは移行できないか」を伝える。
つまり運用者はマイグレーションを発行して障害ログを待つ前に、API状態だけで大まかな制約を読み取ることができる。
4. MigrationStateは障害分析の中心軸である
VirtualMachineInstanceMigrationStateには障害分析に必要な情報が多く含まれている。
- ソースノードとソースPod
- ターゲットノードとターゲットPod
- 同期アドレス
- ダイレクトマイグレーションポート
- 完了状態
- 失敗状態
- 中断リクエスト状態
- 中断ステータス
- 障害理由
- 現在のマイグレーションモード
この構造を見ると、KubeVirtがマイグレーションを単純なブーリアン状態として見ていないことがわかる。マイグレーションはソースとターゲットが時間と共に変わる分散プロトコルであり、障害も複数の段階で発生する。
5. pre-copyは失敗しても回復の余地があるが、post-copyはより危険
前の記事で見たように、pre-copyはソースに元のメモリが残った状態で段階的に転送する。一方、post-copyはターゲットが先に実行を開始し、必要なページを後からソースから取得する。
そのためpost-copy障害ははるかに危険である。pkg/virt-handler/vm.goにはformatIrrecoverableErrorMessageがあり、post-copy障害でdomainがpaused状態になると「VMI is irrecoverable due to failed post-copy migration」というメッセージが生成される。
これは非常に強いシグナルである。単にマイグレーションジョブが失敗したのではなく、実行中のVM状態自体が回復不可能な方向に崩壊する可能性があることを意味する。
つまりpost-copyは忙しいワークロードを移すための強力なツールだが、障害コストもより大きい。
6. abortも一つの状態マシンである
VirtualMachineInstanceMigrationStateにはAbortRequestedとAbortStatusがあり、abort状態もSucceeded、Failed、Abortingと別途モデル化されている。
この設計は現実的である。マイグレーション中断はボタン一つ押せばすぐ終わる作業ではない。
- まだ中断可能な段階か
- すでにターゲットがハンドオフを受けたか
- ストレージやネットワークのサイドエフェクトがどこまで進んだか
によって結果が変わる。つまりKubeVirtはabortも通常のAPIキャンセルではなく、別の状態マシンとして扱う。
7. マイグレーション障害はコントロールプレーンとデータプレーンの両方で発生する
障害原因を大きく分けると二つある。
コントロールプレーン側の障害
- ターゲットPodがスケジュールされない
- 適切なnode selectorを満たせない
- クォータやポリシーに引っかかる
- ユーティリティボリュームやバックアップによりブロックされる
データプレーン側の障害
- ダーティページ率が高すぎてpre-copyが収束しない
- post-copy切り替え後にソースとターゲットの同期が壊れる
- マイグレーションソケットまたはプロキシ経路の問題
- ターゲットでのドメイン準備が遅い
つまり「migration failed」の一行だけでは不十分で、どのプレーンで障害が起きたかを分けて見る必要がある。
8. セキュリティ機能はマイグレーションの柔軟性と衝突することが多い
API レベルですでに明らかなように、SEV、Secure Execution、TDX、ホストデバイスパススルーなどの機能はマイグレーション制約と頻繁に衝突する。
これは偶然ではない。これらの機能は大体次のいずれかを要求する。
- 特定のホストハードウェアとの強い結合
- ゲストメモリの特殊な保護方式
- 外部から再現しにくいデバイス状態の使用
つまりセキュリティを強化したりハードウェア性能を最大化するほど、「どのノードにでも無停止移動」という特性と衝突しやすくなる。
9. マイグレーション中の複数Pod存在は障害分析をより困難にする
ActivePodsがなぜ重要かは障害モードでより明確になる。マイグレーション中はソースとターゲットのlauncher Podが一時的に共存するため、ログや状態を見るときにどのPodが本当の現在のソースか混乱しやすい。
障害を見るときは最低限以下を一緒に見る必要がある。
- VMIの
activePods - マイグレーションCRフェーズ
- ターゲットPod名
- ソースPod名
- VMIの
migrationState
この情報を照合しなければ、すでにクリーンアップされたPodのログを見て現在の問題だと誤解しやすい。
10. drain運用戦略はワークロード特性に応じて変えるべき
すべてのVMに同じeviction strategyを適用してはいけない。例えば:
- ステートレスに近いテストVM
- SR-IOVとホストデバイスを使うパフォーマンス敏感なVM
- RWXボリュームとライブマイグレーションが可能な一般業務VM
- post-copy許可の可否が重要なメモリwrite-intensive VM
は障害コストと許容可能な対処が全く異なる。
つまりdrain戦略はインフラのデフォルトではなく、VM特性に合わせた運用ポリシーであるべきである。
運用者が覚えるべき要点
- drainはPod除去ではなくVM退避戦略の問題である。
EvictionRequested、EvacuationNodeName、MigrationStateを一緒に見る必要がある。- non-migratable reasonは障害後のログではなく、事前判断シグナルである。
- post-copy障害はirrecoverable状態につながる可能性があるため、はるかに慎重に扱う必要がある。
まとめ
KubeVirtは障害を隠さず状態マシンとして構造化する。drainはeviction戦略と連携し、ライブマイグレーション可否はcondition reasonで事前に表面化され、実際のマイグレーション進行状況と障害理由はMigrationStateに蓄積される。特にpost-copy障害をirrecoverableとして分離した点は、KubeVirtがVM障害を単純なPod再起動問題とは異なる視点で見ていることをよく示している。
次の記事ではシリーズを締めくくりながら、KubeVirtソースコードをどの順序で読めばこの全体構造を最速で理解できるか、ソース読み取りマップを整理する。