Hello, Cloud Gurus,
and welcome back for this lesson
where we're going to take a look
at enabling nested virtualization.
Let's take a look at what we're going to cover.
First up, we'll introduce nested virtualization,
then we'll take a look at the requirements,
we'll also cover off some of the specific concepts
around nested virtualization networking,
and then we'll do a demo
where we will configure nested virtual machines.
Let's get started.
Earlier in this section,
we spoke about some of the requirements that Hyper-V has
including the special CPU extension requirements.
When Hyper-V is installed,
the Hyper-V hypervisor takes control of the CPU
and prevents the guest operating systems
from accessing those CPU extensions.
Instead, it provides a virtual CPU
and presents that to the guest operating system.
This means that by default,
virtual machines running on Hyper-V
cannot install the Hyper-V role
and cannot run VMs within a VM.
Now, running a hypervisor in a VM to run another VM
is referred to as nested virtualization.
I personally wish they'd used the name, "Vmception".
Anyways, nested virtualization works both
on premises and in Azure VMs.
And nested virtualization is useful
for testing and development purposes.
Developers will use nested virtualization
to run development devices without needing access
to multiple physical devices,
and hybrid administrators will use nested virtualization
to test scenarios that would
otherwise require multiple physical servers.
I've used nested virtualization myself in this course
to demonstrate Hyper-V and Azure Arc,
as just a couple of examples.
You can enable nested virtualization
using the Set-VMProcessor commandlet.
And when you do this,
Hyper-V will expose the CPU capabilities
to the guest operating system,
allowing the VM to install the Hyper-V role
and run nested virtual machines.
Now on Azure, we don't have access to the Hyper-V server,
so we can't run this command.
So thankfully, Microsoft has already run
this command for us.
Now, there are some requirements
to use nested virtualization,
so let's take a look at those now.
For Intel processors,
you need to use Window Server 2016 or later on the host.
And you need to be using VM configuration version 8
or later on the guest.
And for AMD processes,
you need to be running Windows Server 2022 on the host
and be using VM Configuration 10 or later on the guest.
And for Azure Virtual Machines,
there is support for nested virtualization
on a wide variety of VM sizes,
including a number of E and D-sized VMs,
including both Intel and AMD-based hosts.
Instead of listing them all here,
take a look at the link I've provided
in the resources for a full list.
Now, nested virtualization provides some challenges
when it comes to networking.
Without diving into advanced networking in too much detail,
there are just a couple of things
that you need to be aware of.
Typically, Hyper-V will provide a virtual MAC address
to guest virtual machines and traffic can be directed
to these virtual machines using that virtual MAC address.
Because a Hyper-V host is connected to a physical network
where MAC addresses are required,
it can own the virtual MAC address
and direct the traffic back to the virtual machine
through its virtual switch.
Now, this is a problem when you use nested virtualization,
because the physical Hyper-V host
doesn't know about the second virtual MAC,
and the physical network doesn't know
where to direct the traffic back.
There are 2 ways to solve this problem.
The first is to use MAC address spoofing,
where you configure the network adapter
on the second level virtual machine
to fake, or spoof, its MAC address,
so that it appears to be the first level virtual machine
to the physical network.
And this is the recommended approach on a physical network,
because it's simply checking a box on the VM
and some networking configuration on the physical network.
The second option is to use network address translation,
which essentially turns the first level VM into a router
and it translates the IP address of the second level VM
to its IP address before sending the traffic to the network.
And this approach is recommended in Azure,
and we'll take a look at this in the demo.
All right, let's take a quick look at nested virtualization.
I've deployed an Azure VM named CORP-AUE-HV01.
And I've deployed the Hyper-V role on that VM.
Now, if this were on-premises,
we'd have to run the Set-VMProcess command
on the Hyper-V host,
but because it's running in Azure,
Microsoft has already done this for us.
And for something a little bit different,
we'll do this demo in PowerShell.
We'll take a look at the steps required to deploy a VM
and we'll take a look at the Set-VMProcessor cmdlet
that we'd need to run on-premises.
And then we'll take a look at the steps required
to configure network address translation
on our Hyper-V host to give our nested VM access
to the Azure virtual network in the internet.
Now, this is a fairly decent PowerShell heavy demo.
So strap in, and let's get started.
All right, so here we are on our Hyper-V host.
Let's go ahead first and create a directory
that we can use to store our virtual machines.
So to do that, we'll create a new folder
named VMs in the C drive.
Using the New-Item PowerShell cmdlet,
go ahead and run that on that.
And now let's go ahead and create a new virtual machine
using the New-VM PowerShell cmdlet
from the Hyper-V PowerShell module.
I'll go ahead and paste the command in here.
So we're running New-VM,
we're specifying a name for our virtual machine,
specifying that we want a Generation 2 virtual machine,
and we're going to put it in the C:\VMs folder,
in its own folder.
We're going to set the memory startup bytes to 1 gigabyte,
we'll create a new VHD in the path C:\VMs
and then a VHDX file.
And then we'll specify that the new VHD
should be 70 gigabytes in size.
We'll go ahead and run that.
It'll go ahead and transparently import
the Hyper-V PowerShell module into our PowerShell session.
And then go ahead and create that virtual machine.
Now let's attach a DVD drive to that virtual machine
using a CD ROM image that we've got in the C ISO's folder.
To do that, we'll use the Add-VMDvdDrive
PowerShell cmdlet,
and we'll use the pass through parameter
to save that DVD ROM drive into a DVD drive variable
that we can use later to set the first boot device.
So we'll go ahead and run that command.
Now let's set the VM boot device.
And because the VM is a Generation 2 VM,
we're going to use the Set-VMFirmware
PowerShell cmdlet, we'll specify the VM name,
and that the first boot device should be the DVD drive
that we've just attached to our VM.
Now, if we were configuring nested virtualization
on a VM that was directly running on a Hyper-V host,
we'd need to run the Set-VMProcessor PowerShell cmdlet.
But because we're already running
in a virtual machine on Azure,
and we're creating another virtual machine,
we don't need to run that Set-VMProcessor
PowerShell cmdlet, but I will show you the property
that that PowerShell cmdlet sets.
So you can see that PowerShell cmdlet
on a Hyper-VVM if you ever run that yourself.
So to do that, I'll use Get-VMProcessor,
and specify that we want to get the VM name property
and the exposed virtualization extension's property.
And we can see here
that virtualization extensions are not exposed
to this virtual machine, and that's as we would expect
because this is a virtual machine that's already running
inside another virtual machine.
Then let's go ahead and start the virtual machine.
And then we'll use VMConnect to connect
to the virtual machine.
We'll start the VM with the Start-VM PowerShell cmdlet.
We'll go ahead and run that.
And now let's connect to that virtual machine
using VMConnect.
So to do that, we can run VMConnect,
specify that we want to connect to the local host
which is the Hyper-V server,
and then the VM name that we want to connect to
on that Hyper-V host, which is our newly created VM.
So I'll go ahead and run that.
All right. And it's failed the boot
because I didn't press the Enter key
when I was booting from the CD ROM,
so let's just go ahead and restart now.
Use Ctrl + Alt + Delete to restart,
press any key to boot from the DVD.
Now I'll go ahead and install Windows on this VM,
and then I'll come back when that's done.
And we'll go through the process
of configuring an internal switch for NAT.
All right. That VM is now installing.
So now I'll jump back to the host
and we'll configure our VM switch
to use network address translation.
So we'll jump back to PowerShell.
We'll go ahead and just clear the screen.
And now we're going to run the new VM switch
and create a switch with the name NAT Switch
and then we'll set the switch type to internal.
All right.
And it just disconnected us
from our remote session for a second. And we're back.
Now, let's go ahead and get a list
of the network adapters on our Hyper-V host
using the Get-NetAdapter PowerShare cmdlet.
And now we're going to need the interface index
for this NAT switch network interface.
So we'll make a note of that, which is 27.
And we'll go ahead and run the next command,
which is to configure an IP address
on that virtual switch network interface.
So we'll go ahead and run New-NetIPAddress,
specify the IP address for our NAT switch network interface.
Specify the prefix index of 24,
and use the interface index of 27.
Now we'll go ahead and create a new network NAT
using the name MyVMNAT,
and we'll specify the internal IP address prefix
which is in the same IP address range
as we've just configured on that network interface,
which will be 192.168.0.0/24.
So this internal IP interface address prefix
will be the IP address that our nested virtual machines
will use.
So we'll go ahead and run that.
Now let's connect the network adapter
for our virtual machine to that virtual switch.
And we'll do that using the Connect-VMNetworkAdapter
PowerShell commandlet, we'll specify the VM name,
the name for the network adapter and the switch name.
We'll go ahead and run that.
All right.
And our virtual machines network adapter
is now connected to that virtual switch.
Now like all NAT routers,
you can actually forward ports back
to your VMs where the traffic originates
from outside your Hyper-V host's internal network.
And you can do that using network address translation rules
to forward traffic back into your virtual machines.
But that's not something we're going to cover in this demo.
I just wanted you to be aware that that is a possibility.
All right, now we're just waiting
for our virtual machine to finish configuring,
and then we can go ahead and test network access
on our virtual machine using NAT.
So I'll pause the video here,
and we'll come back when this is done.
All right, the VM deployment is now complete.
Now I want to paste some PowerShell commands
into this virtual machine.
So I've just gone ahead
and enabled remote desktop connections
on this virtual machine.
So I can go ahead and click OK on that.
And now I can go ahead and switch to an enhanced session
by selecting View and then Enhanced Session.
And then this will allow me to paste commands
into this virtual machine.
So I'll go ahead and hit Connect.
And now I just need to log in again.
And now let's go ahead and run some PowerShell commands
to configure the networking on this virtual machine.
The first thing we need to do is use the New-NetIPAddress
PowerShell cmdlet to set the IP address
on this virtual machine.
And we need to set a default gateway
that is the IP address of the network interface
on our host that is connected to the internal virtual switch
and has NAT configured on it.
So we'll go ahead and run that New-NetIPAddress
PowerShell cmdlet, and for the interface index,
we're just specifying to get the only network adapter
that's connected to this virtual machine
and get the interface index from that network adapter.
So we'll go ahead and run that command.
And we'll just go ahead select yes
to make this VM discoverable on our network.
And now let's go ahead and configure DNS.
And we'll do that using the SetDnsClientServerAddress.
We'll specify the interface index
of our only network adapter again,
and we'll set the server addresses to the Azure DNS server.
So we'll go ahead and run that command.
And then we'll just give our VM a second to realize
that it's connected to the internet.
And then we'll go ahead and test network connectivity.
All right.
The VM has realized that we're connected.
Now let's go ahead and test network connectivity.
To do that, we'll just do a Test-NetConnection
to microsoft.com.
And we can see that even though the ping failed,
it did resolve the IP address
which means we've got internet connectivity
for this virtual machine.
All right.
That concludes this demo.
Now let's wrap up with a bit
of a summary of what we've covered in this lesson.
All right.
So what have we covered in this lesson?
Nested virtualization enables you to run Hyper-V
within a guest virtual machine
and it's great for both development and test scenarios.
And to enable nested virtualization,
you run the Set-VMProcessor PowerShell commandlet
to path through the processor extensions
to that virtual machine so it can install the Hyper-V role.
And on Azure, Microsoft does this for you
on supported VM sizes.
And you can use an internal virtual switch
and run the New-NetNat PowerShell commandlet
to provide external network access for your nested VMs.
All right, thanks for being with me in this lesson.
I hope you found it useful,
and I look forward to seeing you on the next lesson.