As I previously wrote about, Amazon announced a load balancing solution called Elastic Load Balancer. While this may prove to be a great addition to AWS currently none of the GUI tools (including the AWS Console provided by Amazon) have built in functionality to create ELB instances.
So I became motivated to finally get comfortable with the EC2 API, allowing me to call EC2 commands from my windows command line. I wrote a post detailing how to setup your command line environment for the EC2 API here.
Now armed with a load balancing solution and a working windows command line I wanted to delve into ELB and see what it has to offer.
Amazon Web Services in general has excellent documentation. ELB is no exception. Probably the most important document you can read is the ELB Quick Reference Card. This one page sheet shows you all the ELB related commands and their argument options.
First a quick overview of the architecture of ELB. Think of an ELB instance as sitting in front of your EC2 instances. ELB routes traffic to your instances you register to be included with ELB. The ELB instance has it’s own IP address and public DNS name.
As we can see from the diagram the load balancer directs traffic to different instances, even across different availability zones.
One thing to keep in mind is that the requests are balanced between different availability zones and then evenly between the instances of that zone. So if you have 10 instances in us-east-1a and 5 instances in us-east-1b your us-east-1b instances will service twice as much traffic per instance. For that reason it is suggested that you keep your number of instances in each zone roughly equal.
When you create the ELB instance it will give you the public DNS name for the instance. That DNS name will remain the same for the life of the instance. You will want to create a CNAME record in DNS to point your branded URL (www.mysite.com) to the “ugly” DNS name that EC2 provides you.
Creating ELB Instance
To create an ELB instance first ensure that your command line environment is configured to work with the EC2 API and the ELB API. I suggest you read my previous article, Setting Up EC2 Command Line Tools on Windows, if you have never use an EC2 command line tool before.
The command for creating an ELB instance is elb-create-lb. The parameters available on this command are:
|<default>||Name of Load Balancer; I suggest you use the DNS name of your public service you will be exposing through this ELB instance|
|–availability-zones||Comma delimited list of zones to allow registered EC2 instances in|
|–listener “protocol=value, lb-port=value, instance-port=value”||This defines which protocol and port the ELB instance will listen on, and which port on the instances to send the traffic to.You can have as many –listener parameters as you want. For example you could configure an ELB instance to listen on ports 80 and 443.|
First lets create an ELB instance to listen for HTTP traffic:
d:aws>elb-create-lb Test –availability-zones us-east-1a,us-east-1b –listener “protocol=http,lb-port=80,instance-port=80”
As you can see it returns the public DNS name associated with this instance.
Here we create an ELB instance to listen for HTTP and HTTPS traffic:
D:aws>elb-create-lb Test –availability-zones us-east-1a,us-east-1b –listener “protocol=http,lb-port=80,instance-port=80″ –listener “protocol=tcp,lb-port=443,instance-port=443″
Notice on the protocols we specify HTTP for HTTP traffic, but TCP for HTTPS traffic. HTTP and TCP are the only protocols supported.
Create CNAME Record for ELB Instance
When you create an ELB instance it provides you a public DNS name. However they are not user friendly and you will want to create a CNAME record in DNS to redirect your friendly URL to your EC2 hosted website.
How you create the CNAME record depends on who is hosting DNS for you. However here is the output of my test website I configured for this tutorial:
Default Server: ip-172-16-0-23.ec2.internal
If you delete your ELB instance and recreate it you will get a new public DNS name and will have to update your CNAME record.
Register EC2 Instance with Load Balancer
Now that you have an ELB instance you need to register EC2 instances with the load balancer. The command to register an EC2 instance with the ELB instance is elb-register-instances-with-lb. The parameters available on this command are:
|<default>||Name of Load Balancer instance to register EC2 instances with.|
|–instances||Comma separated list of instance ID’s|
First we need to get a list of our instances because we need the instance ID to register them with the ELB instance. We do this with ec2-describe-instances from the EC2 API:
<Lots of Stuff>
INSTANCE i-ed156e84 ami-da4daab3
<Lots of Stuff>
INSTANCE i-ef156e86 ami-da4daab3
<Lots of Stuff>
I removed quite a bit from the actual output to help with readability. The part you want to focus on is where it says “INSTANCE i-**********”. That is the information you need for each instance.
To register your instances you run the command elb-register-instances-with-lb:
D:aws>elb-register-instances-with-lb Test –instances i-ed156e84, i-ef156e86
You pass it the name of your ELB instance (Test in this case) and a comma separated list of the instance ID’s of your EC2 instances you this load balancer to route traffic to.
To de-register an instance you run the command elb-deregister-instances-from-lb:
D:aws>elb-deregister-instances-from-lb Test –instances i-ed156e84, i-ef156e86
No instances currently registered to LoadBalancer
It takes the same parameters as the register command.
HTTP vs HTTPS
There is not any information on the behavior between HTTP and HTTPS connections available yet. But I can tell you what I have experienced with my limited tests.
When using HTTP (protocol=http) it appears to not have any session stickiness. I loaded two web servers with a Default.htm file. Each file specified which web server I was hitting. When I repeatedly refreshed the page it bounced back and forth between the two servers pretty consistently.
When using HTTPS (protocol=tcp) the session was sticky. In fact I could never get it to fail over to the other node. When I pulled up the page on a different computer though it did pull up the other web server so I know that load balancing was working.
This is far from an extensive test. I expect more detailed tests and hopefully Amazon themselves will provide specifics soon.
Instance Health Checks
A good load balancer needs a way to check that it’s nodes are online and traffic should still be routed to them. Otherwise if a node failed the load balancer would continue to route traffic to them and would cause partial downtime for your site.
ELB checks a file that you specify on a schedule that you specify to determine instance health. You configure this with the elb-configure-healthcheck command. The parameters are:
|<default>||Name of Load Balancer instance to configure health checks on.|
|–target||File to read|
|–interval||How often to perform a health check|
|–timeout||How long to allow the server to respond|
|–unhealthy-threshold||How many consecutive failed checks before marking node as OutOfService|
|–healthy-threshold||How many consecutive successful checks before marking node as InService|
Here is an example of configuring health checks:
D:aws>elb-configure-healthcheck Test –target “HTTP:80/status.htm” –interval 5 –timeout 3 –unhealthy-threshold 2 –healthy-threshold 2
HEALTH-CHECK HTTP:80/status 5 3 2 2
In this example we set the file http://<node IP address>:80/status.htm to be retrieved every 5 seconds. We allow 3 seconds for the web server to respond. If it fails to respond after 2 attempts we take the node out of service, if it responds successfully 2 times we put it back in service.
If we run the command elb-describe-instance-health before we configure health checks we will get the following output:
INSTANCE-ID i-ed156e84 InService
INSTANCE-ID i-ef156e86 InService
However once we enable the health checks we get the following output:
INSTANCE-ID i-ed156e84 OutOfService
INSTANCE-ID i-ef156e86 OutOfService
If we looked out our web server logs we would see that the load balancer tried to read the file status.htm and failed. Once we put that file in place the nodes will go back to being InService. This is important to note when adding this after you are in production. You want to have your check file in place before you enable the monitoring.
You should also set that file to not be included in the log file, or you will have an entry in your logs every few seconds while the load balancer checks it’s health. You should also leave the file blank since there is no reason to increase traffic load with irrelevant data.
Destroying ELB Instance
An ELB instance costs $18/month without even being in use. Not a huge amount of money, but not something you want to be paying for if your not using it.
To delete an ELB instance you run the command elb-delete-lb:
Warning: Deleting a LoadBalancer can
lead to service disruption to any
customers connected to the LoadBalancer.
Are you sure you want to delete
this LoadBalancer? [Ny] y
You may want to run elb-describe-lbs to confirm that you no longer have unnecessary ELB instances in place.
Remember if you delete an ELB instance you will not get the same DNS name when you recreate it. So if you delete it you will have to update your CNAME records to reflect the changes.