How to Configure Windows Server 2016 SLB MUX

The Software Load Balancer (SLB) Multiplexer (MUX) is a core component of the Windows Server 2016 SDN stack that provides inbound network address translation and load balancing for virtual IP (VIP) addresses. The SLB MUX runs as a virtual machine on the SDN fabric and works in conjunction with the Network Controller and the SLB Host Agent installed on each Hyper-V host. Together they distribute incoming connections to backend VMs using a consistent hashing algorithm, providing both scalability and high availability.

This tutorial covers how to deploy and configure the SLB MUX on Windows Server 2016, including the preparation of MUX VMs, their registration with the Network Controller, BGP peering configuration, and verification of load balancing functionality.

SLB Architecture

The SLB in Windows Server 2016 SDN has three components: the Network Controller, which stores and distributes load balancing policy; the SLB MUX VMs, which advertise VIP addresses to the physical network using BGP and forward inbound connections to the correct DIP (Direct IP) backend; and the SLB Host Agents on each Hyper-V host, which perform the actual return traffic processing using Direct Server Return (DSR). In the DSR model, return traffic from backend VMs goes directly to the client without traversing the MUX, improving throughput.

Prerequisites

Prepare one or more Windows Server 2016 VMs to serve as SLB MUX nodes. Each MUX VM needs two NICs: one on the management/HNV network and one for BGP peering with the physical network. Install the SLB MUX feature on each VM:

Install-WindowsFeature SoftwareLoadBalancer -IncludeManagementTools

Verify the installation:

Get-WindowsFeature -Name SoftwareLoadBalancer

Step 1 — Create a VIP Logical Network

The VIP logical network defines the public IP address space that will be advertised by the MUX via BGP. Register it with the Network Controller:

$uri = "https://nc.contoso.com"
$headers = @{ "Content-Type" = "application/json" }

$vipNetBody = @{
  properties = @{
    networkVirtualizationEnabled = $false
    subnets = @(@{
      properties = @{
        addressPrefix = "192.0.2.0/24"
        vlanID = 0
      }
    })
  }
} | ConvertTo-Json -Depth 5

Invoke-RestMethod `
  -Uri "$uri/networking/v1/logicalNetworks/PublicVIP" `
  -Method Put `
  -Body $vipNetBody `
  -Headers $headers `
  -UseDefaultCredentials

Step 2 — Register the SLB MUX VM

Register each MUX VM as a load balancer MUX resource in the Network Controller, specifying its BGP peering address and the router it will peer with:

$muxBody = @{
  properties = @{
    connections = @(@{
      managementAddress = "10.10.55.30"
      credential = @{ resourceRef = "/credentials/MuxAdminCred" }
      credentialType = "UsernamePassword"
    })
    networkInterfaces = @(@{
      resourceId = "MUX1-NIC"
      properties = @{
        ipConfigurations = @(@{
          properties = @{
            privateIPAddress = "10.10.56.30"
            privateIPAllocationMethod = "Static"
            subnet = @{ resourceRef = "/logicalNetworks/HNVProvider/subnets/0" }
          }
        })
      }
    })
    virtualServer = @{ resourceRef = "/virtualServers/MUX1-VS" }
    peerBgpInformation = @{
      extAsNumber = "0.64512"
      localIpAddress = "10.10.56.30"
      peerIpAddress = "10.10.56.1"
      peerAsNumber = 64513
      routerName = "TOR-Switch"
    }
  }
} | ConvertTo-Json -Depth 8

Invoke-RestMethod `
  -Uri "$uri/networking/v1/loadBalancerMuxes/MUX1" `
  -Method Put `
  -Body $muxBody `
  -Headers $headers `
  -UseDefaultCredentials

Step 3 — Configure BGP Peering on the Physical Router

The MUX must establish a BGP session with the top-of-rack (ToR) switch or router to advertise VIP addresses. Configure the peer on the router side to accept connections from the MUX IP address. On the MUX VM itself, verify the BGP peer is configured by the Network Controller host agent:

Get-BgpPeer

The peer should show a ConnectivityStatus of Established once the ToR switch accepts the BGP session.

Step 4 — Create a Load Balancer Policy

Define a load balancer resource that maps a VIP to a pool of backend DIPs. First create the load balancer:

$lbBody = @{
  properties = @{
    frontendIPConfigurations = @(@{
      resourceId = "FrontendVIP"
      properties = @{
        privateIPAllocationMethod = "Static"
        privateIPAddress = "192.0.2.10"
        subnet = @{ resourceRef = "/logicalNetworks/PublicVIP/subnets/0" }
      }
    })
    backendAddressPools = @(@{
      resourceId = "WebServerPool"
      properties = @{}
    })
    loadBalancingRules = @(@{
      resourceId = "HTTP-LB-Rule"
      properties = @{
        frontendIPConfiguration = @{ resourceRef = "/loadBalancers/WebVIP/frontendIPConfigurations/FrontendVIP" }
        backendAddressPool = @{ resourceRef = "/loadBalancers/WebVIP/backendAddressPools/WebServerPool" }
        protocol = "TCP"
        frontendPort = 80
        backendPort = 80
        enableFloatingIP = $false
      }
    })
    probes = @(@{
      resourceId = "HTTP-Probe"
      properties = @{
        protocol = "HTTP"
        port = 80
        requestPath = "/health"
        intervalInSeconds = 5
        numberOfProbes = 2
      }
    })
  }
} | ConvertTo-Json -Depth 9

Invoke-RestMethod `
  -Uri "$uri/networking/v1/loadBalancers/WebVIP" `
  -Method Put `
  -Body $lbBody `
  -Headers $headers `
  -UseDefaultCredentials

Step 5 — Add Backend VMs to the Pool

Associate backend VM network interfaces with the load balancer’s backend pool:

$poolMemberBody = @{
  properties = @{
    ipConfigurations = @(
      @{ resourceRef = "/networkInterfaces/WebVM1-NIC/ipConfigurations/0" },
      @{ resourceRef = "/networkInterfaces/WebVM2-NIC/ipConfigurations/0" }
    )
  }
} | ConvertTo-Json -Depth 5

Invoke-RestMethod `
  -Uri "$uri/networking/v1/loadBalancers/WebVIP/backendAddressPools/WebServerPool" `
  -Method Put `
  -Body $poolMemberBody `
  -Headers $headers `
  -UseDefaultCredentials

Step 6 — Verify Load Balancing

Test that connections to the VIP are being distributed to backend VMs:

for ($i = 1; $i -le 10; $i++) {
  Invoke-WebRequest -Uri "http://192.0.2.10/" -UseBasicParsing | Select-Object StatusCode
}

Check the MUX BGP advertisements:

Get-BgpRouteInformation -Type All

Conclusion

The SLB MUX is a critical component of the Windows Server 2016 SDN load balancing architecture. By advertising VIP addresses via BGP, applying Direct Server Return for high throughput, and integrating seamlessly with the Network Controller, the SLB MUX provides enterprise-grade load balancing in a fully software-defined, scale-out model. Deploying multiple MUX VMs in the SDN fabric ensures high availability and allows the load balancing capacity to grow with your application requirements.