The goal of this blog series is to share how I use the Windows 8 Client Hyper-V feature to model application infrastructure. I will share my techniques and tips to get the developer focused on getting environments up and running as quickly as possible.
The experiences that led me to write this series stem from observation of difficulties and oversights between developers and operations teams during application deployment and troubleshooting. It is not uncommon for IT organizations to have many environments that increase in complexity as an application moves through development, integration testing, quality assurance, performance testing, and production environments. Commonly there are more “real life” components present in high level environments such as production and more mocking and simulation in lower environments such as development. The single machine developer perspective of an application may be quite different than an IT Pro supporting a farm of servers. When deployed in “real life” the application may have to work across many servers, load balancers, subnets, and potentially geographically disperse datacenters. A number of questions for the developer may arise as the application is deployed to higher level environments.
These are difficult questions for a developer and I have found them often ignored or disregarded as “someone else’s job”. Architecture should have thought of these kind of things right? This isn’t to suggest that developers are doing it wrong – quite the opposite the advent of tools like the Web Platform Installer, Nuget, and Visual Studio 2012 have made developers more productive than ever on even the most modest laptop. A downside of this explosion of productivity is the unforeseen complexity that can result when an application is taken from a single machine and deployed across a farm of servers. Now with the release of Windows 8 developers now have a powerful new tool to add to their arsenal, Client Hyper-V, to better simulate “the real world”.
Until Windows 8 the use of Hyper-V was limited to Windows Server operating systems or those developers brave enough to build their own “frankenserver” workstations. Other options are available for non-Microsoft hypervisors including several that are intended for more desktop use scenarios. However, having used just about all of them I’ll do my best to make a case that Client Hyper-V will almost let the developer build out most any scenario or topology that their application may require. Along the way the infrastructure knowledge gained by the developer is invaluable and will lead to new thinking across deployment, supportability, and troubleshooting of their application. Put simply client Hyper-V will let the developer walk in the shoes of IT Pro’s without leaving the comfort of their developer workstation.
The minimum requirements for using Client Hyper-V are:
To determine if your PC supports SLAT download the Sysinternals utility Coreinfo and run the command below. Note that the ‘-v’ switch requires local administrative rights (depending on your processor manufacturer the text output may vary).
Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
Intel64 Family 6 Model 30 Stepping 5, GenuineIntel
HYPERVISOR * Hypervisor is present
VMX - Supports Intel hardware-assisted virtualization
EPT - Supports Intel extended page tables (SLAT)
If your hardware doesn’t support SLAT don’t fret just yet. Reboot your PC and enter your BIOS or EFI and validate that your hardware's virtualization features are enabled. In my experience the virtualization features of PC’s are often disabled by default. Please note that it takes a full shutdown for this change to take effect.
Lastly the Client Hyper-V feature is not enabled by default under Windows 8 Pro. You can enable Client Hyper-V via the Programs and Feature applet under Windows 8 or by running the following command from a Powershell command prompt:
Enable-WindowsOptionalFeature –FeatureName Microsoft-Hyper-V -All
The hardware I use at present for my Client Hyper-V machine is modest: A laptop with a “Sandy Bridge” Core i7 processor, 16GB of RAM, and two 128GB SSD drives. With this hardware I have successfully built an environment consisting of eleven virtual severs running simultaneously implementing this beast courtesy my friends over at SQLCAT. I find it best for performance reasons to separate the virtual hard drives across the two SSD’s placing “parent” virtual disk files on my C:\ParentDisks folder and “child” virtual disk files on my D:\ChildDisks folder (more on this later).
Your first steps to using Client Hyper-V will be to build base operating system (OS) images for server and client virtual machines. In my case I keep base OS images handy for Windows Server 2008 R2, Windows Server 2012, Windows 7, and Windows 8. I make use of sysprep for all of my images. Think of sysprep as a templating mechanism for operating system images. Furthermore some server products can also be sysprepped such as SQL Server 2012. The good news is that this is an activity you will have to perform only once per base OS image. Once the image is created you can create as many virtual machines from it for as long as you need.
To create your first base OS image navigate to the Hyper-V manager applet which was installed once Client Hyper-V was enabled and select New->Virtual Machine and proceed through the wizard. Booting the virtual machine from an ISO file of the operating system is probably the quickest means to creating the base image. Regardless of whether you are fortunate enough to have access to a TechNet or MSDN subscription, evaluation editions for Windows Server 2008 R2, Windows 7, Windows Server 2012, and Windows 8 are available for download to anyone. These ISO’s will allow a 90 or 180 day evaluation period which is often more than enough for proof-of-concept or break-fix scenarios.
Complete the OS installation and proceed to install any additional software that you want available to future servers or clients virtual machines that will be based on these images. As an example for Windows Server 2012 I use an image that includes the following additional tools installed into the OS:
In addition to this software I have added Visual Studio 2012 and a sysprepped version of SQL Server 2012 and all patches available from Windows Update at the time I built the image. As a last step bring up a command prompt within the virtual machine and type the following command to Sysprep the OS:
C:\Windows\System32\Sysprep\Sysprep.exe /generalize /shutdown
C:\Windows\System32\Sysprep\Sysprep.exe /generalize /shutdown
Once the sysprep operation is completed copy the *.vhdx file to your C:\ParentDisks folder and mark the virtual hard disk file as read-only via the Windows explorer. The reason for setting the read-only property this is that you will be using this virtual disk as a parent disk to create a number of child disks (these type of disks are referred to as differencing disks). Once you create the first child disk based on your OS image parent disk you cannot make modifications to the parent.
If you encounter any difficulties building your images it’s worth taking a look at this step-by-step guide on TechNet for building a Windows 7 based image using sysprep.
Networking beyond simple NAT’ing out to the Internet is one of the more difficult tasks for setting up virtual machines with Hyper-V. The Hyper-V manager includes a link under Actions called Virtual Switch Manager… which lets you create virtual network switches to associate with virtual machines. Think of a conference room with a bunch of laptops all plugged into a physical Ethernet hub resulting in a small LAN that may or may not bridge out to a larger corpnet or the internet. There are three types of networks supported by the Hyper-V virtual switch feature:
On my setup I create two standard switches:
Additionally create one or more private switches for each subnet required for your simulation. Think of these subnets as datacenters logically if you are modeling based on physical topology. To illustrate here is a screen clipping of my setup to simulate two datacenters across two subnets. We will be building a small farm of servers that spans these virtual switches.
So now let’s put all the pieces together. The following steps will allow us to build out a four server topology with Client Hyper-V using a sysprepped Windows Server 2012 base OS Image. To create these machines quickly we are going to use a Powershell script from a PFE peer of mine Richard Sasser called “MDGHOST.ps1” that performs several useful functions:
Here is a snippet of my MDGHOST.ps1 script with defaults for my setup as an example:
#This file builds VMs based on differencing disks #initialize defaults $ParentDef = "Win2012Sysprep" $Namedef = "Scratch" $Networkdef = "Guest2External" [int64]$Memdef = 1024MB $Procdef = 2 $ParentDir = "C:\ParentDisks" $global:VHD="D:\ChildDisks\" $procval=1,2,4 [int64]$maxmem=4192MB
Next open a Powershell command prompt running as administrator. We are going to execute four commands to create four virtual machines: a domain controller (DC1), an application server (APP1), a second application server (APP2), and a router (ROUTER1).
PS C:\ParentDisks> . .\MDGHOST.ps1 PS C:\ParentDisks> mdghost -help mdghost [parent] [newvhd] [net] [mem] [cpu] [help] [go] PS C:\ParentDisks> mdghost Win2012Sysprep.vhdx APP1 Parent:Win2012Sysprep.vhdx VHD:APP1 Net:Guest2External Memory:1024MB CPU:2 Confirm (y/n): y PS C:\ParentDisks> mdghost Win2012Sysprep.vhdx APP2 Parent:Win2012Sysprep.vhdx VHD:APP2 Net:Guest2External Memory:1024MB CPU:2 Confirm (y/n): y PS C:\ParentDisks> mdghost Win2012Sysprep.vhdx ROUTER1 Parent:Win2012Sysprep.vhdx VHD:ROUTER1 Net:Guest2External Memory:1024MB CPU:2 Confirm (y/n): y PS C:\ParentDisks> mdghost Win2012Sysprep.vhdx DC1 Parent:Win2012Sysprep.vhdx VHD:DC1 Net:Guest2External Memory:1024MB CPU:2 Confirm (y/n): y
You may have observed that based on the defaults setup in the MDGHOST.ps1 file I simply needed to specify the parent disk and the NetBIOS style name of the virtual machine I wished to create. The remainder of the work is handled by the Powershell script. A quick trip over to the Hyper-V manager and we can see that all four machines were created and have started.
Next we login to each machine by double clicking the server name and completing the sysprepped installation which consists of the steps listed below. Note that when you double click the machine name you open the Virtual Machine Connection tool which is a utility that allows you to connect from your host (in this case my laptop) to each of the running virtual machines.
As a tip to quickly rename and reboot each machine you can execute the following Powershell snippet and get this text into the Virtual Machine via the Clipboard –> Type clipboard text feature of the Virtual Machine Connection. This is a useful script to add to your base image potentially and easily modified to prompt for user input.
$NewName = "APP1" $ComputerInfo = Get-WmiObject -Class Win32_ComputerSystem $ComputerInfo.Rename($NewName)
In addition you can also automate the tasks of running Windows Update on your virtual machines with a PowerShell module as detailed on another Scripting Guy’s blog posting over here. This PowerShell module will allow you to have Windows Update execute, select available updates, install updates, and reboot the virtual machines.
Once these steps are complete we are ready to configure the private network. At this point all of our Windows Server 2012 machines are standalone servers meaning they are not part of a Active Directory domain but rather part of a workgroup. First things first we need to move the servers to our private network and assign IP addresses to simulate our two datacenter topology. To keep things simple we will use the following static IP address and virtual NIC configurations:
So what this table is accomplishing sets the stage for using the DC1 server as our DNS server and using the ROUTER1 machine as a software router to bridge the 10.x and 20.x networks. We’ll set up the ROUTER1 machine first.
When completed the network setup for the ROUTER1 virtual machine should resemble the following screen clipping from the Hyper-V settings for this virtual machine:
Startup the ROUTER1 machine and login locally with the local administrator account you created during the OS installation. One the machine is started head over to the Network Connections control panel in the virtual machine so we can IP the various NICs. This applet should resemble the screen clipping below.
Well that’s not too helpful is it? How can one tell which NIC is associated with which virtual switch? There are several ways for one you could match up the MAC addresses of each virtual NIC with the MAC address in the Hyper-V settings for each virtual NIC but that’s no fun. Go back to the Hyper-V settings for this virtual machine and set all but the Corpnet 10.x.x.x Datacenter1 NIC to Not Connected under the virtual switch setting. This is analogous to physically unplugging an Ethernet cord from a running server.
Now that’s better. We can now easily determine which NIC is associated with which guest virtual switch. Next set the IP addresses to the values defined in the table earlier one by one (do so by right clicking each NIC selecting Properties, scrolling down to Internet Protocol Version 4 (TCP/IPv4), double clicking the icon, and keying in the values). I recommend renaming the NICs as you go along within the virtual machine and remember you only have to do this once!
Now we can configure the networks on the DC1, APP1, and APP2 servers which will be far simpler as each of these servers have only once virtual NIC. Go slowly and don’t rush this part of the setup. Once this is complete we can begin to test network connectivity between our servers. Let’s login to the DC1 server and attempt to ping the APP1 (10.1.1.3) and ROUTER1 (10.1.1.1) servers.
So what happened? After double checking your settings you will determine that all three of these servers have valid network setups, and are virtually plugged into the same virtual switch, so what gives? The Windows Firewall is active by default and is blocking the ICMP protocol the Ping command is using. So here you have a choice either disable the Firewall across the servers or begin to enable inbound firewall rules to allow the Ping traffic into each server. From the Windows Server 2012 start screen typing the word “Firewall” will jump you to a the Firewall configuration applet. Once this is launched click on Inbound Rules and find File and Printer Sharing (Echo Request – ICMPv4-In) rule and enable it via right clicking. Repeat this step for each of our servers unless you have elected to disable the Windows Firewall.
Once this is complete from the DC1 machine we can ping the APP1 and ROUTER1 servers on our private network with the exception of the APP2 server.
Our issue with communication between the DC1 and APP2 servers is that the two servers are located on different networks from one another. In essence these two servers are sitting in different datacenters and we need a router to bridge the two networks. We can create a software router using the Routing and Remote Access feature (RRAS) of Windows Server 2012 along with our carefully crafted network IP address and NIC configuration created earlier. If you were watching closely you may have noticed that the default gateway IP address for the DC1, APP1, and APP2 servers matched one of the two IP addresses assigned to the ROUTER1 server. From the ROUTER1 virtual machine startup the Server Manager applet from the task bar and under the Configure this local server header select the Add Roles and Features option.
Once the wizard launches click Next—> three times and select the Remote Access feature. A pop-up window will appear and you should click Add Feature. The screen selection should now resemble the screen clipping below.
Select Next—> three more times until you are at the select Role Services for Remote Access screen.
Select the Routing checkbox and once again a pop-up window will appear so click Add Feature. Select Next—> three more times and finally select Install and wait for the wizard to complete. Finally reboot the ROUTER1 server. Once the reboot is complete log back into the ROUTER1 server. A screen clipping of the desktop wallpaper for this server follows (courtesy of the Sysinternals BGInfo utility).
A few quick observations show our statically configured IP addresses on each subnet in our simulation along with a 192.168.1.79 address from the virtual NIC configured on the Guest2External virtual switch. This NIC has received an IP address from the router on my home network and we will soon use this NIC to allow the other servers in our private network to access the internet. From the Start screen of ROUTER1 launch the Routing and Remote Access Configuration applet.
Following the screen clipping above select the option to Configure and Enable Routing and Remote Access. Select Next > on the first page of the wizard and check the radio button Custom Configuration.
Click Next > once more and check the NAT and LAN Routing checkboxes. Select Next > and then Finish on the resulting screen of the wizard.
After selecting Finish a pop-up window will appear and you should select Start Service.
We are almost done! After the RRAS service has started you will return to the Routing and Remote Access configuration applet. We need to add an interface to the NAT section of the treeview (IPv4) by right clicking NAT and selecting New Interface.
Next you need to select interface that is connected to the Guest2External virtual switch. The names in the select box below stem from renaming the NICs we configured earlier at the Network Connections control panel.
Finally select the Public interface connected to the Internet radio button and check the Enable NAT on this interface checkbox and click the OK button.
At long last we are hopefully complete. Head back over to the DC1 virtual server and let’s try to ping the APP2 server which failed earlier. If all is well we should bridge the 10.x network to the 20.x network via the RRAS software router we just setup.
Our Ping command from DC1 (10.1.1.2) to APP2 (188.8.131.52) now works! The last and final test is whether or not we can access the internet from our private network on the DC1 server via the NAT feature we enabled on the ROUTER1 RRAS service. We can test the connectivity by opening a web browser on the DC1 server and navigating to a internet site such as http://bing.com/.
Here we are accessing the internet from a private network within our Hyper-V virtual machine DC1. Feel free to test the other servers in our farm APP1, APP2, and ROUTER1 in all cases they should be able to access the internet as well.
Our work to date has laid the groundwork for the remainder of this blogs series and is by far the most time consuming portion so congratulations for making it this far!
In Part 2 of this blog series we will focus on completing the following tasks:
Stay tuned and thanks for reading.
Acknowledgements to the following Microsoft Premier Field Engineers who have over the years given me much knowledge and insight into world of infrastructure: Bruce Adamczak, Richard Sasser, Tom Moser, Jeff Stokes, and Doug Gabbard. Their blogs are more than worthy of being added to your RSS reader of choice!