Activer la nested virtualization dans Windows server 2016

Inception sous Windows Server 2016

Johan Delattre

Les dernières versions de Windows Server 2016 Technical Preview permettent de réaliser de la virtualisation imbriquée.

Le but est donc d'avoir un hôte Hyper-V, contenant une VM, avec elle aussi Hyper-V, contenant encore là une VM.

Pour réagir à ce tutoriel, un espace de dialogue vous est proposé sur le forum : Commentez

- Titre : Activer la nested virtualization dans Windows server 2016

- Auteur : Johan Delattre

- Parution : 13 juin 2016

- Licence : Copyright ® 2016 Johan Delattre. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Prérequis

- III. Environnement de test

- IV. Réalisation

- V. Informations complémentaires

- VI. Conclusion

- VII. Virtualisation imbriquée

- VII-A. Configuration requise de la virtualisation imbriquée

- VII-B. Activer la virtualisation imbriquée

- VII-C. Problèmes connus

- VII-D. FAQ et résolution des problèmes

- VII-D-1. Ma machine virtuelle ne démarre pas, que dois-je faire ?

- VII-D-2. La connexion à une machine virtuelle n'est pas rétablie

- VII-D-3. Mon problème n'est pas indiqué ici

- VIII. Remerciements

I - Introduction

Les dernières versions de Windows Server 2016 Technical Preview permettent de réaliser de la virtualisation imbriquée.

Le but est donc d'avoir un hôte Hyper-V, contenant une VM, avec elle aussi Hyper-V, contenant encore là une VM.

II - Prérequis

Afin de pouvoir utiliser la « Nested Virtualization », il faut :

- Windows 2016 Build 10565 minimum ;

- 4 GB de RAM minimum par VM + la RAM pour l'hôte physique ;

- Intel VT-x activé dans le bios.

III - Environnement de test

L'environnement de test pour cet article est simplement constitué d'un serveur DELL PowerEdge R210 avec un Intel Xeon X3440 possédant 8 GB de RAM nommé PHY2016TP5

IV - Réalisation

La réalisation est simple. Tout d'abord nous installons Windows Server 2016 Technical Preview 5 sur notre machine physique.

Nous installons ensuite le rôle Hyper-V et le configurons selon nos besoins. Rien de particulier ici.

Nous allons ensuite créer une VM elle aussi installée en 2016 TP 5 (dans notre exemple VM2016TP5).

Cette VM doit avoir un minimum de 4 Go de RAM et on doit activer le MAC spoofing sur sa carte réseau si on veut qu'elle puisse avoir un accès au réseau.

Une fois la VM installée en 2016 TP5, si on tente d'installer le rôle Hyper-V, on aura une erreur, ce qui est normal, car il détecte qu'il est sur une machine virtuelle et non sur un serveur physique.

On éteint la VM.

On récupère le script de Microsoft, puis on le lance en administrateur dans une fenêtre PowerShell sur l'hôte physique :

Invoke-WebRequest https://raw.githubusercontent.com/Microsoft/Virtualization-Documentation/master/hyperv-tools/Nested/Enable-NestedVm.ps1 -OutFile ~/Enable-NestedVm.ps1

~/Enable-NestedVm.ps1 -VmName “VM2016TP5”

On peut ensuite rallumer la VM et cette fois nous pouvons installer le rôle Hyper-V et créer une autre VM dessus.

V - Informations complémentaires

Cette technologie n'est qu'un début, c'est de la preview. Elle possède d'ailleurs quelques limitations qu'il faut connaître :

- pas de mémoire dynamique pour la VM-host (dans notre exemple VM2016TP5) ;

- pas de modification de la mémoire à chaud pour la VM-Host ;

- pas de checkpoint pour la VM-Host ;

- pas de live migration pour la VM-Host ;

- pas de Save/Restore pour la VM-Host.

Cela ne fonctionne pas ? Vérifiez que votre hôte et votre VM sont capables de faire de la virtualisation imbriquée une fois le premier script appliqué.

Téléchargez simplement ce script et lancez-le :

Invoke-WebRequest https://raw.githubusercontent.com/Microsoft/Virtualization-Documentation/master/hyperv-tools/Nested/Get-NestedVirtStatus.ps1 -OutFile ~/Get-NestedVirtStatus.ps1

~/Get-NestedVirtStatus.ps1

VI - Conclusion

En conclusion, Microsoft a rendu possible la virtualisation de la virtualisation avec Hyper-V au sein de Windows Server 2016. On peut maintenant créer un serveur physique avec Hyper-V, y faire une VM, avec Hyper-V, dans laquelle on fait une autre VM, avec elle aussi Hyper-V, sur laquelle on fait une VM et ainsi de suite.

Cette technologie, combinée à celle du docker sous Windows 2016 (voir notre article IIS sous Docker grâce à Windows server 2016) nous entraîne vers une nouvelle forme de virtualisation.

VII - Virtualisation imbriquée

Source : Microsoft

Cette fonctionnalité préliminaire anticipée est uniquement disponible pour les Windows Insiders qui exécutent la Build 10565 ou version ultérieure. Elle n'inclut aucune garantie de performances ou de stabilité.

La virtualisation imbriquée exécute la virtualisation dans un environnement virtualisé. En d'autres termes, l'imbrication vous permet d'exécuter le rôle serveur Hyper-V au sein d'une machine virtuelle.

Hyper-V s'appuie sur la prise en charge de la virtualisation matérielle (par ex., Intel VT-x et AMD-V) pour exécuter des machines virtuelles. En règle générale, une fois qu'Hyper-V est installé, l'hyperviseur masque cette fonction sur les machines virtuelles invitées. Cela empêche les machines virtuelles invitées d'exécuter le rôle serveur Hyper-V sur d'autres hyperviseurs.

La virtualisation imbriquée expose les composants de prise en charge de la virtualisation matérielle à la machine virtuelle invitée.

Le diagramme ci-dessous illustre Hyper-V sans imbrication. L'hyperviseur Hyper-V prend le contrôle total des extensions de virtualisation matérielle (flèche orange) et ne les expose pas au système d'exploitation invité.

En revanche, le diagramme ci-dessous illustre Hyper-V avec imbrication. Dans ce cas, Hyper-V expose les extensions de virtualisation matérielle à ses machines virtuelles. Quand l'imbrication est activée, une machine virtuelle invitée peut installer son propre hyperviseur et exécuter ses propres machines virtuelles invitées.

VII-A - Configuration requise de la virtualisation imbriquée

Avant d'activer la virtualisation imbriquée, notez qu'il s'agit d'une version préliminaire. N'utilisez pas l'imbrication dans des environnements de production.

Configuration requise :

- 4 Go de RAM disponible au minimum. La virtualisation imbriquée nécessite une quantité de mémoire importante ;

- les deux hyperviseurs doivent être la dernière Build de Windows Insider (10565 ou supérieure). Les autres hyperviseurs ne fonctionnent pas ;

- cette fonctionnalité est actuellement exclusivement Intel. Intel VT-x est nécessaire.

VII-B - Activer la virtualisation imbriquée

1. Créez une machine virtuelle exécutant la même Build que celle de votre hôte. Instructions ici.

2. Exécutez ce script en tant qu'administrateur sur l'hôte Hyper-V :

1. param([string]$vmName)

2. #

3. # Enable-NestedVm.ps1

4. #

5. # Checks VM for nesting comatability and configures if not properly setup.

6. #

7. # Author: Drew Cross

9. if([string]::IsNullOrEmpty($vmName)) {

10. Write-Host "No VM name passed"

11. Exit;

12. }

14. # Constants

15. $4GB = 4294967296

17. #

18. # Need to run elevated.  Do that here.

19. #

21. # Get the ID and security principal of the current user account

22. $myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent();

23. $myWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($myWindowsID);

25. # Get the security principal for the administrator role

26. $adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator;

28. # Check to see if we are currently running as an administrator

29. if ($myWindowsPrincipal.IsInRole($adminRole)) {

30. # We are running as an administrator, so change the title and background colour to indicate this

31. $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)";

33. } else {

34. # We are not running as an administrator, so relaunch as administrator

36. # Create a new process object that starts PowerShell

37. $newProcess = New-Object System.Diagnostics.ProcessStartInfo "PowerShell";

39. # Specify the current script path and name as a parameter with added scope and support for scripts with spaces in it's path

40. $newProcess.Arguments = "& '" + $script:MyInvocation.MyCommand.Path + "'"

42. # Indicate that the process should be elevated

43. $newProcess.Verb = "runas";

45. # Start the new process

46. [System.Diagnostics.Process]::Start($newProcess) | Out-Null;

48. # Exit from the current, unelevated, process

49. Exit;

50. }

52. #

53. # Get Vm Information

54. #

56. $vm = Get-VM -Name $vmName

58. $vmInfo = New-Object PSObject

60. # VM info

61. Add-Member -InputObject $vmInfo NoteProperty -Name "ExposeVirtualizationExtensions" -Value $false

62. Add-Member -InputObject $vmInfo NoteProperty -Name "DynamicMemoryEnabled" -Value $vm.DynamicMemoryEnabled

63. Add-Member -InputObject $vmInfo NoteProperty -Name "SnapshotEnabled" -Value $false

64. Add-Member -InputObject $vmInfo NoteProperty -Name "State" -Value $vm.State

65. Add-Member -InputObject $vmInfo NoteProperty -Name "MacAddressSpoofing" -Value ((Get-VmNetworkAdapter -VmName $vmName).MacAddressSpoofing)

66. Add-Member -InputObject $vmInfo NoteProperty -Name "MemorySize" -Value (Get-VMMemory -VmName $vmName).Startup

69. # is nested enabled on this VM?

70. $vmInfo.ExposeVirtualizationExtensions = (Get-VMProcessor -VM $vm).ExposeVirtualizationExtensions

72. Write-Host "This script will set the following for $vmName in order to enable nesting:"

74. $prompt = $false;

76. # Output text for proposed actions

77. if ($vmInfo.State -eq 'Saved') {

78. Write-Host "\tSaved state will be removed"

79. $prompt = $true

80. }

81. if ($vmInfo.State -ne 'Off' -or $vmInfo.State -eq 'Saved') {

82. Write-Host "Vm State:" $vmInfo.State

83. Write-Host "    $vmName will be turned off"

84. $prompt = $true

85. }

86. if ($vmInfo.ExposeVirtualizationExtensions -eq $false) {

87. Write-Host "    Virtualization extensions will be enabled"

88. $prompt = $true

89. }

90. if ($vmInfo.DynamicMemoryEnabled -eq $true) {

91. Write-Host "    Dynamic memory will be disabled"

92. $prompt = $true

93. }

94. if($vmInfo.MacAddressSpoofing -eq 'Off'){

95. Write-Host "    Optionally enable mac address spoofing"

96. $prompt = $true

97. }

98. if($vmInfo.MemorySize -lt $4GB) {

99. Write-Host "    Optionally set vm memory to 4GB"

100. $prompt = $true

101. }

103. if(-not $prompt) {

104. Write-Host "    None, vm is already setup for nesting"

105. Exit;

106. }

108. Write-Host "Input Y to accept or N to cancel:" -NoNewline

110. $char = Read-Host

112. while(-not ($char.StartsWith('Y') -or $char.StartsWith('N'))) {

113. Write-Host "Invalid Input, Y or N"

114. $char = Read-Host

115. }

118. if($char.StartsWith('Y')) {

119. if ($vmInfo.State -eq 'Saved') {

120. Remove-VMSavedState -VMName $vmName

121. }

122. if ($vmInfo.State -ne 'Off' -or $vmInfo.State -eq 'Saved') {

123. Stop-VM -VMName $vmName

124. }

125. if ($vmInfo.ExposeVirtualizationExtensions -eq $false) {

126. Set-VMProcessor -VMName $vmName -ExposeVirtualizationExtensions $true

127. }

128. if ($vmInfo.DynamicMemoryEnabled -eq $true) {

129. Set-VMMemory -VMName $vmName -DynamicMemoryEnabled $false

130. }

132. # Optionally turn on mac spoofing

133. if($vmInfo.MacAddressSpoofing -eq 'Off') {

134. Write-Host "Mac Address Spoofing isn't enabled (nested guests won't have network)." -ForegroundColor Yellow

135. Write-Host "Would you like to enable MAC address spoofing? (Y/N)" -NoNewline

136. $input = Read-Host

138. if($input -eq 'Y') {

139. Set-VMNetworkAdapter -VMName $vmName -MacAddressSpoofing on

140. }

141. else {

142. Write-Host "Not enabling Mac address spoofing."

143. }

145. }

147. if($vmInfo.MemorySize -lt $4GB) {

148. Write-Host "VM memory is set less than 4GB, without 4GB or more, you may not be able to start VMs." -ForegroundColor Yellow

149. Write-Host "Would you like to set Vm memory to 4GB? (Y/N)" -NoNewline

150. $input = Read-Host

152. if($input -eq 'Y') {

153. Set-VMMemory -VMName $vmName -StartupBytes $4GB

154. }

155. else {

156. Write-Host "Not setting Vm Memory to 4GB."

157. }

158. }

159. Exit;

160. }

162. if($char.StartsWith('N')) {

163. Write-Host "Exiting..."

164. Exit;

165. }

166. Write-Host 'Invalid input'

Dans cette version préliminaire, l'imbrication inclut quelques exigences de configuration. Pour faciliter les choses, ce script PowerShell vérifie votre configuration, remplace tout ce qui est incorrect, puis active la virtualisation imbriquée pour la machine virtuelle spécifiée.

Invoke-WebRequest https://raw.githubusercontent.com/Microsoft/Virtualization-Documentation/master/hyperv-tools/Nested/Enable-NestedVm.ps1 -OutFile ~/Enable-NestedVm.ps1
~/Enable-NestedVm.ps1 -VmName "DemoVM"

3. Installez Hyper-V dans la machine virtuelle.

Invoke-Command -VMName "DemoVM" -ScriptBlock { Enable-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V -Online; Restart-Computer }

4. Créez des machines virtuelles imbriquées.

VII-C - Problèmes connus

Voici une liste des problèmes connus :

- les hôtes sur lesquels la fonctionnalité Device Guard est activée ne peuvent pas exposer les extensions de virtualisation aux invités ;

- les hôtes sur lesquels la sécurité basée sur la virtualisation est activée ne peuvent pas exposer les extensions de virtualisation aux invités. Vous devez d'abord désactiver la sécurité basée sur la virtualisation pour pouvoir afficher un aperçu de la virtualisation imbriquée ;

- une fois la virtualisation imbriquée activée sur une machine virtuelle, les fonctionnalités suivantes ne sont plus compatibles avec cette machine virtuelle ;

ces actions échouent ou empêchent la machine virtuelle de démarrer si elle héberge d'autres machines virtuelles :

- la mémoire dynamique doit être désactivée. Sinon la machine virtuelle ne peut pas démarrer,

- le redimensionnement de la mémoire d'exécution échoue,

- l'application de points de contrôle à une machine virtuelle en cours d'exécution échoue,

- la migration dynamique échoue. En d'autres termes, une machine virtuelle qui héberge d'autres machines virtuelles ne peut pas être migrée dynamiquement,

- la sauvegarde/restauration échoue ;

Ces fonctionnalités fonctionnent toujours dans la machine virtuelle invitée la « plus interne ». Les restrictions s'appliquent uniquement à la première couche de machines virtuelles.

- une fois la virtualisation imbriquée activée, l'usurpation MAC doit être activée sur la machine virtuelle pour que la mise en réseau fonctionne sur les invités les « plus internes ».

VII-D - FAQ et résolution des problèmes

VII-D-1 - Ma machine virtuelle ne démarre pas, que dois-je faire ?

1. Assurez-vous que la mémoire dynamique est désactivée.

2. Exécutez ce script PowerShell sur votre ordinateur hôte à partir d'une invite de commandes avec élévation de privilèges.

Ce script indique si votre hôte et les machines virtuelles sont configurés correctement pour l'imbrication.

Invoke-WebRequest https://raw.githubusercontent.com/Microsoft/Virtualization-Documentation/master/hyperv-tools/Nested/Get-NestedVirtStatus.ps1 -OutFile ~/Get-NestedVirtStatus.ps1
~/Get-NestedVirtStatus.ps1

VII-D-2 - La connexion à une machine virtuelle n'est pas rétablie

Si vous utilisez un mot de passe vide, il s'agit d'un problème connu. Modifiez votre mot de passe pour résoudre le problème.

VII-D-3 - Mon problème n'est pas indiqué ici

Votre problème n'est pas indiqué ? Vous avez des commentaires ? Contactez-nous.

Indiquez-les dans l'application Commentaires sur Windows, les forums sur la virtualisation ou sur GitHub.

VIII - Remerciements

Nous tenons à remercier Claude Leloup pour sa relecture orthographique et Malick SECK pour la mise au gabarit.

Nous tenons également à remercier Microsoft France pour leur autorisation d'intégration de leur page https://msdn.microsoft.com/fr-fr/virtualization/hyperv_on_windows/user_guide/nesting.