Hyper-Vの中でHyper-Vを動かす

目次

Hyper-Vの中でHyper-Vを動かす(Nested VM)にあたって、忘れていたことがあったりタグVLANの設定につまずいたりしたので設定をメモ

背景

Hyper-V上で動いているVMを一時的に別PCへ退避したかったが、ハードウェアの条件があうPCが空いていなかったため、Windows 11のHyper-V上にWindows ServerのVMを作成してライブマイグレーションを実施した。

構成

  • ホストOS: Windows 11 Pro
  • CPU: AMD CPU

CPUがAMDの場合にNested VMを行う場合はホストOSの制約がIntel CPUの場合より厳しいので注意する。

前提条件

Intel プロセッサ (VT-x/EPT テクノロジ搭載)

  • Hyper-V ホストは、Windows Server 2016 以降、または Windows 10 以降である必要があります。
  • VM 構成バージョン 8.0 以降。

AMD EPYC/Ryzen プロセッサ以降

  • Hyper-V ホストは、Windows Server 2022 以降、または Windows 11 以降である必要があります。
  • VM 構成バージョン 9.3 以降。

(引用元) 入れ子になった仮想化による仮想マシンでの Hyper-V の実行 | Microsoft Learn

手順

VMへCPUの仮想化機能を公開

Hyper-VのGUIでは設定できないため、VMをGUIで作成した後PowerShellから設定を変更する必要がある。

手順としては上記Microsoftのページに書いてある通り。

Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true

VMにVLANをタグが付いた状態で渡す

Hyper-VのGUI上からはAccessポートの設定しかできないが、PowerShellを使うことでTrunkポートの設定ができるため、タグVLAN(802.1q)を利用している場合はVMのネットワークポート設定をTrunkポートにすることで、VM内でもタグVLANを扱うことができる。

使うコマンドは Set-VMNetworkAdapterVlan でここにコマンドリファレンスがある。
Set-VMNetworkAdapterVlan (Hyper-V) | Microsoft Learn
VMに複数のNICが存在する場合、VMName のみを指定して設定するとすべてのポート設定が変更されてしまうため、以下のようにすると良い。

$adapter = Get-VMNetworkAdapter -VMName <VMName>
Set-VMNetworkAdapterVlan -VMNetworkAdapter $adapter[0] -Trunk -NativeVlanId 1 -AllowedVlanIdList "10,20,30"

MACアドレススプーフィングを許可

Hyper-V上に作成したWindows Server VMの中でさらにVM(Nested VM)を作成した場合、ホストから見るとNested VM発の通信はMACアドレスが偽装された通信に見える。
Hyper-Vのデフォルト設定ではこのような通信を落とす設定になっているため設定を変更する。

PowerShellから設定する場合は以下のようになる。

# 上記のTrunkポート設定時に取得したVMNetworkAdapterBaseを再利用
#$adapter = Get-VMNetworkAdapter -VMName <VMName>
Set-VMNetworkAdapter -VMNetworkAdapter $adapter[0] -MacAddressSpoofing On

GUIからも設定可能で、GUIから設定する場合はネットワークアダプターの「高度な機能」メニューにある「MACアドレスのスプーフィングを有効にする(E)」が該当する。

MACアドレススプーフィングを許可するGUI設定画面

おわりに

今回は少し特殊な事情でこのようなことを実施したが、同様の手段でHyper-VやESXi、Proxmox VEなどの仮想化基盤を検証したり、VMでルータを作成する場合に活用できると思う。

Hyper-Vは意外とできることが多いが、残念ながらGUIでは設定できずPowerShellやWMI頼りになってしまうことがたびたびあり少し残念である。