Powering your Amazon ECS Clusters with Spot Fleet
My colleague Drew Dennis sent a nice guest post that shows how to use Amazon ECS with Spot fleet.
There are advantages to using on-demand EC2 instances. However, for many workloads, such as stateless or task-based scenarios that simply run as long as they need to run and are easily replaced with subsequent identical processes, Spot fleet can provide additional compute resources that are more economical. Furthermore, Spot fleet attempts to replace any terminated instances to maintain the requested target capacity.
Amazon ECS is a highly scalable, high performance, container management service that supports Docker containers and allows you to run applications on a managed cluster of Amazon EC2 instances easily. ECS already handles the placement and scheduling of containers on EC2 instances. When combined with Spot fleet, ECS can deliver significant savings over EC2 on-demand pricing.
Why Spot fleet?
Amazon EC2 Spot instances allow you to bid on spare Amazon EC2 computing capacity. Because Spot instances are often available at a discount compared to On-Demand pricing, you can significantly reduce the cost of running your applications. Spot fleet enables customers to request a collection of Spot instances across multiple Availability Zones and instance types with a single API call.
The Spot fleet API call can specify a target capacity and an allocation strategy. The two available allocation strategies are lowest price and diversified. Lowest price means the instances are provisioned based solely on the lowest current Spot price available while diversified fulfills the request equally across multiple Spot pools (instances of the same type and OS within an Availability Zone) to help mitigate the risk of a sudden Spot price increase. For more information, see How Spot Fleet Works.
Using Spot fleet
The Spot fleet console is available at https://console.aws.amazon.com/ec2spot/home. It provides a simple approach to creating a Spot fleet request and setting up all necessary attributes of the request, including creating an IAM role and base64-encoding user data. The console also provides the option to download the request JSON, which can be used with the CLI if desired.
If you prefer not to use the Spot fleet console, you need to make sure you have an IAM role created with the necessary privileges for the Spot fleet request to bid on, launch, and terminate instances. Note that the iam:PassRole action is needed in this scenario so that Spot fleet can launch instances with a role to participate in an ECS cluster. You need to make sure that you have an AWS SDK or the AWS CLI installed.
This post assumes you are familiar with the process of creating an ECS cluster, creating an ECS task definition, and launching the task definition as a manual task or service. If not, see the ECS documentation.
Creating a Spot fleet request
Before you make your Spot fleet request, make sure you know the instance types, Availability Zones, and bid prices that you plan to request. Note that individual bid prices for various instance types can be used in a Spot fleet request. When you have decided on these items, you are ready to begin the request. In the screenshot below, a fleet request is being created for four c4.large instances using an Amazon Linux ECS-optimized AMI. You can obtain the most up-to-date list of ECS optimized AMIs by region in the Launching an Amazon ECS Container Instance topic.
Notice the very useful warnings if your bid price is below the minimum price to initially launch the instance. From here, you can also access the Spot pricing history and Spot Bid Advisor to better understand past pricing volatility. After choosing Next, you see options to spread the request across multiple zones, specify values for User data, and define other request attributes as shown below. In this example, the user data sets the ECS cluster to which the ECS container agent connects.
Other examples could create a Spot fleet request that contains multiple instance types with Spot price overrides for each instance type in a single Availability Zone. The allocation strategy could still be diversified, which means it will pull equally from the two instance-type pools. This could easily be combined with the previous example to create a fleet request that spans multiple Availability Zones and instance types, further mitigating the risk of Spot instance termination.
Running ECS tasks and services on your Spot fleet
After your instances have joined your ECS cluster, you are ready to start tasks or services on them. This involves first creating a task definition. For more information, see the Docker basics walkthrough. After the task definition is created, you can run the tasks manually, or schedule them as a long-running process or service.
In the case of an ECS service, if one of the Spot fleet instances is terminated due to a Spot price interruption, ECS re-allocates the running containers on another EC2 instance within the cluster to maintain the desired number of running tasks, assuming that sufficient resources are available.
If not, within a few minutes, the instance is replaced with a new instance by the Spot fleet request. The new instance is launched according to the configuration of the initial Spot fleet request and rejoins the cluster to participate and run any outstanding containers needed to meet the desired quantity.
In summary, Spot fleet provides an effective and economical way to add instances to an ECS cluster. Because a Spot fleet request can span multiple instance types and Availability Zones, and will always try to maintain a target number of instances, it is a great fit for running stateless containers and adding inexpensive capacity to your ECS clusters.
Auto Scaling and Spot fleet requests
Auto Scaling has proven to be a great way to add or remove EC2 capacity to many AWS workloads. ECS supports Auto Scaling on cluster instances and provides CloudWatch metrics to help facilitate this scenario. For more information, see Tutorial: Scaling Container Instances with CloudWatch Alarms. The combination of Auto Scaling and Spot fleet provides a nice way to have a pool of fixed capacity and variable capacity on demand while reducing costs.
Currently, Spot fleet requests cannot be integrated directly with Auto Scaling policies as they can with Spot instance requests. However, the Spot fleet API does include an action called ModifySpotFleetRequest that can change the target capacity of your request. The Dynamic Scaling with EC2 Spot Fleet blog post shows an example of a scenario that leverages CloudWatch metrics to invoke a Lambda function and change the Spot fleet target capacity. Using ModifySpotFleetRequest can be a great way to not only fine-tune your fleet requests, but also minimize over-provisioning and further lower costs.
Amazon ECS manages clusters of EC2 instances for reliable state management and flexible container scheduling. Docker containers lend themselves to flexible and portable application deployments, and when used with ECS provide a simple and effective way to manage fleets of instances and containers, both large and small.
Combining Spot fleet with ECS can provide lower-cost options to augment existing clusters and even provision new ones. Certainly, this can be done with traditional Spot instance requests. However, because Spot fleet allows requests to span instance families and Availability Zones (with multiple allocation strategies, prices, etc.), it is a great way to enhance your ECS strategy by increasing availability and lowering the overall cost of your cluster’s compute capacity.