📜 ⬆️ ⬇️

Amazon EC2 Autoscale Load Balancer

Many people know that Amazon provides the ability to automatically increase the power of your pool (increase the number of virtual servers) depending on the load. However, I could not find an explanatory description of the practical implementation of such a scheme in the Russian-speaking segment of the network. I would venture to present to the public the result of my studies on this topic.

So, the input data. Our server, judging by the attendance curve, will soon begin to experience very severe loads, especially at peak times. To efficiently handle the traffic, as well as to avoid denial of service, it was decided to use the mechanisms provided by Amazon, which allow the necessary number of servers to be started in real time. At the same time, when the load decreases, the resulting pool should “slow down”, automatically decreasing in size, and thereby reduce the financial costs of the project.


For all this, we picked up a virtual server (EC2 instance in Amazon terminology, then I will sometimes use a vulgar tracing from English - “instance”), on which we configured all the necessary software. It is important that everything be done so that the software does not need any additional configuration, and such identical machines could be started as much as necessary, without causing any conflicts, because the instance starts from the finished fixed impression. Such a server in our project will serve as a multiple front-end, on which the load will be balanced by means of Amazon, while the database is stored separately, and the content of users (for example, uploaded photos and avatars) is generally stored on Amazon S3.
')
Well, we believe that the reference front-end is ready for us, we can proceed.

This is how the scheme will look like from a certain distance:
image

1. First, remove the image from the reference instance


The quickest way to do this is through the AWS management console, i.e. via web interface. To do this, go to the menu item ELASTIC BLOCK STORE -> Snapshots and take a new snapshot from the volume of our front-end. Then, by right-clicking on the resulting snapshot, select the item “Create image from snapshot” to get an image (so-called AMI) for further cloning. When creating an AMI, it is important to specify the correct (same as in the reference instance) Kernel ID, otherwise there is a chance that AMI will simply not start.

2. Install the necessary tools for working with balancer and autoscaling


Actually, you can manage your farm absolutely from any computer, we chose one of the servers with Ubuntu for ourselves, so I’ll give examples of settings for this OS.

2.1. Put java (if not already installed) and write the JAVA_HOME environment variable

 apt-get install default-jdk 


Add a line to / etc / environment (in this case)
 JAVA_HOME="/usr/lib/jvm/java-6-openjdk" 


Next, we put the Amazon toolkit. I put it in the / opt directory, and make symbolic links to make it easier to find the necessary folders in the future, but this is of course a matter of taste.

2.2. Let's put the Amazon toolkit to adjust the balancer

 wget http://ec2-downloads.s3.amazonaws.com/ElasticLoadBalancing.zip unzip ElasticLoadBalancing.zip mv ElasticLoadBalancing-1.0.15.1 /opt/ ln -s /opt/ElasticLoadBalancing-1.0.15.1 /opt/ELB 


Add environment variables (I do this by editing / etc / environment)
in the PATH variable you need to add the path "/ opt / ELB: / opt / ELB / bin"

Add AWS_ELB_HOME variable there:
 AWS_ELB_HOME="/opt/ELB" 


Create a file / opt / ELB / credential-file, where to put your AWS credentials (if you do not know what it is - see AWS management console -> Security credentials) in the format:
 AWSAccessKeyId=xxx AWSSecretKey=xxx 


 chmod 600 /opt/ELB/credential-file 


Add in / etc / environment the variable AWS_CREDENTIAL_FILE:
 AWS_CREDENTIAL_FILE="/opt/ELB/credential-file" 


2.3. Install Amazon Toolkit for Autoscaling

 wget http://ec2-downloads.s3.amazonaws.com/AutoScaling-2011-01-01.zip unzip AutoScaling-2011-01-01.zip mv AutoScaling-1.0.39.0 /opt/ ln -s /opt/AutoScaling-1.0.39.0/ /opt/AS 


Add environment variables in / etc / environment - the path "/ opt / AS: / opt / AS / bin" must be added to the PATH variable

Add the AWS_AUTO_SCALING_HOME variable there:
 AWS_AUTO_SCALING_HOME="/opt/AS" 


2.4. Install Amazon Toolkit for Monitoring Settings.

 wget http://ec2-downloads.s3.amazonaws.com/CloudWatch-2010-08-01.zip unzip CloudWatch-2010-08-01.zip mv CloudWatch-1.0.12.1 /opt/ ln -s /opt/CloudWatch-1.0.12.1/ /opt/CW 


Add environment variables in / etc / environment - add the path "/ opt / CW: / opt / CW / bin" to the PATH variable

Add the AWS_CLOUDWATCH_HOME variable there:
 AWS_CLOUDWATCH_HOME="/opt/CW" 


2.5. Checking the installed toolkit

To check the variables set in / etc / environment, you can re-login or re-read them in any way.
We give commands:
 elb-cmd --help 

 as-cmd --help 

 mon-cmd --help 

Each of them must issue a certificate, or if there were any errors during installation, point them out.

3. Let's go. Actually configure the load balancer with autoscaling


3.1. We create a balancer


 elb-create-lb myLB --headers --listener "lb-port=80,instance-port=80,protocol=http" --region us-west-1 --availability-zones us-west-1c 


Where myLB is the name of our balancer
--listener "lb-port = 80, instance-port = 80, protocol = http" - listen to port 80, send traffic to port 80 on the target instance and use the http protocol
--region us-west-1 region, where the balancer will be raised
--availability-zones us-west-1c zone where the balancer will be raised

In response, we get something like:
 DNS_NAME DNS_NAME DNS_NAME myLB-108660279.us-west-1.elb.amazonaws.com 

This is the address of our future balancer.

3.2. Create a validation test for the balancer (healthcheck)

This is a test by which the balancer understands that the target instance is already heavily loaded and transfers traffic to the next instance.
 elb-configure-healthcheck myLB --headers --target "HTTP:80/" --interval 30 --timeout 10 --unhealthy-threshold 2 --healthy-threshold 2 --region us-west-1 


where myLB is the name of our balancer
--headers is an optional parameter that includes the display of field names in the description of this healthchek
--target "HTTP: 80 /" - protocol: port / URI to check
--interval 30 - check interval (check every 30 seconds)
--timeout 10 - timeout, if exceeded - the instance feels rather bad
--unhealthy-threshold 2 - how many checks to do before finally making sure that the instance is unhealthy
--healthy-threshold 2 - how many checks to do before finally making sure that the instance is healthy
--region us-west-1 - location

If the command is successful, we will get something like this:
 HEALTH_CHECK TARGET INTERVAL TIMEOUT HEALTHY_THRESHOLD UNHEALTHY_THRESHOLD HEALTH_CHECK HTTP:80/index.html 30 10 2 2 


3.3. Create a configuration for launching a new instance when autoscaling

 as-create-launch-config myAS --image-id ami-fd015fb8 --kernel aki-9ba0f1de --key ubuntu --group ubuntu-new --region us-west-1 --instance-type m1.xlarge 


Where myAS is the configuration name
--image-id XXX - ID of the nugget (AMI) created in step 1
--kernel XXX - Kernel ID for AMI created in step 1
--key XXX - the name of your access key
--group XXX - the name of the security group - a set of firewall rules for access to this instance
--instance-type XXX - type of instance launched
--region us-west-1 - region

In the case of a successful configuration, we get the following output:
 OK-Created launch config 


3.4. We describe the properties of the server pool during autoscaling, bind the pool to the balancer

 as-create-auto-scaling-group myASG --launch-configuration myAS --availability-zones us-west-1c --min-size 1 --max-size 20 --load-balancers myLB --grace-period 500 --health-check-type ELB --region us-west-1 


Where myASG is the pool name
--launch-configuration myAS - the configuration name to run from the previous step
--min-size 1 - minimum pool size
--max-size 20 max pool size
--load-balancers myLB - binding to balancer
--grace-period 300 is an important parameter that indicates how many seconds after the start of a new instance it can be loaded. For example, after the start, I have a deployment application, so this period is quite long
--health-check-type ELB is a healthchek type, in our case Elastic Load Balancer
--region us-west-1 - location
--availability-zones us-west-1c - zone

3.5. We describe the growth policy of the pool

 as-put-scaling-policy myUp-policy -auto-scaling-group myASG --adjustment=1 --type ChangeInCapacity --cooldown 300 --region us-west-1 


Where myUp-policy is the name of the policy
-auto-scaling-group myASG - name of the server pool to which the policy will apply
--type ChangeInCapacity - type of policy. In this case, the absolute change in the number of servers in the pool. It can also take the values ​​ExactCapacity (the exact value of the new pool size), PercentChangeInCapacity (percentage of the current value of the change in the size of the pool).
--adjustment = 1 - in this case we add one server to the pool
--cooldown 600 - timeout before the next pool size change. It should reasonably correlate with the grace-period parameter (at least be no less) specified in the previous step.
--region us-west-1 region of placement

In response, we get a line - a handle to this policy, something like this:
 arn:aws:autoscaling:us-west-1:033313991904:scalingPolicy:5ae9e75d-4344-4b3f-abb0-c501c7221ecf:autoScalingGroupName/myASG:policyName/myUp-policy 


3.6. Bind pool growth policy to balancer monitoring

 mon-put-metric-alarm MyHighLatAlarm --metric-name Latency --comparison-operator GreaterThanThreshold --evaluation-periods 1 --namespace "AWS/ELB" --period 60 --statistic Average --threshold 80 --alarm-actions arn:aws:autoscaling:us-west-1:033313991904:scalingPolicy:5ae9e75d-4344-4b3f-abb0-c501c7221ecf:autoScalingGroupName/myASG:policyName/myUp-policy --dimensions "LoadBalancerName=myELB"--unit Seconds --region us-west-1 


Where MyHighLatAlarm is the name of the binding
--metric-name Latency is an important parameter. We show that we are actually measuring the delay on the balancer. This metric was created when the balancer was created automatically. (which can be verified by checking the output of the mon-list-metrics command).
--comparison-operator GreaterThanThreshold is a comparison operator, in this case “greater than a threshold value”, may also be “GreaterThanOrEqualToThreshold”, LessThanThreshold ”and“ LessThanOrEqualToThreshold ”
--evaluation-periods 1 - how many times to check the metric before comparing with the threshold
--namespace "AWS / EC2" - namespace (required parameter, why it is not clear)
--period 60 survey period
--statistic average - how we measure the threshold. In this case, by the average, and maybe also “SampleCount”, “Sum”, “Minimum”, “Maximum”
--threshold 80 is the delay threshold itself.
--alarm-actions arn: aws: autoscaling: us-west-1: 033313991904: scalingPolicy: 5ae9e75d-4344-4b3f-abb0-c501c7221ecf: autoScalingGroupName / myASG: policyName / myUp-policy - saying that to achieve the threshold execute policy, described by this descriptor that we created in the previous step.
--dimensions "LoadBalancerName = myLB" - we filter the alarms on this basis.
--unit Seconds - units of measurement
--region us-west-1 - location region.

Uff. Now we have a pool that will respond to the load, adding one server at a time. However, it would be desirable for the pool to “deflate” in response to a decrease in load. To do this, we need to describe the pool reduction policy and bind it to the balancer metric. I will not repeat the details, everything seems to be clear from the syntax:

3.7. Describe the pool reduction policy

 as-put-scaling-policy myScaleDown-policy --auto-scaling-group myASG --adjustment=-1 --type ChangeInCapacity --cooldown 600 --region us-west-1 


We get the policy descriptor:
 arn:aws:autoscaling:us-west-1:033313991904:scalingPolicy:a764b4d4-aff5-4061-ba3a-c35c05ad1d25:autoScalingGroupName/myASG:policyName/myScaleDown-policy 


3.8. Bind a pool reduction policy to balancer monitoring

 mon-put-metric-alarm MyLowLatAlarm --comparison-operator LessThanThreshold --evaluation-periods 1 --metric-name Latency --namespace "AWS/EC2" --period 600 --statistic Average --threshold 20 --alarm-actions arn:aws:autoscaling:us-west-1:033313991904:scalingPolicy:a764b4d4-aff5-4061-ba3a-c35c05ad1d25:autoScalingGroupName/myASG:policyName/myScaleDown-policy ---dimensions "LoadBalancerName=myLB" --unit Seconds --region us-west-1 


4. Contact the balancer by name and patronymic.


Great. Now you can test the whole thing, referring to our balancer according to its public DNS name obtained in step 3.1., In our case myLB-108660279.us-west-1.elb.amazonaws.com

Amazon advises then make a CNAME DNS record indicating the given name for your site's domain:
 www.site.com IN CNAME myLB-108660279.us-west-1.elb.amazonaws.com 

Then you can get on the balancer, simply referring to www.site.com

5. How do we get rid of all this?


Now a few words about how to disassemble this structure (when you play enough with the test version for example), so that it does not eat money in vain (albeit small, but still). This suddenly turned out to be a nontrivial task, since the balancer with scaling did not allow itself to be disassembled, constantly producing new instances and not letting the balancer quench while those same instances hung behind it. In general, the correct sequence of actions was as follows:

get a list of our alarms:
 mon-describe-alarms --region us-west-1 


Let's clean them one by one:
 mon-delete-alarms --region us-west-1 --alarm-name MyHighLatAlarm mon-delete-alarms --region us-west-1 --alarm-name MyLowLatAlarm 


Get a list of our policies:
 as-describe-policies --region us-west-1 


Let's clean them one by one:
 as-delete-policy myScaleDown-policy --auto-scaling-group myASG --region us-west-1 as-delete-policy myUp-policy --auto-scaling-group myASG --region us-west-1 


Here it is, a trick. First it turns out that the group size should be set to zero so that the instances are not undermined:
 as-update-auto-scaling-group myASG --min-size 0 --max-size 0 --region us-west-1 


Now we will wait about five minutes until all the instances have gone out and delete the pool:
 as-delete-auto-scaling-group myASG --region us-west-1 


Delete the configuration:
 as-delete-launch-config myAS --region us-west-1 


Well, finally extinguish the balancer:
 elb-delete-lb myLB --region us-west-1 

Source: https://habr.com/ru/post/136827/


All Articles