Previous Post in Series: Part 9: Deploy and Configure SDN Network Controller Service
Welcome to part 10 of my Server 2016 Features series. This guide will continue on from parts 8 and 9 where we learned a little about SDN v2 in Server 2016 and deployed our multi node Network Controller service (which is a prerequisite for our Software Load Balancer service). Going forward, I’ll be referring to our Software Load Balancer service as the SLB or SLB/MUX
As with the Network Controller service, this deployment will be done using a multi node (3 nodes) Service Template deployed by SCVMM.
Here’s a list of the tasks we’ll be covering:
- Prerequisites
- Provide SSL Certificate
- Create Required Logical Networking in SCVMM
- Import SLB Service Template
- Deploy SLB Service
- Configure the SLB Role
- Validate the SLB Deployment
With no further ado, let’s get to it.
Prerequisites
For the most part, this is an easy one, any prerequisites should have been taken care of during your Network Controller deployment. I’ll link to sections of my part 9 post as we go, as a reminder.
The only exception to this would be around your BGP configuration. As explained in my SDN overview the Software Load Balancer role will exchange BGP routes with the Top of Rack (ToR) switches. A /32 route will be created and published to the ToR when NAT is enabled on a tenant VM Network.
To allow this to work, your networking team will have to configure a BGP peering on your ToRs between two private AS numbers, one assigned to the ToRs and one assigned to your SLB VMs. You’ll see how this is configured from the SCVMM network service later in this guide.
Provide SSL Certificate
Another easy section In part 9, you created an SSL certificate, copied the .CER to a folder named “NCCertificate” and uploaded it to your SCVMM library. Check HERE if you need to confirm you’re all good before continuing.
Create Required Logical Networking in SCVMM
Before importing our SLB Service Template, we need to create 3 additional logical networks. These are the “Transit”, “Private VIP” and “Public VIP” networks. You can find more information on these networks and their use in an SDN environment HERE.
Transit Logical Network
From within your SCVMM console, navigate to “Fabric”, “Networking”, right-click “Logical Networks” and select “Create Logical Network”.

Enter a “Name” and optionally a “Description” and click “Next”

Select “One connected network”, “Create a VM network with the same name…”, “Management by Microsoft Network Controller” and click “Next”

Click “Add” to add a new “Network Site”
Place a tick in the host group that contains your SDN enabled Hyper-V hosts
Click “Insert row” and enter the VLAN ID and subnet you’ve configured on your Top of Rack switches for this network. Now click “Next” and “Finish”

As SCVMM will be dishing out IPs on this network (to our SLBs), we’ll also need to create an IP pool.
Right-click on the network your just created and select “Create IP Pool”

Enter a “Name” and optionally a “Description” for the IP Pool, I generally call mine “Logical Network Name – IP Pool”
The correct logical network should already be selected, if not, select the correct one and click “Next”

Click “Use existing network site” and make sure you’ve got the correct “Network site”, “IP subnet” and “VLAN” selected/input and click “Next”

Enter a “Stating IP address”, if you’re using a /24 enter .4 It’s always best to start from the 4th IP in your subnet irrelevant of size.
Leave the “Ending IP address” at its default and click “Next”

Under “Default gateways” click “Insert” and enter the default gateway IP configured on your Top of Rack switches for this network (generally .1) and click “Next”

Click “Next” past “DNS” and “WINS” and click “Finish”

NOTE: Now add this logical network to your management uplink port profile.
Private VIP Network
To create the Private VIP network and IP pool, follow the Transit Network guide with the following exceptions:
When adding the “Network Site” during the logical network creation, do not configure a VLAN (See screenshot):

On the “IP Address range” page of the IP Pool creation wizard, enter the whole configured range under “IP addresses reserved for load balancer VIPs” (See screenshot).

On the “Gateway” page of the IP Pool creation wizard, do not configure a default gateway (See screenshot).

Public VIP Network
To create the Public VIP network and IP pool, follow the Private VIP Network guide with the following exceptions:
On the “Settings” page of the logical network creation wizard, select “Public IP address network” (See screenshot)

With all the required networks configured, let’s import our service template
Import SLB Service Template
Within your SCVMM console, navigate to “Library” and click “Import Template” on the ribbon at the top of the screen.

You should have downloaded the SLB template back in part 9. Click “Browse” and navigate to C:\Temp\SLB\SLB Production Generation 2 VM.xml and click “Next”

On the “Configure References” page, we’re marrying up the custom resources (.cr folders) you copied to your SCVMM library share earlier.
Click the “pencil” icon next to “WinServer.vhdx”, select the VHDX you prepared earlier and click “OK”

Do the same for “NCCertificate.cr” and “EdgeDeployment.cr”.
- For “NCCertificate.cr”, select the custom resource of the same name.
- For “EdgeDeployment.cr”, select the custom resource of the same name
Your screen should now look something like this:

Now click “Next” and “Import”
Now that our template is imported, we need to customise it for our environment.
Navigate to “Library”, “Service Templates” right-click the template you just imported and click “Properties”

Have a look at the “Service Settings” tab. These settings can be configured at the point of template deployment but if we do it here we can save them which means we don’t have to re-enter them if we do something wrong or have to reuse the template
You can modify each value by highlighting it, clicking “Properties” and populating its “Value” field


I’ve created a table below that what value you should be setting against each item:
Setting | What to Configure |
---|---|
localAdmin | Browse and select a "Run As" account that will be the local administrator account for the SDN VMs you deploy. If you don't have a Run As account for "Administrator" yet, create it 🙂 |
ManagementNetwork | Select the "Management" VM network you created earlier |
MgmtDomainAccount | Select the Run As Account for the Network Controller Admin user you created earlier |
MgmtDomainFQDN | Enter the FQDN of the domain the above account sits on e.g. CONTOSO.com |
SelfSignedCertificate | Must be answered either "True" or "False". For example, if you're using a CA issued certificate, type "False" *1 |
TransitNetwork | Select the "Transit Network" VM network you created earlier |
*1 NOTE: If you have machine auto-enrolment enabled on your Certification Authority, your SLB VMs will automatically request computer certificates when they join the domain. This guide assumes that’s not the case (as it’ll work without issue otherwise and requires no explanation) and will explain how to work round that.
Deploy SLB Service
Now we’re going to modify a few of the settings specific to the roles we’re about to deploy.
Right-click your service template and select “Open Designer”

Click “Software Load Balancer” to highlight it and select “View All Properties” in the bottom right

On the “Hardware Configuration” tab change “Availability” to high.
This isn’t strictly required as the Software Load Balancer service will continue to function when a node goes down. At the very least though, it’ll save you having to power a node down during maintenance of the host it sits on. Much more elegant to just migrate it to another host in the cluster.
NOTE: You’ll receive a warning when trying to migrate an SLB node to a Hyper-V node that already hosts one. Not an issue if your Hyper-V host count is greater than your SLB nodes. It will let you manually migrate two SLB nodes to the same host (overruling the Availability Set), I suggest only doing this for maintenance windows and only if it cannot be avoided.

Make sure that if you’ve set a “Classification” for your shared storage in SCVMM that you assign this classification to the VMs disk as not doing so will cause you problems during the deployment.

On the “OS Configuration” tab, modify the “Identity Information” field to something that makes sense for your organisation. This is the name convention used for deploying your NC nodes. So using Blog-SLB# will name your SLB nodes, Blog-SLB1, 2 and 3. Using Blog-SLB## will name them Blog-SLB01, 02 and 03…dealers choice
Change the “Operating System” to “Windows Server 2016 Datacenter”
Enter a “Product Key”
Change the “Time Zone” if required
On the “Application configuration” tab, place a tick in “Windows Server 2016 Datacenter” (This is required because we changed the OS to Server 2016 above, for some reason, this template still comes with this setting as 2012 R2 as default).
Now click “OK”


Now click “Configure Deployment”

Enter a name for your SLB Service and choose the host group that contains the Hyper-V hosts you’re deploying your SLBs to.
If you’ve followed all the above steps correctly, “Network Settings” should be pre-populated.
Now click “OK”

When you’re first presented with the “Deploy Service” screen your Hyper-V host status will show as “No suitable host”, don’t worry about this, it’s perfectly normal. Click “Refresh Preview” and this should place each VM on a suitable host, updating the deployment screen in the process.


If you receive any errors at this point, it’s likely that one of the previous steps has been missed and you’ll be provided with an error message to help you troubleshoot the cause. Assuming all is as above though, click “Deploy Service” and select “OK”

The deployment will take a good while (upwards of an hour), so go grab yourself a coffee. All going well you should see the following when you get back:

NOTE: If the job fails then it’s likely you’re Certification Authority isn’t set up for auto-enrolment. If that’s the case, we can fix the problem and restart the failed job, which will continue on from where it left off.
Log onto the first SLB VM as a domain administrator and complete the following tasks:
Open the start menu, type “certlm.msc”, right-click it and select “Run as Administrator”

Navigate to “Personal”, “Certificates”, right-click and select “All Tasks” then “Request New Certificate”

Click “Next” past the welcome screen
Highlight “Active Directory Enrollment Policy” and click “Next”

Place a tick in the “Computer” template and click “Enroll”

…and that’s it, repeat the above steps for the other two SLB VMs and restart the failed job in SCVMM by right-clicking it and selecting “Restart”

All going well, the deployment should continue from where it left off and you’ll end up with a running SLB service. If it errors again, troubleshoot based on the error messages you receive and try restarting again. If the job fails in the same place, it may be worth removing the failed deployment completely and starting again from “Deploy SLB Service”
Configure the SLB Role
Now that we have successfully deployed our SLB service, we need to add it to the network service we created as part of our Network Controller deployment. This will allow the Network Controller service to manage our SLB role as part of our SDN infrastructure.
Within your SCVMM console, navigate to “Fabric”, “Networking” and “Network Service”
Right-click the network service you created as part of your Network Controller deployment and select “Properties”

- Navigate to the “Services” tab, click on “Load balancer role” and click “Browse” for “Associated service”
- Click “Browse” from “run as account” and select the NC Admin account you created earlier and configured in your NC and SLB deployment
- In “SLB Manager VIP”, enter an IP from the “Private VIP Network” IP pool you created earlier (I went with .4 as it’s the first in my pool)
- Under “SLBM VIP Pools”, select both “Private VIP Network” and “Public VIP Network”
- Now click “OK”

The job should complete with the following status:

Now we need to configure the BGP peer settings on our SLB VMs:
- Right-click your network service and select “Properties”
- Now click on one of the SLB VMs, to show its BGP settings
- In “Local ASN” enter the private AS number that your networking team has provided for the SLB service
- Click “Add” and type in a name (can be anything) for your first ToR switch
- Type in the IP from the Transit Network IP pool assigned to that same switch
- Type in the private AS number your networking team provided for your ToRs
- Click “Add” and add the name, IP and ASN for the second ToR
Repeat the above steps for the remaining two SLB VMs and click “OK”

After a few minutes (at most), the job should complete with the following status:
![clip_image041[1]](http://davidfleming.org/wp-content/uploads/2017/04/clip_image0411_thumb.png)
Validate the SLB Deployment
Nice one! We now have a Network Controller service deployed and configured, and managing a Software Load Balancer service…all that’s left to do is test it.
So when we finished deploying our Network Controller in part 9, we spun up two VMs, created a VM network and attached our VMs to it. We’re going to use those same VMs again.
What we’re going to test is our VMs ability to route out to the internet and our ability to connect to one of the VMs via RDP once we’ve added a NAT rule for it.
We’ll start by enabling NAT on the tenant VM network mentioned above.
Within your SCVMM console, navigate to “VMs and Services”, “VM Networks”, right-click the tenant VM network you created earlier and select “Properties”

On the “Connectivity” tab, select “Connect directly to an additional logical network” and “Network address translation (NAT)“
Under “Gateway Device”, select the Network Controller service you deployed in part 9

NOTE: If you look at the above screenshot, you’ll see that I’ve highlighted (in green) the amount of VM networks you can create on your 3 node Network Controller service. I thought this number looked a little low so checked with Microsoft. It’s a bug in SCVMM and will be resolved in an upcoming patch (if not already fixed). The actual number of VM networks you can create is 200.
On the “Network address translation” tab, select your “Public VIP Network” IP pool and click “OK”
This will pick a public IP from the pool and NAT it to an IP that’s been selected from the Private IP pool. This will then be advertised out as a /32 route by the SLB to your ToR switches via BGP.

You should now be able to connect out to the internet from any VMs that sit on that VM network.
If you look at the properties of the VM network again, you can see which IP was assigned by checking the “Network address translation” tab.

You can confirm this on the VM by opening a browser and navigating to https://www.whatismyip.com/ or any similar service.
So we can now get out to the internet for a VM sitting on an SDN VM network, but by default all inbound traffic is blocked, and that’s a good thing
Let’s say for talking sake that we want to be able to RDP to a VM sitting on this SDN VM network, how do we do that? Thankfully, it’s probably the most straightforward part of this whole thing.
- Go back to the properties of your VM network and select the “Network address translation” tab
- Click “Add” and type a name for your NAT rule, something that make sense. For me that was “Inbound_RDP_Tenant-A-VM1”
- Keep the default Protocol setting of “TCP”
- Change the “Incoming Port” to “50000” (this could be anything within reason)
- Change the “Destination IP” to the VM address of the VM (it’s guest configured IP)
- Change the “Destination Port” to “3389” (has to be 3389 for RDP)
- Now click “OK”

You should now be able to connect to the VM over RDP from any machine that can route to the VM networks configured IP address by typing the following into a command prompt:
mstsc /v:PublicIPAddress:50000 /f
Well that’s us at the conclusion of this guide folks, I hope you found it useful and that you didn’t hit too many stumbling blocks along the way. I’ve got one more guide in this series to go, this will be around troubleshooting your SDN environment and will contain a couple of log gathering and troubleshooting scripts that I’ve put together. I don’t expect that it will be hugely detailed as I’m still working through this piece myself but if I think it’ll help, I’ll put it up.
Hope to see you then

Thanks.
Hello,
Thank you for these guides.
I’m managing the system infrastructure and also responsible for the network side in our company.
I would like to know how to obtain the private AS number please.
Thanks
Hi AB,
A private ASN is just assigned by a network administrator from within the following range: 64512 to 65535.
Best regards,
David
Thank you David for your reply.
I’ll try to setup this new solution on our infrastructure and get back you in case of any issue.
Thank you once again.
AB
Anytime, and you’re very welcome. Good luck with the deployment!
How do manage certificate for Windows 2016 Core? there is no GUI
[slb01]: PS C:\> Get-Certificate -Template Computer -CertStoreLocation cert:\LocalMachine\My
CertEnroll::CX509Enrollment::InitializeFromTemplateName: The operation being requested was not performed because the
user has not been authenticated. 0x800704dc (WIN32: 1244 ERROR_NOT_AUTHENTICATED)
+ CategoryInfo : NotSpecified: (:) [Get-Certificate], Exception
+ FullyQualifiedErrorId : System.Exception,Microsoft.CertificateServices.Commands.GetCertificateCommand
[slb01]: PS C:\>
[slb01]: PS C:\> $cred = Get-Credential
Windows PowerShell Credential Request: cmdlet Get-Credential at command pipeline position 1
Warning: A script or application on the remote computer SLB01 is requesting your credentials. Enter your credentials
only if you trust the remote computer and the application or script that is requesting them.
Supply values for the following parameters:
Credential
[slb01]: PS C:\> Get-Certificate -Template Computer -CertStoreLocation cert:\LocalMachine\My -Credential $cred
Get-Certificate : Missing Url parameter
At line:1 char:1
+ Get-Certificate -Template Computer -CertStoreLocation cert:\LocalMach …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Certificate], ParameterBindingException
+ FullyQualifiedErrorId : RuntimeException,Microsoft.CertificateServices.Commands.GetCertificateCommand
Executing in the console to the slb vm, I still get this error. My head is rolling now.
PS C:\Users\administrator> Get-Certificate -Template Computer -CertStoreLocation cert:\LocalMachine\My | Out-File .\ComputerC
ertificate.txt
Get-Certificate : CertEnroll::CX509Enrollment::InitializeFromTemplateName: The requested certificate template is not
supported by this CA. 0x80094800 (-2146875392 CERTSRV_E_UNSUPPORTED_CERT_TYPE)
At line:1 char:1
+ Get-Certificate -Template Computer -CertStoreLocation cert:\LocalMach …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Certificate], Exception
+ FullyQualifiedErrorId : System.Exception,Microsoft.CertificateServices.Commands.GetCertificateCommand
I have got the server to auto-enrollment certificate with new certificate template duplicate from computer template. And the certificate has been issued from CA successfully.
But now the service deployment is stuck at error 22655 saying that VMM is unable to retrieve status from the mux vm. I have checked the accessible over the network and its fine, reinstalling the vmm guest agent (also rebooting it too) still its stuck here.
Error (22042)
The service SlbMuxService was not successfully deployed. Review the event log to determine the cause and corrective actions.
Recommended Action
The deployment can be restarted by retrying the job.
Error (22655)
VMM is unable to retrieve status from computer mux2.fabric.cloud.
Recommended Action
Check if the computer is running and the VM guest agent is in a healthy state.
Error (22655)
VMM is unable to retrieve status from computer mux3.fabric.cloud.
Recommended Action
Check if the computer is running and the VM guest agent is in a healthy state.
Error (22655)
VMM is unable to retrieve status from computer mux1.fabric.cloud.
Recommended Action
Check if the computer is running and the VM guest agent is in a healthy state.
Error (20400)
3 parallel subtasks failed during execution.
Error (21952)
Application deployment failed for one or more tiers or application hosts in the service SlbMuxService. Check job logs to get more information on the failed operation.
Recommended Action
Check error messages and retry the operation if needed.
Hi David,
Do you have any idea how to resolve this error?
Error (22631)
The script command exit code 1 matched the failure policy setting “Match any value other than zero.” Standard output log data: “494+07:00] Starting slbmux service
VERBOSE: [2017-12-06T23:38:31.2049554+07:00] Caught an exception:
VERBOSE: [2017-12-06T23:38:31.2049554+07:00] Exception Type: Microsoft.PowerShell.Commands.ServiceCommandException
VERBOSE: [2017-12-06T23:38:31.2049554+07:00] Exception Message: Failed to start service ‘Software Load Balancer
Multiplexer (slbmux)’.
VERBOSE: [2017-12-06T23:38:31.2049554+07:00] Exception HResult: -2146233087
VERBOSE: [2017-12-06T23:38:31.2049554+07:00] retrying
VERBOSE: [2017-12-06T23:38:31.2049554+07:00] Starting slbmux service
VERBOSE: [2017-12-06T23:38:33.3196068+07:00] Caught an exception:
VERBOSE: [2017-12-06T23:38:33.3216674+07:00] Exception Type: Microsoft.PowerShell.Commands.ServiceCommandException
VERBOSE: [2017-12-06T23:38:33.3216674+07:00] Exception Message: Failed to start service ‘Software Load Balancer
Multiplexer (slbmux)’.
VERBOSE: [2017-12-06T23:38:33.3216674+07:00] Exception HResult: -2146233087
VERBOSE: [2017-12-06T23:38:33.”
Recommended Action
If the script command’s job restart action is set to restart, then the script will be re-executed. Otherwise, the script command will be skipped when the job is restarted, in which case corrective action should be taken to mitigate the effects of the script command failure.
Hi David,
Thank you for the detailed guide.
I’m just getting familiar with this new technology and as I read your article 2 questions came to my mind.
The first is that why should we assign different ASN s to our SLB and TOR switches?
The second is that if we configure the Public VIP range but we would like to control which external IP is assigned to which tenant VM network to NAT the traffic can we do this somehow?
Thank You
Hi Gergely,
It’s been a good while since I’ve actually worked on this (new job) but I’m pretty certain that you can assign any IP within the Public VIP pool when setting up the NAT connection within SCVMM.
It will pick one for you if you don’t specify one though.
Hi David,
I’m having trouble getting outbound NAT access from my Tenant VM’s. The tenant VM’s can ping each other and are spread across 3 hyper-v hosts. I setup a NAT connection and assigned a Public VIP from the IP pool.
But I’m still unable to get an outbound NAT connection. What else could be stopping the connectivity ?
Management Network: 172.16.0.0./16
Transit Network: 10.20.0.0/23
HNV Network: 10.10.0.0/23
3 x Hyper-V Hosts connected to a Management vNIC with a Gateway of 172.16.0.254
3 x NC VM’s connected to Management Lan with a Gateway of 172.16.0.254
3 x SLB/Muxes connected to Management Lan, Transit Lan and HNV Lan with a Gateway of 10.20.0.1 (Windows VM Router)
3 x Gateway VM’s connected to Management Lan, Transit Lan and HNV Lan with a Gateway of 10.20.0.1
Running Get-BGPPeer from the Windows Router VM returns a connected status to all 3 SLB/Muxes and all 3 Gateway VM’s.
Running Get-BGPRouteinformation returns the PrivateVIP address mapped to each SLB/Mux and the correct next hop using the transit network IP address. It also returns the correct Public IP address that was assigned to the Tenant VM Network and mapped to the correct next hop using the transit IP address of the slb/muxes.
Any help would be appreciated. Thanks
Hi David,
I have deployed SDNExpress VMM using the deployment scripts successfully but I am unable to get an Outbound Nat connection. My tenant VM’s are able to ping each other in the isolated VM network.
I had a Jumbo packet issue on the physical switch which is now resolved and when I now run
Test-LogicalNetworkSupportsJumboPacket on each of the hosts I get a successful reply for payload data 1632
I’m still unable to get an outbound NAT connection. What else could be stopping the connectivity ?
Management Network: 172.16.0.0./16
Transit Network: 10.20.0.0/23
HNV Network: 10.10.0.0/23
3 x Hyper-V Hosts connected to a Management vNIC with a Gateway of 172.16.0.254
3 x NC VM’s connected to Management Lan with a Gateway of 172.16.0.254
3 x SLB/Muxes connected to Management Lan, Transit Lan and HNV Lan with a Gateway of 10.20.0.1 (Windows VM Router)
3 x Gateway VM’s connected to Management Lan, Transit Lan and HNV Lan with a Gateway of 10.20.0.1
Running Get-BGPPeer from the Windows Router VM returns a connected status to all 3 SLB/Muxes and all 3 Gateway VM’s.
Running Get-BGPRouteinformation returns the PrivateVIP address mapped to each SLB/Mux and the correct next hop using the transit network IP address. It also returns the correct Public IP address that was assigned to the Tenant VM Network and mapped to the correct next hop using the transit IP address of the slb/muxes.
Any help would be appreciated. Thanks
Hi
could you provider also a hnv ras gateway for site to site vpn in a multi tenant scenario?
Hi David,
could you provide also a hnv ras gateway for site to site vpn in a multi tenant scenario?
hi
i’ve been working at using SRIOV for slb muxes, but i get an error while creating logical switch
$vfpExtension = get-scvirtualSwitchExtension -Name “MS NC”
New-logicalSwitch -name “example” -EnableSriov $true -SwitchUplinkMode “EmbeddedTeam” -MinimumBandWidth “None” -VirtualSwitchExtensions $vfpExtension
“choose the minimum bandwidth mode that is compatible with switches managed by microsoft NC”
do you have any idea how to fix it,thx