English中文

ドキュメント · 1.0

ネストされた仮想化

ネストされた仮想化を使うと、仮想マシン(以下、ネストの外側の guest を「L1」と呼びます)の中でさらに仮想マシンを動かせます。Linux guest で KVM を動かしたり、Windows で Hyper-V や WSL2 を有効にしたりできます。keelOS では既定でオフで、仮想マシンごとに個別にオンにします。この章では、オンにすると何ができて何ができないか、どんな制限があるかを説明します。

1. 使えるもの

次のものは、keelOS で実際に動作を確認しています。

  • Linux guest の KVM:Debian に qemu-system-x86 を入れ、その中でさらに仮想マシン(L2)を起動。起動と停止を何度繰り返しても問題ありません。
  • Windows 10 の Hyper-V:Hyper-V を入れて再起動すると hypervisor が正常に起動し、その中で第 2 世代の仮想マシンを作って Linux を起動できます。
  • Windows 10 の WSL2:wsl --import … --version 2 でディストリビューションをインポートし、起動と停止を 10 回繰り返して、すべて成功しました。

項目ごとの確認はまだですが、原理的に同じ KVM や Hyper-V の機能に頼るものとして、Firecracker のような KVM ベースの microVM(Linux guest 内)と Docker Desktop(WSL2 または Hyper-V に依存)があります。問題があったときは、現象をお知らせください。

2. まだ使えないもの

  • AMD ホスト:hyp の上で動く Intel ホストだけが対象です。AMD ホストではこのスイッチはグレーアウトされ、横に理由が表示されます。
  • Windows の VBS、メモリ整合性(HVCI):ネストを有効にした guest で Windows の Hyper-V は起動しますが、HVCI はまだ使えません(さらに多くの CPU 機能と IOMMU 機能が必要です)。Windows 11 と Windows Server はまだ試していません。
  • ライブマイグレーション、ストレージプール間のライブ移動:ネストを有効にした仮想マシンでは、現時点では使えません(サスペンドと reload は可能です。§3 を参照。コールド移行は専用の確認をしていません)。
  • PCI パススルー:ネストとは同時に使えません。パススルーデバイスのある仮想マシンではスイッチがグレーアウトされ、ネストを有効にした仮想マシンでは PCI デバイスを追加するボタンがグレーアウトされます。
  • keelOS の Hyper-V 拡張:Windows テンプレートは通常、性能向上のために Hyper-V 拡張を guest に渡します。ネストを有効にした Windows guest は自分自身の Hyper-V を動かすので、この拡張は既定では渡されません。手作業で "hyperv": true と書くと拒否されます。
  • kcell:ネストは有効にできません。

3. サスペンド、reload、アップグレード

ホストは、ネストを有効にした仮想マシンの CPU 状態(「内側のどの仮想マシンを実行しているか」を含む)もまとめてチェックポイントに保存します。

  • サスペンドと再開は、ほかの仮想マシンと同じです。 再開後、L1 の KVM、Hyper-V、WSL2、およびその中で動いていた仮想マシンは、再起動なしにそのまま動き続けます。
  • ホストの reload 時には、サスペンドされて reload 後に再開されます。 ほかの仮想マシンと同じです。一覧では reload 時の動作が「サスペンド」と表示されます。
  • 例外:新しいバージョンが試用中のとき(アップグレード後、アップグレードを確定を押す前。アップグレードの章を参照)。このとき、ホストは古いバージョンの形式でチェックポイントを書きますが、古い形式にはこれらの状態が入りません。そのため、サスペンドできません。稼働中は、ホストの reload、再起動、スロットの切り替えが拒否され、ページ(システム → アップグレード、システム → メンテナンス)にこの仮想マシンが一覧表示され、横にオフにするボタンが付きます。一覧の reload 時の動作は「root reload 時にシャットダウン(ネストされた仮想化)」と表示され、keel vm list では poweroff (nested) と表示されます。アップグレードを確定すると、これらの制限はなくなります。
  • この種のチェックポイントを読めない古いバージョンのスロットへの切り替えは拒否されます(先にこの仮想マシンをシャットダウンしてください)。

4. 有効にする方法

Web:

  1. 仮想マシンで変更したい仮想マシンを押し、編集を押します(新規作成のときは、ウィザードの最後のステップ、または「カスタム」のデバイスのセクションです)。
  2. デバイスセクションで、この VM の中でさらに仮想マシンを動かす(ネストされた仮想化)にチェックを入れます。下に上記の制限が小さな文字で書かれています。
  3. 保存します。設定は仮想マシンの次回のコールドスタートから有効になります。稼働中の仮想マシンは、いったんシャットダウンして起動し直してください。
仮想マシンの編集ページの「デバイス」セクション:ネストされた仮想化のチェックボックスと説明
仮想マシンの編集ページの「デバイス」セクション:ネストされた仮想化のチェックボックスと説明

スイッチがグレーアウトされている場合は、横に理由が書かれています。ホストが keelOS の hyp 上で動いていない、ホストが AMD CPU である、ホストの hypervisor モジュールが古い(keelOS をアップグレードしてください)、またはこの仮想マシンに PCI パススルーデバイスがある、のいずれかです。

コマンドライン:新規作成時に --nested を付けます。既存の仮想マシンでは config.json に "nested": true と書きます。

keel vm create --alias lab --vcpus 4 --ram 8G --disk 60G --nested

keel vm list の RELOAD 列は、この種の仮想マシンでは suspend と表示されます(試用期間中は poweroff (nested)。§3 を参照)。

5. 使うときのポイント

  • L1 に十分な CPU とメモリを割り当ててください。 内側の仮想マシンのメモリは L1 のメモリから確保されます。Windows は Hyper-V を入れると、Windows 自身が Hyper-V の「ルートパーティション」になります。
  • Windows:Hyper-V のインストール後に 1 回再起動が必要です。再起動後、systeminfo に「ハイパーバイザーが検出されました」と表示されますが、これは正常です。
  • 性能:L2(内側の仮想マシン)が VM exit するたびに、root と hyp の間を約 16 回往復します。測定した規模は 1 回あたり数十マイクロ秒です(テスト機では約 32 マイクロ秒)。ページフォールトが多い負荷(コンパイル、fork が多いもの)は、ネストされた EPT により大幅に速くなります(テスト機では、fork が多い負荷はネストされた EPT なしの場合より 22 倍、ページフォールトが多い負荷は 44 倍速くなりました)。一方、VM exit が多い負荷(I/O や割り込みが多いもの)は、exit のたびにこのコストがかかるので、L1 で直接動かすより遅くなります。実験、開発、テスト環境には向いていますが、本番の仮想化基盤としては使わないでください。

6. トラブルシューティング

  • 保存時に nested virtualization and passthrough devices cannot be combined と表示される:先に PCI デバイスを外すか、ネストをオフにしてください。
  • 保存時に … the Hyper-V enlightenments cannot be combined yet と表示される:config.json に "hyperv": true が入っているので、削除してください。
  • ホストの reload またはアップグレードが runs with nested virtualization … shut it down first で拒否される:新しいバージョンがまだ試用中です(またはホストの vmm モジュールが古い)。一覧に出た仮想マシンをシャットダウンするか、先にアップグレードを確定してください。
  • L1 で kvm_intel をロードしても ept=Y にならない:ホストの vmm モジュールが新しいことを確認してください(システム → アップグレードでバージョンを確認)。

詳細とテスト記録は、設計文書 docs/69 にあります。