안녕하세요. 접수/예약 서비스 개발 및 인프라를 담당하고 있는 백엔드팀 안정민 입니다. 저희 똑닥에서 현재 일부 서비스를 제외하고 주로 사용 중인 AWS의 컨테이너 오케스트레이션 서비스 ECS(Elastic Container Service)에 대해서 살펴보려고 합니다.
Docker에 대한 사전 기초 지식이 어느 정도 필요하므로 아직 Docker에 대해서 아직 잘 모르신다면, Docker에 대해 미리 한번 살펴보신 후 읽어 보시면 좋습니다! 추천 포스팅: 초보를 위한 도커 안내서
ECS란?
ECS(Elastic Container Service)는 AWS에서 제공하는 컨테이너 오케스트레이션 서비스로 여러 어플리케이션 컨테이너를 쉽고 빠르게 실행하고, 컨테이너를 적절하게 분배 및 확장 & 축소 할 수 있도록 도와주는 서비스입니다.
ECS 외에도 오케스트레이션 서비스로는 Docker Swarm, Kubernetes(k8s), Nomad 등 다양한 오케스트레이션들이 존재하지만 각각 장단점이 존재하는데요.
ECS 서비스 같은 경우에는 클러스터를 관리하기 위한 별도의 인스턴스를 구성 & 관리 하지 않아도 되며, 당연히 클러스터 관리에 대한 추가적인 비용도 전혀 없습니다. AWS에서 만든 서비스라 다른 AWS 서비스과 연동 지원도 어느정도 되며 Fargate라는 아주 특별한 녀석(?)도 지원합니다.
물론 Googel의 쿠버네티스에 비해 다소 오케스트레이션에 부족한 기능들도 있지만, ECS에서 제공해주는 정도의 수준만 필요한 경우라면 비용적인 부분이나, 다른 오케스트레이션에 비해 비교적 적은 학습 시간으로 빠르게 여러분들의 서비스를 ECS로 적용할 수 있습니다.
ECS 주요 개념
AWS ECS 서비스 아키텍쳐를 살펴보면 아래와 같이 알고 넘어가야하는 주요 요소들이 있습니다. 한번 살펴볼까요?
Container & Image
ECS는 기본적으로 컨테이너 오케스트레이션 서비스인 만큼 기본적으로 어플리케이션을 Docker 컨테이너에서 실행 되도록 구성 하셔야 합니다.
Docker Container & Image에 대해 다시한번 간단하게 설명하면 컨테이너는 Docker Image라는 읽기 전용 탬플릿을 통하여 생성되는것을 컨테이너라고 하며, 이미지는 컨테이너에 포함되는 모든 구성 요소(runtime base Image, 어플리케이션 소스, 라이브러리 등)을 지정해주는 일반 텍스트 파일인 Docker file을 통하여 빌드 생성합니다. Docker를 사용하면 이제 더 이상 필요한 런타임 환경 구축을 직접 세팅, 어플리케이션 구동에 필요한 라이브러리 설치 및 기타 세팅을 매번 할 필요가 없으며 특정 PC 마다 런타임 환경이나 설치된 라이브러리 버전이 달라 문제가 생기는 것에서 해방될 수 있습니다.
Cluster
ECS의 클러스터는 도커 컨테이너를 실행할 수 있는 논리적인 공간이라고 볼 수 있는데요, 우리가 사용하는 도커 컨테이너는 도커가 설치된 컨테이너 인스턴스에서 컨테이너가 실행되며 이 인스턴스들을 목적에 따라 하나로 묶어주는 것이 바로 클러스터라고 할 수 있습니다.
ECS에서는 이렇게 논리적으로 그룹화된 컨테이너 인스턴스들에게 특정 컨테이너를 띄우고, 증가 시키고 등의 명령을 내려 오케스트레이션을 행할수 있게 되는것이죠. 그리고 논리적인 공간이다 보니 빈 클러스터 즉 컨테이너 인스턴스가 없는 클러스터도 생성이 가능합니다.
물론 컨테이너 인스턴스를 클러스트에 연결 시키고 명령을 전달 즉 오케스트레이션을 하기 위해서는 AWS에서 제공하는 ECS Agent가 컨테이너 인스턴스(EC2)에 설치가 되어있어야 하며, ECS Agent를 통해서 ECS 서비스에서의 오케스트레이션 명령 수행이 가능하게 됩니다.
클러스터 생성 시 빈 클러스터가 아닌 컨테이너 인스턴스 타입과 수를 지정하여 생성한 경우, 기본적으로 ECS Agent가 설치된 AMI로 EC2가 자동 생성되어 클러스터와 연결됩니다.
다시 한번 간단하게 요약 정리해본다면
- 클러스터는 컨테이너 인스턴스(EC2)의 논리적인 그룹화 이다.
- 논리적인 공간이므로, 컨테이너 인스턴스가 없는 빈 클러스터도 생성이 가능하다.
- ECS Agent를 통해 논리적인 클러스터에 연결된다.
Task Definitions & Task
작업(Task)는 컨테이너를 실행하는 최소 단위 입니다. 그렇다고 컨테이너 1개 = Task 1개를 의미하지는 않으며, 최소 1개 이상의 컨테이너로 구성될 수 있으며, 해당 Task 내의 컨테이너는 모두 같은 ECS 클러스터 인스턴스 내에 실행되도록 보장 받습니다. 여러 컨테이너를 하나로 묶어서 실행한다고 생각하면 되며, docker-compose와 비슷한 개념이라고 보시면 됩니다.
작업 정의(Task Definitions)은 위에서 말한 Task를 정의한 작업 정의 입니다. Task 실행 시 Task Role, Docker Netwrok Mode, Docker 실행 명령, CPU/Memory 제한, Logging Driver, Vloum Mount 등의 옵션 설정을 할 수 있으며, 생성 또는 업데이트된 Task Definitions는 모두 Revision Version 이 기록되어 저장 되므로, 특정 Revision Version으로 Task를 Roll back 등을 하고자 할 때 유용합니다.
작업과 작업 정의에 대한 관계를 그림으로 보면 아래와 같습니다.
Service
ECS Cluster에서의 최소 실행 단위는 Task라고 말씀드렸는데요, Task를 실행 하는 방식은 직접 Task Definitions를 이용한 실행과 Service를 이용한 실행 두 가지 방식을 제공합니다. 직접 Task Definitions를 실행하는 방식은 Task에 대한 관리가 되지 않으며, AWS에서 제공하는 다른 서비스 (ELB, AutoScale)등을 이용할 수 없으므로, 대부분 사용하지 않습니다.
Service는 Task Definitions를 이용하여 Task 실행 유형(EC2 or Fargate), 타입(복제 or 데몬), 테스크가 실행 되어야할 작업 개수, 배포 방식(롤링 or Blue Green), 배치 전략, AutoScale 설정 및 컨테이너와 ELB(ALB or NLB)등을 설정하여 Task를 실행 및 관리 하도록 도와줍니다. ECS Cluster에 Task를 관리하는 상위 그룹 개념으로 보시면 됩니다.
서비스에는 EC2, Fargate 두가지 Task 실행 유형을 제공합니다. 실행 유형은 ECS Cluster 내에 EC2 인스턴스 타입의 클러스터에 Task를 실행 할 것인지 또는 Fargate를 이용하여 서비스를 실행할지를 선택하는 것이며, 만일 Fargate를 선택하신다면 이전에 Task Defintions 작성 시 호환성 여부 항목에 Fargate가 선택되어 있어야 합니다. 만일 Fargate로 서비스를 구성하신다면, ECS 클러스터내에 인스턴스가 없어도, Task에 정의한 CPU, 메모리 설정에 따라 관리하는 EC2 인스턴스 없이 Serverless 하게 서비스를 실행할 수 있습니다.
서비스에는 타입은 복제(Replica)와 데몬(Daemon) 두 가지를 제공하며, 복제는 서비스에 정의된 작업 개수 및 AutoScale 설정에 따라 클러스터 인스턴스에 Task가 복제하여 실행하는 방식이며, 데몬은 클러스터 내의 모든 ECS 인스턴스에 무조건 하나씩 실행되는 방식입니다.
마치며
AWS에서 제공하는 Docker 오케스트레이션 서비스중 하나인 ECS가 무엇인지 간단하게 살펴보았는데요, ECS의 클러스터, 작업 & 작업 정의, 서비스에 대해 어느정도 이해가 되셨다면, 직접 ECS 클러스터 생성 부터 시작해서 Docker 컨테이너를 올리는 과정까지 실습해보시면 좋을 것 같습니다.
AWS에서 ECS 서비스 실습을 도와드리기 위해 ECS Workshop 이라는 페이지를 제공합니다. 비록 영문으로만 제공되지만, ECS에 관심이 있으신 분들은 한번 참고하셔서 실습해보시면 좋을것 같습니다.