Skip to content

searchmetrics/ecs-workshop

Repository files navigation

ECS WORKSHOP

This workshop aims to provide an overview for basic ECS operation. For a full and more complete workshop, please check https://ecsworkshop.com/

Requirements

AWS CLI: It can be installed here: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html

Docker: https://docs.docker.com/get-docker/

Credentials

Use aws-azure-login cli or the provided credentials

Overview on ECS

AWS workshop: https://ecsworkshop.com/introduction/ecs_basics/

Internal Wiki:

Clone the repository

git clone https://github.com/searchmetrics/ecs-workshop.git
cd ecs-workshop

Checkout the running cluster

Brief on ASG and Spot.io options

Create ECR

To create an ECR repository we can run the following command:

aws ecr create-repository --repository-name workshop-<name>

Replace with your name.

This will produce an output similar to this one:

{
    "repository": {
        "repositoryArn": "arn:aws:ecr:eu-west-1:123456789000:repository/workshop-mls",
        "registryId": "123456789000",
        "repositoryName": "workshop-mls",
        "repositoryUri": "123456789000.dkr.ecr.eu-west-1.amazonaws.com/workshop-mls",
        "createdAt": 1502712474.0,
        "imageTagMutability": "MUTABLE",
        "imageScanningConfiguration": {
            "scanOnPush": false
        }
    }
}

Please take a note of the repositoryUri and registryId, in the case above is 123456789000.dkr.ecr.eu-west-1.amazonaws.com/workshop-mls and 123456789000.

Push an image

Once we create the ECR repository, we can build an example image and push it to the new repository, but first, lets login to the AWS ECR:

aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin <registryId>.dkr.ecr.eu-west-1.amazonaws.com

Replace with the newly created repository Id After login, we can build the image:

docker build -t <repositoryUri> -f Dockerfile .

Replace with the newly created repository URI.

Once the build is done, we can push the image:

docker push <repositoryUri>

Replace with the newly created repository URI.

Create a Task definition

To create the task definition, first lets edit the file simple-task.json and replace the image value with our repositoryUri:

{
  "containerDefinitions": [
    {
      "name": "nginx",
      "image": "<repositoryUri>",
...

Once this is complete, we can create the task definition with the following command:

aws ecs register-task-definition --family workshop-<name>  --cli-input-json file://simple-task.json

Replace with your name.

This will produce an output similar to this one:

{
    "taskDefinition": {
        "taskDefinitionArn": "arn:aws:ecs:eu-west-1:123456789000:task-definition/workshop-mls:1",
        "containerDefinitions": [
            {
                "name": "nginx",
                "image": "123456789000.dkr.ecr.eu-west-1.amazonaws.com/workshop-mls",
                "cpu": 0,
                "memory": 128,
                "portMappings": [
                    {
                        "containerPort": 80,
                        "hostPort": 0,
                        "protocol": "tcp"
                    }
                ],
                "essential": true,
                "environment": [],
                "mountPoints": [],
                "volumesFrom": []
            }
        ],
        "family": "workshop-mls",
        "revision": 1,
        "volumes": [],
        "status": "ACTIVE",
        "placementConstraints": [],
        "compatibilities": [
            "EC2"
        ]
    }
}

Please take a note of the taskDefinitionArn, in the case above is arn:aws:ecs:eu-west-1:123456789000:task-definition/workshop-mls:1.

Now, lets run the task definition as a simple task in our cluster:

aws ecs run-task --cluster ecs-workshop --count 1 --task-definition <taskDefinitionArn>

Now we can access the ECS cluster and check our task under the tasks tab by typing your name in the search bar. When you access the task information page, you can expand the container to view which host port the container is mapped and after enable access to that port, you can try to access the ip:port provided.

Add variables

With this run, lets check the example with a environment variable.

This time, lets edit the file withvars-task.json, once again replace the image value with our repositoryUri and replace the value for the variable SMWORKSHOP with your name:

{
  "containerDefinitions": [
    {
      "name": "nginx",
      "image": "<repositoryUri>",
      "cpu": 0,
      "memory": 128,
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 0,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      "environment": [
        {
          "name": "SMWORKSHOP",
          "value": "<name>"
        }
      ]
    }
  ]
}

Then we can register our new task, get the new taskDefinitionArn and execute the run-task command again with the new file:

aws ecs register-task-definition --family workshop-<name>  --cli-input-json file://simple-task.json

Note that the task arn have a number increment

Execute the run-task using the new revision.

aws ecs run-task --cluster ecs-workshop --count 1 --task-definition <taskDefinitionArn>

This time we will be able to see a new task and in its information page we can see our environment variable

Create a Service

Now lets create an ecs service to manage our task lifecycle.

First step, lets create the task:

aws ecs create-service --cluster ecs-workshop --desired-count 1 --service-name workshop-<name> --task-definition <taskDefinitionArn>  

Here we can check and discuss the main differences from scheduling the container using Service x stand alone task.

Attach to LB

In order to expose our services to the internet, we need to recreate them, but this time we will use a load balancer and direct traffic based on host-header.

First we need to create target group for our service:

aws elbv2 create-target-group --name workshop-<name>  --protocol HTTP --port 80 --target-type instance --health-check-interval-seconds 10 --health-check-timeout-seconds 5 --healthy-threshold-count 2 --vpc-id <vpc_id>

vpc_id will be provided by the meeting host

This will generate an output like the following:

{
    "TargetGroups": [
        {
            "TargetGroupArn": "arn:aws:elasticloadbalancing:eu-west-1:123456789000:targetgroup/workshop-mls2/15a9e0c1b1414df9",
            "TargetGroupName": "workshop-mls",
            "Protocol": "HTTP",
            "Port": 80,
            "VpcId": "vpc-123456789000",
            "HealthCheckProtocol": "HTTP",
            "HealthCheckPort": "traffic-port",
            "HealthCheckEnabled": true,
            "HealthCheckIntervalSeconds": 10,
            "HealthCheckTimeoutSeconds": 5,
            "HealthyThresholdCount": 2,
            "UnhealthyThresholdCount": 2,
            "HealthCheckPath": "/",
            "Matcher": {
                "HttpCode": "200"
            },
            "TargetType": "instance"
        }
    ]
}

Keep note of the TargetGroupArn

Now lets create your listener rule which tells the Load balancer to forward traffic to the new target group. First lets edit the conditions-host.json and replace with your name:

[
    {
        "Field": "host-header",
        "HostHeaderConfig": {
            "Values": ["<REPLACE>.ecs.src.hm"]
        }
    }
]

Then we can create the listener rule by running the command below:

aws elbv2 create-rule --listener-arn <listener_arn> --priority <priority> --conditions file://conditions-host.json --actions Type=forward,TargetGroupArn=<TargetGroupArn>

listener_arn will be provided by the host

priority should be different among the participants

Replace with the one previously created

Once you have prepared the target group and the listener rule, we can recreate our service. First, lets delete the previous service:

aws ecs delete-service --cluster ecs-workshop --force --service workshop-<name>

Now lets recreate the service with loadbalancer support:

aws ecs create-service --cluster ecs-workshop --desired-count 1 --service-name workshop-<name> --task-definition <taskDefinitionArn> --load-balancers targetGroupArn=<TargetGroupArn>,containerName=nginx,containerPort=80

Replace with the one previously created

Now you can access your service at http://name.ecs.src.hm

Access the instance

This is a visual part where we use AWS SSM session manager through the ec2 console to connect to the instance.

See logs and exec into the container

To view logs, we have many options, from plain docker logs, to cloudwatch or datadog. Here we will discuss the possibilities and get logs from the instance access.

After access the instance using AWS SSM session manager, we can run the following commangs:

sudo docker ps | grep <name>

This will give you all runing containers with your name, where you can use one of the containers id to get logs:

sudo docker logs <container_id>

You can access the service url and generate some 404 requests http://name.ecs.src.hm/error, you will notice new events.

Metrics

Lets go through the metrics that ECS offers

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published