Graceful Light

AWS ECS 부수기

2017-08-12


ECS는 서울 리젼이 아직 없어서 그런가, 구글링해도 사용할만한 데이터가 너무 적었다.
(기초 설명은 잘 되있다. 하지만 Hello World Application을 올리려고 ECS를 쓰는 건 아니니까..)

용어

Cluster

Amazon ECS 클러스터는 작업을 배치할 수 있는 컨테이너 인스턴스의 논리적 그룹화입니다.
이 공식 설명을 보고 Cluster에 대한 감을 잡기가 쉽지 않았다.

간단히하면 Docker Container를 올리는 EC2 Instance이다.

Task

Task는 작업이라고 번역되며, 하나의 Task Definition JSON은 하나의 Docker-compose YAML 이라고 보자.

Service

Amazon ECS는 단일 ECS 클러스터에서 작업 정의에 지정된 수(“원하는 개수”)의 인스턴스를 동시에 실행 및 관리할 수 있게 해줍니다.
어떤 이유로 작업이 실패 또는 중지되는 경우 Amazon ECS 서비스 스케줄러가 작업 정의의 다른 인스턴스를 시작하여 이를 대체하고 서비스의 원하는 작업 수를 유지합니다.

Task를 자동으로 관리할 수 있게 하는 기능, LB나 Auto Scaling 모두 여기서 적용이 된다.

Repository

AWS Docker 레지스트리 서비스로 AWS Private DockerHub라고 보자.

볼륨 생성

-v 또는 –volume으로 Host의 폴더를 Mount하는 기능이 꼭 필요한데, 설정 창에선 찾기가 너무 힘들었다.
ECS에서는 작업 정의 생성 시에 하단에 볼륨 추가 를 꼭 먼저 클릭해 볼륨부터 추가해야한다.

이름엔 –name 옵션 사용하듯이 닉네임을 넣고
소스 경로엔 Host directory 경로를 넣자.

추가가 되면 컨테이너 추가 시에 탑재 지점 메뉴의 소스 볼륨 select box에서 선택할 수 있다.

이 짓을 하는 것보단 공식 문서의 Task Definition JSON Parameter를 보고 JSON으로 때려박는게 편하다.

예시 JSON은 아래와 같다.
(3306과 3307을 열고 Host의 Data 폴더를 Mount하는 기본 구성의 MariaDB Image)

mariadb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
{
"requiresAttributes": [
{
"value": null,
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.21",
"targetId": null,
"targetType": null
}
],
"taskDefinitionArn": "your task definition arn",
"networkMode": "bridge",
"status": "ACTIVE",
"revision": 3,
"taskRoleArn": null,
"containerDefinitions": [
{
"volumesFrom": [],
"memory": null,
"extraHosts": null,
"dnsServers": null,
"disableNetworking": null,
"dnsSearchDomains": null,
"portMappings": [
{
"hostPort": 3306,
"containerPort": 3306,
"protocol": "tcp"
},
{
"hostPort": 3307,
"containerPort": 3307,
"protocol": "tcp"
}
],
"hostname": null,
"essential": true,
"entryPoint": null,
"mountPoints": [
{
"containerPath": "/var/lib/mysql",
"sourceVolume": "dbdata",
"readOnly": null
}
],
"name": "maria",
"ulimits": null,
"dockerSecurityOptions": null,
"environment": [
{
"name": "MYSQL_DATABASE",
"value": "db"
},
{
"name": "MYSQL_PASSWORD",
"value": "db_pw"
},
{
"name": "MYSQL_ROOT_PASSWORD",
"value": "root_pw"
},
{
"name": "MYSQL_USER",
"value": "db_user"
}
],
"links": null,
"workingDirectory": null,
"readonlyRootFilesystem": false,
"image": "mariadb:latest",
"command": [
"mysqld",
"--character-set-server=utf8",
"--collation-server=utf8_general_ci"
],
"user": null,
"dockerLabels": null,
"logConfiguration": null,
"cpu": 0,
"privileged": null,
"memoryReservation": 500
}
],
"placementConstraints": [],
"volumes": [
{
"host": {
"sourcePath": "/ecs/dbdata"
},
"name": "dbdata"
}
],
"family": "mariadb"
}

고민

Container를 Task별로 생성해야하는데, 그럼 Task JSON에서 link 옵션을 연결할 수가 없다. 이 경우엔 어떻게 Task Definition을 짜야되나?
EC2에 접근해서 매번 link를 생성해서 다시 올려야되나?

이 부분을 해결하기 위해선 ecs-task-kite를 사용하거나 VPC를 구성해 수동으로 연결해 주는 방법 밖에 없다.

쉬운 방법으로 가자면 DB는 (모든 컨테이너가 하나의 데이터를 바라봐야하는) RDSElastiCache처럼 AWS의 서비스 사용하고 VPC를 구성해 Backend, Frontend 단의 서버만 ECS Task를 만들어서 가변적으로 돌리는 게 좋아보인다.

물론 동기화를 할 수도 있는데… 삽질할 시간에 더 잘 나온 포스팅을 기다려본다.

여담

그냥 모니터링 컨테이너 하나 더 띄우고, HAProxy 컨테이너 올리고 EC2에 다 때려박고 싶다.

AWS Korea week in review에 소개되었다.

🍺

Buy me a beer 🍗

공유하려면 QR코드를 스캔해주세요