Backend port reusability on Azure VM using Azure Load balancer

Objective:

 

Would like to have multiple websites hosted on the same port 80 and 443. These VM's need to be load-balanced with the help of a Azure load balancer in ARM.

 

Assessment:

 

As of today we will not be able to accomplish this setup with the Portal however this setup can be done using PowerShell.

The challenge over here is that we will not able to create multiple load balancing rules with the same backend port unless we have the floating IP enabled. It is possible to create a load balancer with multiple rules having static public IP mapped to each rule as frontend configuration. The floating IP is enabled over the load balancing rule which allow us to use same public port and backend port. 

 

Here is the script that can be used to create a load-balancer with multiple VIP mapped to the load balancing rules:

 

 

#Set Resource group and location. Update to your values.

$RG=’prajarm1’

 

$Location=’west us’

 

New-AzureRmResourceGroup -Name $RG -Location $Location

 

#Create new public IP’s Just update the name for each one you want to add.

 

$PIP1=New-AzureRmPublicIpAddress -Name PIP1 -ResourceGroupName $RG -Location $Location -AllocationMethod Static

 

$PIP2=New-AzureRmPublicIpAddress -Name PIP2 -ResourceGroupName $RG -Location $Location -AllocationMethod Static

 

$PIP3=New-AzureRmPublicIpAddress -Name PIP3 -ResourceGroupName $RG -Location $Location -AllocationMethod Static

 

 

#Creations of the FE Configes Update the number of FE Configs you want to create. This will increase with Public IP’s and be added to the LB as shown down below.

 

$FEConfig=New-AzureRmLoadBalancerFrontendIpConfig -Name FEConfig1 -PublicIpAddressId $PIP1.Id

 

$FEConfig1=New-AzureRmLoadBalancerFrontendIpConfig -Name FEConfig2 -PublicIpAddressId $PIP2.Id

 

$FEConfig2=New-AzureRmLoadBalancerFrontendIpConfig -Name FEConfig3 -PublicIpAddressId $PIP3.Id

 

#Creation of the BEPools

 

$BEPool=New-AzureRmLoadBalancerBackendAddressPoolConfig -Name BEPool

 

#Creation of the LB

 

$lb=New-AzureRmLoadBalancer -Name LBTest1 -ResourceGroupName $RG -Location $Location -FrontendIpConfiguration $FEConfig,$FEConfig1 -BackendAddressPool $BEPool

 

#Updating with the configuration from Azure

 

$lb=Get-AzureRmLoadBalancer -Name LBTest1 -ResourceGroupName $RG

 

#Adding FE Configurations ot the LB

 

$lb.FrontendIpConfigurations.Add($FECOnfig2)

 

$Set=Set-AzureRmLoadBalancer -LoadBalancer $lb

 

#Updating with the configuration from Azure

 

$lb=Get-AzureRmLoadBalancer -Name LBTest1 -ResourceGroupName $RG

 

#Adding Probes

 

$fec=Get-AzureRmLoadBalancerFrontendIpConfig -Name $FEConfig.Name -LoadBalancer $lb

 

$fec1=Get-AzureRmLoadBalancerFrontendIpConfig -Name $FECOnfig2.Name -LoadBalancer $lb

 

$BEP=Get-AzureRmLoadBalancerBackendAddressPoolConfig -Name $BEPool.Name -LoadBalancer $lb

 

$Probe=New-AzureRmLoadBalancerProbeConfig -Name Probe2 -Protocol Tcp -Port 80 -IntervalInSeconds 5 -ProbeCount 2

 

$lb.Probes.Add($Probe)

 

$Set=Set-AzureRmLoadBalancer -LoadBalancer $lb

 

#Getting values from Azure for Rules

$lb=Get-AzureRmLoadBalancer -Name LBTest1 -ResourceGroupName $RG

 

#Need to have $fec1 $fec2 etc for each Front End Config in the Load balancer. Only update the $FECOnfig(1234567).Name for each.

$fec=Get-AzureRmLoadBalancerFrontendIpConfig -Name $FEConfig.Name -LoadBalancer $lb

 

$fec1=Get-AzureRmLoadBalancerFrontendIpConfig -Name $FECOnfig2.Name -LoadBalancer $lb

 

$BEP=Get-AzureRmLoadBalancerBackendAddressPoolConfig -Name $BEPool.Name -LoadBalancer $lb

 

$Probe=Get-AzureRmLoadBalancerProbeConfig -Name Probe2 -LoadBalancer $lb

 

#Adding LB rules

 

$LBRule1=New-AzureRmLoadBalancerRuleConfig -Name Rule1 -FrontendIpConfigurationId $fec.Id -BackendAddressPoolId $BEP.Id -ProbeId $Probe.Id -Protocol Tcp -FrontendPort 80 -BackendPort 80 -EnableFloatingIP

 

$LBRule12=New-AzureRmLoadBalancerRuleConfig -Name Rule1443 -FrontendIpConfigurationId $fec.Id -BackendAddressPoolId $BEP.Id -ProbeId $Probe.Id -Protocol Tcp -FrontendPort 443 -BackendPort 443 -EnableFloatingIP

 

$lb.LoadBalancingRules.Add($LBRule1)

 

$lb.LoadBalancingRules.Add($LBRule12)

 

$Set=Set-AzureRmLoadBalancer -LoadBalancer $lb

 

#Adding LB Rule to FE Config

$lb=Get-AzureRmLoadBalancer -Name LBTest1 -ResourceGroupName $RG

 

$fec1=Get-AzureRmLoadBalancerFrontendIpConfig -Name $FEConfig1.Name -LoadBalancer $lb

 

$Probe=Get-AzureRmLoadBalancerProbeConfig -Name Probe2 -LoadBalancer $lb

 

$LBRule1=New-AzureRmLoadBalancerRuleConfig -Name Rule2 -FrontendIpConfigurationId $fec1.Id -BackendAddressPoolId $BEP.Id -ProbeId $Probe.Id -Protocol Tcp -FrontendPort 80 -BackendPort 80 -EnableFloatingIP

 

$LBRule12=New-AzureRmLoadBalancerRuleConfig -Name Rule2443 -FrontendIpConfigurationId $fec1.Id -BackendAddressPoolId $BEP.Id -ProbeId $Probe.Id -Protocol Tcp -FrontendPort 443 -BackendPort 443 -EnableFloatingIP

 

$lb.LoadBalancingRules.Add($LBRule1)

 

$lb.LoadBalancingRules.Add($LBRule12)

 

 

$Set=Set-AzureRmLoadBalancer -LoadBalancer $lb

 

 

 

This is the same script that is used to create Multi VIP Load-balancer in ARM with few small modifications.

Once the load-balancer is created, we can add the backend VM’s from the Portal. The configuration steps required from azure end is now completed.

 

 

 

 

 

 

From the above screen shot we can notice that both the Rules 1&2 are listening on 80 and 443.

 

As we already know that load balancer with floating IP will not work with the IIS configuration as the VM will directly talk to the source while responding, and this is expected to get dropped.

 

In order to overcome this behavior we need to configure the backend VM’s with the loop back adaptor and enable weakhostreceive and weakhostsend on the loop back adaptor.

 

Hence now we can go ahead and added the loop back adaptor to the backend VM’s by following the below steps.

 

  1. Click Run and type devmgmt.msc at the prompt.
  2. Right-click the server name and select Add legacy hardware.
  3. When you are prompted by the wizard, select Install the hardware that I manually select from a list (Advanced).
  4. Find Network Adapter in the list, and click Next.
  5. From the list of manufacturers, select Microsoft and Microsoft KM-TEST Loopback Adapter . A new network interface is added to your server.

 

Once the loop back adaptors are added, we need to manually specify the load balancer front end config public IP address as the NIC IP address as shown below.  

 

 

 

 

The changes made to the loop back adaptor will not change even though we reboot re-deploy the VM.  

The next step is to enable the weakhostreceive and weakhostsend on the default NIC and the loopback adaptor.

 

 Here are the commands that need to be run from the command prompt:

 

netsh interface ipv4 set interface "Ethernet" weakhostreceive=enabled à Default NIC

netsh interface ipv4 set interface "Ethernet 3" weakhostreceive=enable

netsh interface ipv4 set interface "Ethernet 3" weakhostsend=enable

netsh interface ipv4 set interface "Ethernet 2" weakhostreceive=enable

netsh interface ipv4 set interface "Ethernet 2" weakhostsend=enable

 

Once this is completed, we can then map these loopback adaptors to the respective bindings in IIS configurations as shown.

 

 

 

 

 

 

The above steps needs to be performed on all the VM’s in the load balancer.

With these configurations being set as above, we can go ahead and test the setup.

First website mapped to public IP http://138.91.147.XXX/

 

 

Second website on the same VM and through the same load-balancer mapped to public IP http://52.160.99.XXX/

With the above configuration it is possible to achieve port reusability on the Azure VM and also load-balance the same port with the help of Azure load-balancer.