ECS note

# ECS
## Network mode
### bridge
ECS network mode = bridge means both its name and driver. So, we have to use `link` for inner task communication, name resolve. 

Because the name `bridge` network doesn't have special resolver. Other name network and type = `bridge` provide special resolver for resolve by container name. ECS doesn't create any other named network. If you select network = `bride`, all containers attached in same `name:bridge` network. 

## To avoid DNS resolution failueres EC2
https://aws.amazon.com/premiumsupport/knowledge-center/dns-resolution-failures-ec2-linux/?nc1=h_ls

### Multi process
It's easy. e.g.) create a multi-process container. Contains dnsmasq or unbound and main app by supervisor or S6_overay 

### Single process
if you want to keep single process, 
- create dns resolver container (unbound or ..) 
- run unbound service with `DAEMON` mode and network mode = bridge(-p option) or host 
- to use this resolver, run containar with `--dns` options. `172.17.0.1` (= It's `name:bridge`'s gateway)

__why we cannot use host's local ip address?__
because of even if host's IP:53 send from container, recv(response) from 172.17.x.x. 

## Roles
### ecsServiceRole
Policy: AmazonEC2ContainerServiceRole (AWS Managed)
Trust:

```json
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
### ecsTaskExecutionRole
Policy: AmazonECSTaskExecutionRolePolicy (AWS Managed)
Trust:

```json
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

## ecsEventsRole
Policy: AmazonEC2ContainerService`Events`Role (AWS managed)
Trust:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

## application autoscaling
`Application autoscaling (AppAS)` treat not only `ECS-tasks` but also EMR,Dynamo,... any other services. So, `AppAS` is not a parts of ECS's API. 
ecs-cli ___CAN NOT___ support/config `AppAS`. We must set it via aws-cli or Cfn, teraffom.

### API register-scalable-target 
First, register target ecs-service to `AppAS`. Unfortunately, we cannot set scaling policy rules in this api.

```bash
aws application-autoscaling register-scalable-target \
--service-namespace ecs --resource-id service/<cluster>/<service-name> \
--scalable-dimension ecs:service:DesiredCount
``` 

### API put-scaling-policy
2nd, set scaling-policy. There are no input-UI about `Custom-metrics` in MC.

```json:ecs-autoscaling.json
{
    "PolicyName": "appas-pol",
    "ServiceNamespace": "ecs",
    "ResourceId": "service/<cluster>/<service-name>",
    "ScalableDimension": "ecs:service:DesiredCount",
    "PolicyType": "TargetTrackingScaling",
    "TargetTrackingScalingPolicyConfiguration": {
        "TargetValue": 100,
        "CustomizedMetricSpecification": {
            "MetricName": "<metricName>",
            "Namespace": "<namespace>",
            "Dimensions": [
                {
                    "Name": "<dim-name>",
                    "Value": "<dim-val>"
                }
            ],
            "Statistic": "<statis>"
        },
        "ScaleOutCooldown": 60,
        "ScaleInCooldown": 60,
        "DisableScaleIn": false
    }
}
```

```bash
aws application-autoscaling put-scaling-policy --cli-input-json file://ecs-autoscaling.json
```

## ecs-cli

#### ecs-cli profile
```
ecs-cli configure -c default -r us-west-2 --default-launch-type EC2 --config-name <hoge>
cat  ~/.ecs/config
version: v1
default: default
clusters:
  default:
    cluster: default
    region: us-west-2
    default_launch_type: EC2
  hoge:
    cluster: default
    region: us-west-2
    default_launch_type: EC2
```
#### Imprement aws resources
- SG
- ecsTaskRole
- ecsTaskExecutionRole

#### create files
- docker-compose.yml
- ecs-params.yml

ecs-params ref 
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cmd-ecs-cli-compose.html

#### `ecs-cli compose service`
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cmd-ecs-cli-compose-service.html

```
// Create and Start a project with service:
//   ecs-cli compose service create      : creates ECS.CreateTaskDefinition or gets from FS cache and ECS.CreateService with desiredCount=0
//   ecs-cli compose service start       : invokes ECS.UpdateService with desiredCount=1
//   ecs-cli compose service up          : compose service create ; compose service start. If the compose yml was changed, it updates the service with new task definition 

// List containers in or view details of the project:
//   ecs-cli compose service ps          : calls ECS.ListTasks of this service Modify containers
//   ecs-cli compose service scale       : calls ECS.UpdateService with new count 

// Stop and delete the project
//   ecs-cli compose service stop        : calls ECS.UpdateService with count=0
//   ecs-cli compose service down        : calls ECS.DeleteService
```

### Docker build & Docker Push (ECR) & New TaskDefinition & Service Update
```
docker compose build
ecs-cli push <TAG for ECR>

## task-def only
ecs-cli compose create ...

## deploy new task-def
ecs-cli compose service up  ...
``` 

`ecs-cli compose service up`

If the compose yml was changed, it updates the service with new task definition.
e.g.  
Current Task-Def:1 Scale:2 and update `.yml` files.
Create Task-Def:2 and Scale:2 via new service.



### Multi-Container
- compose ver = 2
- use `links` (`network` will be ignored)

### image: ...
We must set `image:` as ECR's URL.
`ecs-cli push`

## Drop get meta from container
http://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html

## + ALB & Draining
ECS Instance draining  ---- Fine!
Stop task via MC ---- Poor
Docker kill container via ssh --- Poor

We expect ecs(+ALB) smart draining.
When run draining ECS-Instance (container-instance) via management console, it's fine.
But stop `task` from MC or `docker kill` via ssh, not wook fine. Exactly, ALB's status change to draining but container dead immediately.

## Stop `task` or `docker kill`
Eventualy almost same. 
- `docker kill` If target container is essential, ECS stop all container in this task.
- Stop `task` kill all containar in this task.

Each case, deregister from ALB normaly, and kill container before ALB draining finished.
 
## ECS Optimized AMI
http://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html

This ami has two disk. / and docker-pool.
I guess docker images are going to consume / disk spaces.

## boot-strap
http://docs.aws.amazon.com/AmazonECS/latest/developerguide/bootstrap_container_instance.html

## Cluster name
`default` is special cluster-name. Except `default` cluster, you must create empty cluster at first. ECS-agent __CAN NOT__ create cluster. 

### Can not rename cluster name !
Erase /var/lib/ecs/* 

# ServiceDiscovery
## Delete sd
1. `delete-service`
2. `delete-namespace`

`delete-namespaces` delete private hosted zone but not reflected immediately.