Nested virtualization allows you to run Hyper-V inside a virtual machine and create several more virtual machines in this nested Hyper-V server. Most often, nested virtualization is used in test environments.
Microsoft Hyper-V supports nested virtualization starting from Windows Server 2016. If you try to install the Hyper-V role inside the VM on the guest Hyper-V with Windows Server 2012 R2 (or older), you will get the install error:
Hyper-V can not be installed: The hypervisor is already running.
This error is related to the fact that the Hyper- host V specifically masked the Intel VT-x and AMD-V Virtualization Extensions from the guest OS. In Windows Server 2016, the Hyper-V architecture has been redesigned. CPU requirements have also changed. Now, for nested virtualization to work, in addition to supporting Intel VT-x, the processor must support Intel EPT (provides virtual machines memory direct access, bypassing the hypervisor).
Other limitations when using nested virtualization:
- Host and guest Hyper-V must use Windows Server 2016/2019 or Windows 10;
- Hyper-V VM hardware version >=8.0;
- For nested virtual machines the following features are nor supported; dynamic memory, dynamic migration, VM checkpoints, and Save/Restore options.
How to Enable and Use Nested Virtualization in Windows Server 2016?
First of all, you need to update the version of the Hyper-V VM configuration (vm hardware) for which you want to enable nested virtualization to 8.0 or higher (the virtual machine must be turned off). To do this, run the Hyper-V Manager console, find the VM, right-click it and select Upgrade Configuration Version.
You can also upgrade the HW version of the virtual machine through PowerShell:
Update-VMVersion -Name ‘WinSrv2016Nested’
You can update all VMs on the host at once:
Get-VM | Update-VMVersion
Now you need to enable nested virtualization support for the selected virtual machine. By default, the hypervisor masks virtualization CPU instruction that are sent to the guest. To change this behavior, use the command:
Set-VMProcessor -VMName VMName -ExposeVirtualizationExtensions $true
Because dynamic memory is not supported for nested Hyper-V, you must disable this option in the VM settings (VM > Settings > Memory > uncheck Enable Dynamic Memory).
Or you can disable dynamic memory through PowerShell:
Set-VMMemory "'WinSrv2016Nested' -DynamicMemoryEnabled $false
If you plan to provide access for nested virtual machines on an external network, the host Hyper-V can see several MAC addresses on a single network adapter of the virtual machine. Therefore, you need to enable MAC address spoofing for the VM network adapter.
Open the VM properties in the Hyper-V manager console, find the VM network adapter and in the Advanced features section enable the Enable MAC address spoofing option.
You can also enable this option via PowerShell:
Get-VMNetworkAdapter -VMName 'WinSrv2016Nested' | Set-VMNetworkAdapter -MacAddressSpoofing On
To quickly check VMs and enable nested virtualization memory, you can use a ready-made PowerShell script Enable-NestedVm.ps1. You can run it as follows:
Invoke-WebRequest https://raw.githubusercontent.com/Microsoft/Virtualization-Documentation/master/hyperv-tools/Nested/Enable-NestedVm.ps1 -OutFile ~/Enable-NestedVm.ps1 ~/Enable-NestedVm.ps1 -VmName 'WinSrv2016Nested'
Now you just have to install the Hyper-V role in the virtual machine (Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart) and you can create nested virtual machines.