Amazon ECS, or EC2 Container Service is a Container Management Service for Docker containers. Similar to Kubernetes in intent, the service allows users to provision Docker containers in a fully managed cluster of EC2s. This post is a quick summary of how to get up and running with your own ECS cluster.

The motivation behind containers is to optimize the usage of underlying resources like CPU and Memory. Containerized infrastructure provides a dense compute environment, allowing us to pack more usage without having to spend $$ for idle/underutilized resources.

Setup

Make sure you have an AWS Account, and the Default VPC. The purpose of this post is a quick start with ECS, and not to suggest a production deployment. Things like VPCs, Security Groups, AMIs, IAM roles, etc. will be completely different in the real world. We will use the default VPC (which has all public subnets), and wide open default Security Groups for Load Balancers and Instances. I am using us-east-1 as reflected by many URLs in this post.

Good familiarity with Docker will be helpful as well.

Terminology

  • Docker is a container platform, which contains a process in a Docker Image. They’re lightweight in terms of provisioning, are ephemeral, and an ideal platform for microservices. Imagine 10 microservices modeled as 10 container images, each hosted under Tomcat. Each container does 1 job, and 1 job only.

  • These containers form the building blocks for tasks. So, 5 running tasks for the same Docker Image would translate to 5 JVMs running the same service on 5 EC2s in the non-docker world. Typical ASG=EC2+ELB scenario for a highly available deployment. Often times tasks and containers are used interchangeably.

  • A cluster is a collection of EC2 instances. These instances run ECS optimized AMIs, and I like to call them hosts to avoid confusion. An instance is a very overloaded term - it could mean an EC2 in a cluster, or a task in the EC2, or an EC2 by itself. The number and type of instances is defined during creation of the cluster. A cluster has the exact same EC2 Instance Type. In other words, we cannot have a ECS cluster with an m3.medium and a r4.xlarge. A cluster can spread across multiple AZs, and for high availability, it should. However, it cannot span across VPCs.

  • A task can be wrapped in a service. A service is a configuration over the task - how many tasks, how to distribute the various tasks within the cluster, autoscaling, and an ALB association. So, a microservice can be instantiated N times in a cluster, creating N containers, where some of those containers can run on the host in us-east-1a, some on the one in us-east-1b. A service looks like an ASG configuration.

  • An ALB is needed for the service, as the task can shift within the hosts in a cluster. Also, based on autoscaling settings on the service, new containers for this service can be spun up. A classic ELB will not work as it has hardwired mapping to the back-end EC2 instances. Imagine 5 completely different tasks running on the same host, each listening to port 8080. In a classic ELB it’d be impossible to port-map dynamically. However, an ALB is associated with a target group, and ECS automatically manages the ALB registry/de-registry of containers.

  • An ECR is EC2 Container Registry, think of it as a private Dockerhub. It works exactly the same way. You build a docker image with docker build, tag it, and push it to a repo in ECR. The repository URI is used to refer the container in the task configuration.

Steps

Push Docker Image

  • First off, we create a Docker image. I have one ready, which runs Tomcat. In the real world, it’d be a war deployed in Tomcat, or a python or node server.

    We can just use the one here -

    $ docker pull lobster1234/tomcat:8.5.20
    
  • Create a repository in ECR by going to https://console.aws.amazon.com/ecs/home?region=us-east-1#/repositories and clicking Create Repository.

  • Push this image onto ECR by creating a new repository, and following the steps on the AWS ECR Console.

  • Once this image is pushed (could take a while to upload 200+ MB), you’ll notice the image show up on ECR. Note the Repository URI as we’ll need it.

Cluster Creation

Task Definition

  • Next, we will create a task definition - this is where the container image we pushed comes in. From the left menu, click Task Definitions, and then click Create new Task Definition.

  • Task Definition Name = my-first-task-definition, leave the rest, and click Add Container.

  • Container Name = my-first-tomcat-container, Image = enter the ECR Repository URI (NOT ARN), Hard Limit = 128, Port Mappings = host 0 container 8080, Protocol = tcp.

  • Click Advanced Container Configuration - CPU Units = 1, Essential = true, and leave the rest of the settings as-is. Click Add. On the Task Definition page, click Create after verifying the newly added container shows up. Notice there can be multiple, different containers per task.

  • Now you should see https://console.aws.amazon.com/ecs/home?region=us-east-1#/taskDefinitions/my-first-task-definition/1 where there is an option to create a new revision, and an Actions drop down.

Service and ALB Creation

  • Next we will create a service using this task definition. Imagine the container image was indeed hosting a real service instead of a just a tomcat installation. We would want this service available across multiple AZs, and also multiple instances of this service within each of the host. So we will do just that. Let us create a service by clicking Create Service from the Actions dropdown.

  • Service Name = my-first-service, Number of Tasks = 5. Leave everything else as-is. In the Task Placement section, pick AZ Balanced Spread (this would mean the tasks, or containers for this service will get spread out across the AZs the hosts are running in).

  • Now we will associate this service with a Load Balancer. Like I mentioned earlier, Classic Load Balancer will not work, so we have to create an Application Load Balancer.

  • Leave the service tab we’re in. Open up a new tab, and point to the EC2 Console https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#LoadBalancers

  • Click Create Load Balancer and pick Application Load Balancer.

  • Name = my-first-ecs-lb, Scheme = Internet Facing, IP Address Type = ipv4, Listeners = HTTP, Port 80, Availability Zones = us-east-1a, us-east-1b, and click Configure Security Settings.

  • Click Next: Configure Security Groups. Select the default security group. Click Next: Configure Routing.

  • Target Group = New target group, Name = my-first-ecs-tg, leave everything else as-is. Click Register Targets. This is where we will pick the EC2s running our containers. Select the 2 EC2 instances which are the part of our cluster, and click Add to Registered. Leave the port as 80. Once the selected Instances show up under Registered Targets, click Next: Review.

  • On the review page, click Create. Click Close on the next screen, and give it a minute to provision the ALB.

  • At this point we go back to the Create Service tab, and click Configure ELB.

  • Select ecsServiceRole for IAM Role for Service. The ALB we just created should show up under the ELB Name. If it does not, click the little button to refresh the drop down. Once the ALB shows up, select it. Then, In the Select a Container, pick the container my-first-tomcat-container:0:8080 and click Add to ELB.

  • This opens up a new section. In the Target Group Name section, select my-first-ecs-tg. Click Save.

  • Review settings, and click Create Service. You’ll see a page showing the Launch Status. Click View Service when it is enabled.

  • On the View Service page, it should show 5 running tasks. Refresh the page if you do not see all 5, as it does take a few seconds for containers to launch.

Verification

Now we have a fully functional ECS Cluster with a service running across all nodes of the cluster, available via an ALB.

Teardown

The fast and easy way is to click Delete Cluster from the Cluster Details page. However, I’ll walk you through the steps that will need some tinkering around and help better understand what goes under the hood.

Summary

In this post, we learnt how to -

  1. Create an ECR Repository, and push a Tomcat Docker image to it
  2. Create an muti-AZ ECS Cluster
  3. Create a Task Definition using this image
  4. Create a Service using this Task Definition
  5. Create a Target Group and ALB for this service
  6. Launch this service in the ECS Cluster using the Balanced Placement Policy
  7. Tear down the ECS Cluster

Thoughts, feedback, ideas? Please let me know in the comments below.

Comments