• 3 min read

How to Load-Balance Internal Servers

Editor's Note: This blog post is written by Chris Clayton, program manager on the Windows Azure Customer Advisory Team. I have been working with Windows Azure since 2009. During this time I have had…

Editor’s Note: This blog post is written by Chris Clayton, program manager on the Windows Azure Customer Advisory Team.

I have been working with Windows Azure since 2009. During this time I have had the opportunity to help architect solutions for many customers in large and small organizations. As the solutions grow, I often need to load balance internal servers. At the time of this post, Windows Azure does not have a built-in solution to address load balancing. However, with the introduction of access control lists (ACLs) for public endpoints, I have the ability to achieve this with standard supported Windows Azure services and components.

In my example, I want to load balance a pair of Internet Information Services (IIS) servers running on virtual machines that function as the façade for the internal services that are exposed by using ASP.NET Web API. By creating a public load-balanced endpoint that is shared by each IIS server, I could load balance my queries across them through the use of the standard load balancer in Windows Azure that all public endpoints are accessed through.

I was concerned that anyone on the Internet would be able access my services. But by applying an ACL to the endpoint, I could restrict access to only my cloud service. The ACL adds limits so that only queries coming from within my cloud service can access the load-balanced endpoint, as shown in the following graphic.

8304.a.jpg-550x0

This was great! It was almost too easy. So I spent some time considering the implications of my decision, and here are the pros and cons that I came up with:

Pros

  • I achieved a load-balanced ASP.NET Web API tier without requiring me to look for a partner solution.
  • I used services and features that are supported by Microsoft, which provided me with a supported construction to do exactly what I wanted.
  • I discussed my solution with the product team, and they agreed that it is a supported implementation at this time because they do not currently offer this feature.

Cons

  • The number of public ports that can be created on a cloud service in Windows Azure is currently 25 and this will be counted as one of them.
  • All of the communications from a single cloud service will come from the same public IP address. This means that all of the clients will share the same 64 K connection limit that is imposed by TCP. This limit is applied to connections from the same source port and source IP address to the same destination port and destination IP address.
  • ACLs are only supported as an infrastructure as a service (IaaS) solution, which leaves me without a platform as a service (PaaS) solution.

Mitigations

As with any solution having cons, there are usually creative ways to mitigate them. I reflected on the first two cons, which are derived from restrictions that are applied to cloud services (for example, a maximum number of public ports and a single IP address per cloud service). I realized that could spread the virtual machines across multiple cloud services. By using a virtual network, I can split them and maintain the ability to communicate. However, this requires configuring additional IP addresses in the ACL.

Step-by-Step Solution

So here is how I set up the load-balancing solution on my two virtual machines…

I started with two virtual machines fully configured for IIS, and I used Windows PowerShell to create the load-balanced endpoint with an ACL assigned on each of them.

7485.b.png-550x0

Going to the dashboard view of the cloud service where my virtual machines are contained, I can quickly find the public IP address that I need to allow. As you can see in the following image of my dashboard, the IP address of my cloud service is 137.135.81.135.

7115.c.png-550x0

I open Windows PowerShell and run the following commands, which leverage the cmdlets in the Windows Azure module. These commands will create a new endpoint on each of the virtual machines that listens on Port 80 and has the ACL set to restrict access to the IP address (137.135.81.135) of my cloud service.

2086.d.JPG-550x0

To test that the load balancer is working for me, I changed the default IIS page to display text that indicates the name of the virtual machine. I try accessing the virtual machine from outside the cloud service. Sure enough! The ACLs are doing their job.

1385.e.png-550x0

I use Remote Desktop to connect to a virtual machine within the cloud service, and I try the same test. This time I see the web site with the name of the virtual machine.

5852.f.png-550x0

I force the page to constantly refresh, and I notice that the name of the virtual machine changes as the load balancer handles my request.

Through a composition of the existing supported services that are available within Windows Azure, I created the ability to load balance my internal IaaS virtual machines. This solution has some caveats (as mentioned earlier in this post); but in my opinion, it is very acceptable for many situations.

I appreciate your feedback. Feel free to email me at Chris Clayton.