Canvas 1 Layer 1

ECS의 매니지드 컨테이너 AWS 파게이트 시작하기

요약

AWS 파게이트AWS Fargate는 AWS 리인벤트AWS re:Invent 2017에서 발표된 서비스입니다. 파게이트는 AWS의 매니지드 컨테이너 오케스트레이션 서비스인 ECS와 EKS를 기반으로 작동하는 서비스로, 도커 컨테이너를 EC2 인스턴스 없이 독립적으로 실행할 수 있게 해줍니다. 또한 EC2보다 컴퓨팅 성능을 더 세세하게 선택할 수 있으며, 태스크 단위에서 IAM 롤이나 네트워크 인터페이스를 부여하는 것도 가능합니다. 따라서 파게이트는 서버리스 서비스인 AWS 람다와 EC2 기반의 ECS 컨테이너의 중간 쯤에 위치한 서비스라고 할 수 있습니다. 이 글에서는 ECS를 기반으로 파게이트의 개념과 사용법을 소개합니다.

들어가며: AWS 파게이트(AWS Fargate)

컨테이너 오케이스트레이션은 애플리케이션 배포에 새로운 시대를 열었습니다. AWS ECSAWS Elastic Container Service, CNCF 쿠베르네티스Kubernetes, 도커 스웜Docker Swarm, 아파치 메소스Apache Mesos와 같은 오케스트레이션을 통한 컨테이너 애플리케이션 배포는 빠르게 자리를 잡아가고 있습니다. AWS에서 오케스트레이션 툴을 사용한다면 AWS의 EC2와 같은 컴퓨팅 자원을 묶어서 클러스터로 관리할 것입니다. 이러한 컴퓨팅 자원을 관리하는 작업은 클러스터를 운영하는 데 있어서 가장 까다로운 작업중 하나입니다.

AWS 파게이트AWS Fargate는 작년 AWS 리:인벤트 2017AWS re:Invent 2017에서 발표한 서비스입니다. 이 서비스를 사용하면 AWS에서 제공하는 매니지드 컨테이너 오케스트레이션 서비스인 ECSElastic Container Service를 기반으로 EC2와 같은 별도의 컴퓨팅 자원에 의존하지 않고 컨테이너를 독립적으로 실행할 수 있습니다. 추후에 AWS의 매니지드 쿠베네티스 서비스인 EKSElastic Container Service for Kubernetes를 지원할 예정입니다.

파게이트가 비록 AWS 람다를 대체하기 위한 서비스는 아닙니다만, 파게이트를 사용하면 AWS 람다AWS Lambda와 같이 컴퓨팅 자원에 대한 추가적인 관리 없이 애플리케이션을 실행하는 것이 가능해집니다. 또한 컨테이너를 기반으로하기 때문에 람다에서 지원하는 언어들*보다 훨씬 더 다양한 환경을 그대로 이식하는 것이 가능합니다. EC2 인스턴스보다 vCPU와 RAM을 세세하게 설정할 수 있으며, 컨테이너에 IAM 롤을 지정하거나 ENI를 설정할 수도 있습니다. 현재는 서울 리전에서도 파게이트 서비스를 사용할 수 있습니다.**

* AWS 람다에서는 현재 공식적으로 C#, 고Go, 자바Java, 노드jsNode.js, 파이썬Python, 루비Ruby 등을 지원하고 있습니다.

** 이 글을 처음 작성할 때는 아직 서울 리전을 지원하지 않았습니다. 2018년 11월 7일부터 서울 리전에서도 파게이트를 사용하는 것이 가능합니다. AWS What’s new - 캘리포니아 북부 및 서울 리전에서 AWS Fargate 사용 가능.

이 글에서는 ECS를 기반으로 파게이트를 사용하는 법을 소개하고자합니다.

ECS(Elastic Container Service) 기초

현재 파게이트는 ECS를 기반으로만 사용할 수 있습니다. 따라서 파게이트를 사용하기 위해서는 ECS의 기본적인 개념과 사용법을 이해할 필요가 있습니다. ECS는 AWS에서 제공하는 매니지드 컨테이너 오케스트레이션 서비스로 컨테이너를 기반으로 서비스를 배포 및 운영하는 기능을 제공합니다. 여기서는 ECS의 기본적인 개념들을 짚고 넘어가도록 하겠습니다. ECS에 익숙하다면 넘어가도 무방합니다. ECS에 대한 더 자세한 소개글은 아마존 엘라스틱 컨테이너 서비스(ECS)와 도커(Docker)로 시작하는 컨테이너 오케스트레이션를 참고해주세요.

클러스터Cluster
ECS의 가장 기본적인 단위입니다. 클러스터는 논리적인 개념으로 서비스나 태스크가 실행되는 공간이라고 이해할 수 있습니다. 따라서 클러스터가 없으면 ECS에서 컨테이너를 실행할 수 없습니다. 기본적으로 컴퓨팅 자원을 포함하지 않습니다.
컨테이너 인스턴스Container Instance
컨테이너 인스턴스는 클러스터에서 서비스나 태스크를 실행하기 위해 사용하는 컴퓨팅 자원입니다. EC2 인스턴스에 ecs-agent를 설치하고 클러스터명을 설정해서 특정 클러스터의 컨테이너 인스턴스로 등록할 수 있습니다. 클러스터(스케줄러)는 클러스트 인스턴스를 조작할 수 있는 권한을 가지고 있으며, 클러스터에서 서비스나 태스크를 실행하면 조건을 만족하는 컨테이너 인스턴스를 찾아 컨테이너로 실행합니다. 단, 파게이트를 사용하는 경우 컨테이너 인스턴스 없이 컨테이너를 실행할 수 있습니다.
이미지Image
ECS는 컨테이너 오케스트레이션 도구로 컨테이너를 관리합니다. 컨테이너는 이미지로부터 실행되며, 이미지는 특정 애플리케이션을 실행가능한 환경을 재현하기 위한 파일 집합입니다. 이 이미지는 ECS와는 별개로 생성 및 관리됩니다. 따라서 ECS 사용자는 먼저 자신이 실행하고자 하는 애플리케이션을 이미지로 가지고 있어야합니다. ECS를 사용할 때 이미지는 도커Docker 이미지와 동의어로 봐도 무방합니다. 일반적으로 이미지 빌드 파일은 애플리케이션 저장소에서 Dockerfile로 관리되며, 도커 허브Docker Hub나 ECRElastic Container Registry에 업로드해서 사용합니다.
태스크 디피니션Task Definition
태스크 디피니션은 ECS의 최소 실행 단위인 태스크를 실행하기 위한 설정을 저장하고 있는 리소스입니다. 태스크 디피니션은 하나 혹은 둘 이상의 컨테이너에 대한 정보(컨테이너 디피니션)를 포함할 수 있습니다. 컨테이너 별로 실행하고자 하는 이미지를 지정해야하며, CPU와 RAM과 같은 리소스 제한 정보와 컨테이너 실행에 필요한 옵션들을 지정합니다. 태스크 디피니션은 클러스터에 종속되어있지 않습니다.
태스크Task
태스크는 ECS의 최소 실행 단위로 하나 혹은 둘 이상의 컨테이너의 묶음입니다. 태스크는 독립 실행되거나 서비스에 의해서 실행될 수 있습니다. 클러스터를 선택하고 태스크 디피니션을 지정해서 태스크를 독립적으로 실행할 수 있습니다. 클러스터는 적절한 컨테이너 인스턴스를 찾아 태스크 디피니션을 기반으로 태스크를 실행합니다. 독립적으로 실행된 태스크는 한 번 실행된 이후로는 관리되지 않습니다.
서비스Service
서비스는 태스크를 지속적으로 관리하는 단위입니다. 서비스는 클러스터 내에서 태스크가 지정된 수만큼 지속적으로 실행될 수 있도록 관리합니다. 또한 아마존의 로드 밸런서와 연동해서 실행중인 태스크를 찾아 자동적으로 로드 밸런서에 등록 및 제거하는 역할도 담당합니다.
ECS 각 요소 간의 관계
ECS 각 요소 간의 관계

이 글에서는 두 가지 방법으로 파게이트를 사용해봅니다. 첫 번째 방법은 시작하기(마법사 기능)을 사용하는 방법으로 몇가지 옵션만 지정하면 바로 ECS 파게이트를 체험해볼 수 있습니다. ECS를 직접 사용하는 데는 상당한 노력이 필요합니다. AWS에 익숙하지 않다면 이 방법으로 테스트해보는 것을 추천드립니다. 두 번째 방법은 이미 존재하는 VPC 위에서 직접 ECS를 만들고 파게이트를 사용해보는 방법입니다. AWS에 익숙하다면 두 번째 방법으로 바로 넘어가는 것을 추천합니다.

시작하기(Get started)로 ECS 체험

ECS 콘솔에 접속합니다. 아직 클러스터를 생성한 적이 없다면 시작하기Get started 화면이 사용자를 맞이합니다.

아마존 ECS 웹콘솔
아마존 ECS 웹콘솔

시작하기로 파게이트 기반의 샘플 애플리케이션을 실행해볼 수 있습니다. 이 샘플에는 VPC, 서브넷, 로드 밸런서 등 다양한 리소스가 포함되어 있습니다. ECS 서비스를 실행하기 위한 풀 세트로 구성이 되어있어서 실제로 활용하기는 어렵습니다. 이 방법은 실제로 작동하는 ECS 클러스터를 살펴보고 싶으신 경우 사용해보시길 추천합니다.

시작하기Get started 버튼을 클릭합니다. 총 4단계로 이루어져있습니다.

1단계: 컨테이너 & 태스크

첫 번째 단계: 컨테이너와 태스크
첫 번째 단계: 컨테이너와 태스크

첫 번째 단계에서는 태스크 디피니션Task Definition컨테이너 디피니션Container Definition을 선택합니다. 컨테이너 디피니션은 sample-app, nginx, tomcat-webserver, custom 네 가지가 준비되어있습니다. 여기서는 sample-app으로 진행해보겠습니다.

먼저 미리 정의된 컨테이너 정의(Container Definition) 중 하나를 선택합니다
먼저 미리 정의된 컨테이너 정의(Container Definition) 중 하나를 선택합니다

컨테이너 디피니션 설정 아래로 태스크 디피니션 설정이 이어집니다. 태스크 디피니션에서 수정할 값은 없습니다만, 파게이트로 실행된다는 걸 확인하고 다음Next을 클릭합니다.

파게이트로 실행할 태스크 디피니션의 정보
파게이트로 실행할 태스크 디피니션의 정보

2단계: 서비스

두 번째 단계에서는 서비스를 설정합니다. 서비스는 태스크를 관리하는 단위입니다. 로드 밸런서 타입Load Balancer Type애플리케이션 로드 밸런서Application Load Balancer로 선택하고 다음Next을 클릭합니다.

3단계: 클러스터

세 번째 단계에서는 클러스터, VPC, 서브넷을 설정합니다. VPC와 서브넷은 자동적으로 설정되며, 클러스터이 이름은 기본값을 사용합니다. 다음Next을 클릭합니다.

4단계: 리뷰

네 번째 단계: 리뷰
네 번째 단계: 리뷰

마지막으로 리뷰 단계입니다. 각 단계에서 설정한 값을 확인하고 생성Create를 클릭하면 ECS 클러스터와 관련된 리소스들이 생성됩니다. 모든 리소스가 생성되는 데는 3분 정도의 시간이 걸립니다.

파게이트 관련 리소스들을 생성하는 과정
파게이트 관련 리소스들을 생성하는 과정

여기서는 ECS 클러스트를 실행하기 위해 VPC로 시작해서, 로드밸런서와 ECS 클러스터와 서비스까지 모든 리소스를 생성합니다.

로드밸런스 DNS에 접속해 서비스 작동 여부 확인하기

생성이 완료되면 EC2 콘솔의 로드 밸런서로 이동해서 방금 생성된 로드 밸런서의 DNS 주소를 확인합니다.

EC2 콘솔의 로드 밸런서 목록에서 새로 생성된 리소스를 확인합니다
EC2 콘솔의 로드 밸런서 목록에서 새로 생성된 리소스를 확인합니다

웹브라우저에서 접속해봅니다. Amazon ECS Sample App을 확인할 수 있습니다.

로드밸런서에 접속해 파게이트로 실행된 ECS Sample App이 실행된 것을 확인합니다
로드밸런서에 접속해 파게이트로 실행된 ECS Sample App이 실행된 것을 확인합니다

겉으로 보기에는 일반 웹서버와 다를 바가 없습니다만, 내부적으로는 파게이트로 실행되고 있습니다.

클러스터와 관련 리소스들을 살펴보았다면*, ECS 클러스터로 돌아와 default 클러스터를 삭제합니다. 클러스터와 관련 리소스들은 클라우드 포메이션 스택CloudFormation stack으로 생성되어있기 때문에 관련된 리소스들도 한꺼번에 삭제할 수 있습니다.

* 여기서는 ECS로 웹서버를 실행하고 잘 작동한다는 걸 확인해본 정도로 넘어갑니다. ECS 및 파게이트와 관련된 리소스들은 뒤에서 좀 더 자세히 이야기하겠습니다.

클러스터 삭제
클러스터 삭제

파게이트 컨테이너 기반 ECS 클러스터 구성

시작하기 기능을 사용해 ECS와 파게이트를 체험해볼 수 있지만, ECS의 사용법을 배우기에 좋은 방법은 아닙니다. 여기부터는 직접 ECS 클러스터를 구성하고 파게이트를 기반으로 컨테이너를 실행해보겠습니다. 여기서 구성할 아키텍처는 시작하기에서 만들었던 아키텍처와 거의 같습니다. 단, 여기서는 VPC나 서브넷은 생성하지 않고 AWS 계정에 미리 만들어져있는 default VPC를 사용한다고 가정합니다.

ECS 클러스터 생성

ECS를 사용하려면 먼저 클러스터를 생성해야합니다. 클러스터 생성하기Create Cluster를 클릭해 클러스터 생성을 시작합니다.

ECS 콘솔에서 클러스터 생성
ECS 콘솔에서 클러스터 생성

클러스터 템플릿을 선택하는 단계로 넘어갑니다. 여기에는 총 3가지의 클러스터 템플릿이 있습니다. 각각의 템플릿은 클러스터와 VPC, 서브넷, 그리고 필요에 따라서 리눅스나 윈도우 인스턴스를 포함합니다. 하지만 앞서 설명한대로 클러스터는 컴퓨팅 자원이 아닌 논리적인 개념에 가깝습니다. 따라서 클러스터를 생성할 때 클러스터 이외의 요소들이 반드시 필요한 것은 아닙니다. 여기서는 클러스터만 생성합니다. 어떤 템플릿을 선택하더라도 무방합니다만, 편의상 맨 앞의 네트워크만 생성*Networking only 템플릿을 선택합니다.

첫 번째 단계: 비어있는 클러스터만 생성하려면 Networking only를 선택합니다
첫 번째 단계: 비어있는 클러스터만 생성하려면 Networking only를 선택합니다

VPC 생성Create VPC 체크 박스를 해제합니다(기본값입니다). 클러스터 이름을 지정합니다. 여기서는 fargate로 지정하겠습니다.

* 다른 템플릿을 선택하는 경우 화면 구성이 약간 다릅니디만, 빈 클러스터 생성Create an empty cluster을 체크하면 클러스터만 생성하는것이 가능합니다.

두 번째 단계: 클러스터의 이름을 지정하고 VPC 생성 여부를 선택합니다
두 번째 단계: 클러스터의 이름을 지정하고 VPC 생성 여부를 선택합니다

생성Create을 클릭하면 클러스터가 만들어집니다.*

새롭게 생성된 빈 클러스터를 확인해봅니다. 태스크의 상태와 클러스터에 포함된 리소스들을 관리하는 메뉴들로 구성된 것을 확인할 수 있습니다.

새롭게 생성한 fargate ECS 클러스터의 정보
새롭게 생성한 fargate ECS 클러스터의 정보

파게이트를 사용하는 경우 EC2 인스턴스 없이도 바로 컨테이너를 실행할 수 있습니다만, 이를 위해서는 먼저 도커 이미지를 준비하고 태스크 디피니션을 만들어야합니다.

도커 이미지(Docker Image)

태스크 디피니션을 생성하려면 먼저 실행하고자 하는 도커 이미지가 준비되어 있어야합니다. * 이 글에서는 stenote/nginx-hostname을 사용하겠습니다. 이미지를 실행해서 작동 여부를 확인해봅니다.

* 도커에 익숙하지 않다면 Subicura 님이 작성하신 초보를 위한 도커 안내서 - 도커란 무엇인가?를 추천합니다. 제가 작성했던 도커(Docker) 튜토리얼 : 깐 김에 배포까지도 있습니다만, 오래된 글이라 참고만해주시기 바랍니다.

$ docker run -d -p 80:80 stenote/nginx-hostname

웹브라우저에서 접속해봅니다. nginx 웰컴 페이지가 표시되면 정상입니다.

stenote/nginx-hostname 이미지를 실행하고 접속한 결과. 컨테이너의 호스트네임이 출력됩니다
stenote/nginx-hostname 이미지를 실행하고 접속한 결과. 컨테이너의 호스트네임이 출력됩니다

실행중인 컨테이너의 호스트네임이 출력되면 정상입니다. 여기서는 이 이미지를 기반으로 태스크 디피니션을 생성해보겠습니다.

태스크 디피니션(Task Definition)

태스크 디피니션은 하나 이상의 컨테이너 디피니션들과 컨테이너가 실행되는 환경에 대한 정보를 담고 있는 리소스입니다. 클러스터에 종속적이지 않으므로, 한 번 정의하고 나면 어떤 클러스터에서든 실행할 수 있습니다.

컨테이너 디피니션은 컨테이너를 실행할 때 사용하는 환경변수와 컨테이너 실행 옵션들을 포함하고 있습니다. 도커 컴포즈Docker Compose를 사용해보셨다면 docker-compose.yaml과 비슷한 역할을 하는 리소스로 이해하셔도 무방합니다.

태스크 디피니션은 서비스 내부적으로 버전 관리가 이루어집니다. 예를 들어 nginx라는 이름으로 태스크 디피니션을 처음 만들면 nginx는 태스크 디피니션이 만들어지고, 실제 태스크 디피니션은 nginx:1과 같이 버전과 같이 표기합니다. 이를 하나의 리비전revision이라고 합니다. 태스크 디피니션은 0개 이상의 리비전들로 구성됩니다.

nginx 리비전 1에서 어떤 환경변수를 변경하고자 한다면, 리비전을 새로 만들어야합니다. 새로 만들어진 태스크 디피니션은 nginx:2가 됩니다. 일반적으로 어떤 태스크 디피니션의 다음 버전은 이전 버전의 정의를 바탕으로 만들어집니다.

중요
TITLE

ECS에는 이상한 제약이 하나 있습니다. 현재 리비전은 삭제가 불가능하고 비활성화 상태로 만들 수 있습니다. 태스크 디피니션은 삭제하거나 이름을 바꾸는 것도 불가능합니다. 이 때문에 태스크 디피니션을 관리할 때는 특히 주의가 필요합니다.

태스크 디피니션 목록Task Definitions 메뉴에 들어갑니다.

태스크 디피니션 목록
태스크 디피니션 목록

새로운 태스크 디피니션 생성Create new Taks Deifinition 버튼을 클릭합니다.

첫 번째 단계: 파게이트를 선택
첫 번째 단계: 파게이트를 선택

태스크 디피니션은 파게이트와 EC2 2가지 방식을 지원합니다. 여기서는 파게이트를 선택합니다.

두 번째 단계: 태스크 디피니션의 이름과 역할(Role)을 지정
두 번째 단계: 태스크 디피니션의 이름과 역할(Role)을 지정

먼저 이름Task Definition Name과 태스크 롤Task Role을 지정합니다. 여기서는 이름을 ecs_fargate_tutorial_nginx로 지정했습니다. 태스크 롤은 태스크에 IAM 권한을 부여할 때 사용하는 기능입니다. 권한을 필요로하지 않는다면 지정하지 않아도 무방합니다.

두 번째 단계: 태스크 디피니션의 실행 롤(Task execution Role)과 리소스 제한을 지정
두 번째 단계: 태스크 디피니션의 실행 롤(Task execution Role)과 리소스 제한을 지정

다음으로 태스크 실행 롤Task execution role과 태스크 사이즈Task Size를 결정합니다. 태스크 실행 롤은 태스크 롤과는 다릅니다. 파게이트 서비스가 사용자를 대신해서 파게이트로 실행된 컨테이너를 관리하기 위한 롤로 ECR에서 이미지를 받아오거나, 클라우드 와치에 로그를 기록하는 등의 권한이 필요한데, 이 때 사용하는 역할이 태스크 실행 롤입니다. 자동으로 생성되어있는 ecsTaskExecutionRole에는 정확히 이 두가지 권한이 부여되어있습니다. 롤에 부여된 권한은 IAM에서 확인하는 것이 가능합니다.

AWS IAM 콘솔에서 ecsTaskExecutionRole에 부여된 권한을 확인
AWS IAM 콘솔에서 ecsTaskExecutionRole에 부여된 권한을 확인

태스크 사이즈는 CPU와 메모리의 조합으로 결정됩니다. CPU 사이즈에 따라서 선택 가능한 메모리의 조합이 다르며, 현재는 약 50가지의 조합이 가능합니다. 예를 들어 가장 작은 CPU 단위인 0.25vCPU의 경우 0.5GB, 1GB, 2GB 메모리 중 하나를 선택하여 조합 가능합니다. 자세한 내용은 AWS Fargate 요금 페이지에서 확인할 수 있습니다. 여기서는 가장 작은 사이즈인 0.25vCPU와 0.5GB 메모리를 선택합니다.

두 번째 단계: 태스크 디피니션의 컨테이너 정의
두 번째 단계: 태스크 디피니션의 컨테이너 정의

마지막으로 컨테이너 디피니션을 추가해야합니다. 컨테이너 추가Add container 버튼을 클릭합니다.

두 번째 단계: 컨테이너에 관련된 옵션을 지정합니다
두 번째 단계: 컨테이너에 관련된 옵션을 지정합니다

컨테이너 이름Container Namenginx, 이미지Imagestenote/nginx-hostname로 지정합니다. 포트 맵핑Port mapping에는 80 포트를 지정합니다. 이외에도 컨테이너 설정을 위한 다양한 옵션들이 있지만 여기서는 기본값을 사용합니다. 추가Add를 클릭합니다.

컨테이너 디피니션이 추가된 것을 확인하고 마지막으로 오른쪽 아래의 생성Create를 클릭합니다.

태스크 디피니션이 추가된 것을 확인
태스크 디피니션이 추가된 것을 확인

태스크 디피니션이 추가된 것을 확인한 것을 확인할 수 있습니다. 이 때 위에서 설정한 대로 리비전도 함께 생성됩니다.

컨테이너 오케스트레이션과 로드 밸런서

컨테이너 오케스트레이션에서 중요한 개념 중 하나는 태스크가 클러스터에 속한 인스턴스 중에 어디에서 실행될지 미리 알 수 없다는 점입니다. 인스턴스와 태스크는 모두 동적으로 생성되거나 삭제되며, 태스크가 실행되는 인스턴스는 오케스트레이션 도구의 스케줄러에 의해서 자동적으로 정해집니다. 이렇게 동적으로 실행된 서비스의 위치를 파악하는 기능을 서비스 디스커버리라고 이야기합니다. 이는 ECS도 마찬가지입니다. 따라서 다수의 태스크를 실행하는 외부에 노출되는 서비스의 경우 로드 밸런서로 서비스 디스커버리 기능을 대체할 필요가 있습니다.

먼저 로드 밸런서를 생성하겠습니다. EC2 콘솔의 로드 밸런서 목록Load Balancers로 이동합니다. 로드 밸런서 생성Create Load Balancer를 클릭합니다.

EC2 웹콘솔의 로드밸런서 목록
EC2 웹콘솔의 로드밸런서 목록

현재 AWS에서는 총 3가지 타입의 로드 밸런서를 지원합니다. 여기서는 애플리케이션 로드 밸런서Application Load Balancer를 선택합니다.

AWS에서 지원하는 로드밸런서 타입들. 여기서는 ALB를 선택합니다
AWS에서 지원하는 로드밸런서 타입들. 여기서는 ALB를 선택합니다

로드 밸런서 생성은 총 6단계로 구성되어있습니다.

1단계에서는 로드밸런서 이름Namefargate-nginx로 지정하고, 나머지 값들은 기본값을 사용합니다. VPC는 default를 선택하고 가용 영역Availability Zonesus-east-1aus-east-1b를 선택합니다.

HTTP만 사용하는 경우 2단계에서 지정할 내용은 없습니다. 3단계에서는 시큐리티 그룹을 설정합니다. 80 포트를 외부에 노출하기 위한 시큐리티 그룹을 임시로 생성합니다.

세 번째 단계: 시큐리티 그룹 지정
세 번째 단계: 시큐리티 그룹 지정

4단계에서는 트래픽을 포워드할 타깃그룹을 생성하거나 지정합니다. 이름Namefargat-nginx으로 지정하고, 나머지는 기본값을 사용합니다. ALB 생성 시에는 타깃그룹을 반드시 지정해야하지만, ECS 서비스 생성시 타깃 그룹Target Group을 다시 생성하기 때문에 지금 만드는 타깃 그룹을 사용하지는 않습니다.

5단계는 로드밸런서(타깃그룹)에 연결할 인스턴스를 지정합니다. 여기서는 바로 다음으로 넘어갑니다. 리뷰를 마치고 생성Create을 합니다.

곧 로드 밸런서가 생성 됩니다. 로드 밸런서 목록으로 이동해 로드 밸런서가 생성되었는지 확인합니다. 방금 생성된 fargate-nginx 로드 밸런서를 선택하고 상세 뷰에서 리스너 목록Listeners으로 이동합니다. 리스너 목록에서는 로드 밸런서에 등록된 타깃 그룹을 확인할 수 있습니다. 80포트로 들어오는 트래픽이 fargate-nginx 타깃 그룹으로 포워딩 되도록 설정되어있습니다. HTTP:80 리스너를 선택하고 삭제합니다.

새롭게 생성된 로드 밸런서를 확인합니다.
새롭게 생성된 로드 밸런서를 확인합니다.

다음으로 타깃 그룹 목록Target Groups으로 이동해 로드 밸런서와 함께 생성된 fargate-nginx 타깃 그룹을 삭제합니다. ALB를 ECS와 연동해서 사용하는 경우 ECS 서비스에서 직접 타깃 그룹을 관리하기 때문에 ALB 생성시 자동으로 생성된 리스너와 타깃 그룹을 사용하지 않습니다.

로드 밸런서와 함께 자동으로 만들어진 타깃 그룹을 삭제해줍니다
로드 밸런서와 함께 자동으로 만들어진 타깃 그룹을 삭제해줍니다

여기까지 ECS 서비스에 연결할 로드 밸런서 셋업을 마쳤습니다.

ECS 서비스

클러스터, 도커 이미지, 태스크 디피니션, 마지막으로 로드 밸런서까지 이제 ECS 서비스를 생성하기 위한 준비를 모두 마쳤습니다. 이제 피날레를 장식하러 ECS 콘솔로 이동합니다. fargate 클러스터로 이동합니다.

fargate 클러스터에서 서비스 탭을 선택합니다
fargate 클러스터에서 서비스 탭을 선택합니다

서비스Service 탭을 선택하고, 생성Create를 클릭합니다. 서비스 생성은 다음과 같이 총 4단계로 이루어져있습니다.

  1. 서비스 설정Configure service
  2. 네트워크 설정Configure network
  3. 오토 스케일링 설정Set Auto Scaling
  4. 리뷰Review

1단계: 서비스 설정(Configure service)

첫 번째 단계의 설정값입니다.

첫 번째 단계: 서비스와 관련된 핵심 옵션들을 지정
첫 번째 단계: 서비스와 관련된 핵심 옵션들을 지정
실행 타입Launch type
서비스의 실행 타입을 지정합니다. EC2와 파게이트를 지원합니다. 여기서는 파게이트를 선택합니다.
태스크 디피니션Task Definition
서비스에서 실행할 태스크 디피니션을 지정합니다. 앞서 생성한 ecs_fargate_tutorial_nginx를 기준으로 최신 리비전을 선택합니다. (수정한 경우 리비전 값이 다를 수 있습니다)
플랫폼 버전Platform version
실행 타입이 파게이트인 경우에만 활성화 됩니다. 파게이트를 실행할 플랫폼 버전을 지정합니다. 특별한 이유가 없다면 최신LATEST를 선택합니다.
클러스터Cluster
서비스가 실행될 클러스터를 선택합니다. 앞서 생성한 fargate를 선택합니다.
서비스 이름Service Name
서비스 이름을 지정합니다. nginx로 지정합니다.
태스크 개수Number of tasks
서비스에서 태스크 디피니션을 기반으로 유지할 태스크 개수를 지정합니다. 2를 지정합니다.
최소 정상 태스크 퍼센트Minimum healthy percent
태스크 디피니션에서 컨테이너 디피니션을 정의할 때 필수essential 컨테이너를 지정할 수 있습니다. ECS 서비스는 이 컨테이너의 실행 여부로 태스크의 상태를 확인합니다. 서비스는 서비스에 지정된 태스크 디피니션 업데이트와 같은 이벤트에 따라서 태스크를 스케줄링합니다. 이 때 태스크 개수를 기준으로 최소 헬시 퍼센트 이하로는 태스크를 줄이지 않습니다. 예를 들어 태스크 개수가 2이고, 최소 헬시 퍼센트가 50%라면, ECS 서비스는 태스크 스케줄링을 진행하더라도 1대는 정상Healthy 상태로 유지합니다. 여기서는 기본값을 사용합니다.
최대 퍼센트Maximum percent
최대 퍼센트에는 ECS 서비스 스케줄링 과정에서 최대로 늘어날 수 있는 태스크 수를 지정합니다. 예를 들어 태스크 수가 2이고 최대 퍼센트가 200%이면, 스케줄링 중에 태스크는 최대 4개까지 늘어날 수 있습니다. 최소 헬시 퍼센트와 최대 퍼센트가 잘못 지정되면 ECS가 자동적으로 태스크 스케줄링을 하지 못 하므로 주의가 필요합니다. 예를 들어 최소 헬시 퍼센트가 100%이고, 최대 퍼센트도 100%이면, ECS에는 어떠한 컨테이너도 종료할 수 없습니다. 여기서는 기본값을 사용합니다.

다음 단계Netx Step을 클릭합니다.

2단계: 네트워크 설정(Configure network)

두 번째 단계는 서비스에서 관리하는 파게이트 태스크의 네트워크를 설정하는 단계입니다. 파게이트로 실행된 태스크는 EC2에 종속적이지 않습니다. 따라서 파게이트 태스크 별로 ENI가 생성되고, 시큐리티 그룹을 붙이거나 퍼블릭 IP를 할당할 수도 있습니다.

두 번째 단계: 네트워크 관련 옵션을 지정합니다
두 번째 단계: 네트워크 관련 옵션을 지정합니다

클러스터 VPC는 미리 생성되어있는 default VPC를 선택합니다. 서브넷Subnetsus-east-1a의 서브넷을 지정합니다. 시큐리티 그룹Security Groups은 자동 생성해주는 기본값을 사용합니다. 퍼블릭 IP 자동 할당Auto-assign public IP활성ENABLED를 선택합니다.*

* 프라이빗 서브넷을 구성하는 경우 NAT를 사용해 퍼블릭 IP를 할당하지 않고도 인터넷을 사용하는 것이 가능합니다. 하지만 아마존 계정에 처음 준비되어있는 네트워크 환경은 NAT를 통하지 않고 인터넷을 사용해야하기 때문에 퍼블릭 IP를 할당해야만 인터넷을 사용할 수 있습니다. 따라서 도커 허브에서 이미지를 풀 받아오기 위해서는 파게이트 서비스에 반드시 퍼블릭 IP를 할당해주어야합니다.

다음으로 로드 밸런서Load Balancing를 설정합니다.

두 번째 단계: 로드 밸런서 설정
두 번째 단계: 로드 밸런서 설정

로드 밸런서를 지정하기 위해서는 로드 밸런서를 미리 만들어두어야합니다(앞에서 만들었습니다). 로드 밸런서 타입Load balancer type애플리케이션 로드 밸런서Application Load Balancer로 선택하고, 로드 밸런서를 앞서 생성한 fargate-nginx로 지정합니다. 화면 아래에 보이는 로드 밸런서에 추가하기Add to load balancer 버튼을 클릭합니다.

두 번째 단계: 로드 밸런서 상세 설정
두 번째 단계: 로드 밸런서 상세 설정

리스너 포트Listener Port에 80을 지정하고, 나머지 값들은 기본 값을 사용합니다.

라우트 53에는 서비스 디스커버리를 대체할 수 있는 기능이 있습니다. 여기서는 사용하지 않으므로 로드 밸런서 설정 뒤에 이어지는 서비스 디스커버리 기능 활성화Enable service discovery integration를 체크 해제합니다.

다음 단계Netx Step을 클릭합니다.

3단계, 4단계

3단계는 오토 스케일링 설정입니다. 여기서는 사용하지 않으므로 바로 다음 단계Netx Step을 클릭합니다.

4단계는 리뷰입니다. 설정값들을 확인하고 서비스 생성Create Service 버튼을 클릭합니다. 서비스가 생성됩니다. 서비스가 생성되고 나면 다음과 같이 서비스의 상태를 볼 수 있습니다. 2개의 태스크가 실행 준비중인 것을 확인할 수 있습니다.

서비스를 실행되면 파게이트 태스크가 실행됩니다. 서비스의 태스크 탭에서 확인합니다
서비스를 실행되면 파게이트 태스크가 실행됩니다. 서비스의 태스크 탭에서 확인합니다

조금 기다리고 태스크 목록 위의 리프레시 버튼을 클릭해서 태스크가 실행RUNNING 상태가 된 것을 확인합니다.

파게이트 태스크가 실행(RUNNING) 상태가 된 것을 확인
파게이트 태스크가 실행(RUNNING) 상태가 된 것을 확인

성공적으로 실행된 것을 확인할 수 있습니다.

로드 밸런서로 서비스 작동 여부 확인

서비스 준비가 끝났으니 이제, 정상적으로 작동하는지 확인해보겠습니다. 먼저 타깃 그룹에 파게이트 태스크가 정상적으로 등록되었는지 확인합니다. EC2 콘솔의 타깃 그룹 목록Target Groups에서 ecs-fargate-nginx 타깃 그룹을 선택합니다. 디테일 뷰의 타깃 목록Targets 탭에서 2개의 타깃을 확인할 수 있습니다.

EC2 타깃 그룹에서 자동으로 등록된 타깃을 확인
EC2 타깃 그룹에서 자동으로 등록된 타깃을 확인

앞서 생성한 fargate-nginx 로드 밸런서의 퍼블릭 DNS 주소를 확인합니다. 이 주소는 ELB를 생성할 때마다 달라지므로 직접 확인해야합니다. 이 주소에 curl을 사용해 접근해보겠습니다(웹브라우저에서 접속해볼 수도 있습니다).

$ curl http://fargate-nginx-1422336731.us-east-1.elb.amazonaws.com/
4830600b8bc8

$ curl http://fargate-nginx-1422336731.us-east-1.elb.amazonaws.com/
6827a8661118

$ curl http://fargate-nginx-1422336731.us-east-1.elb.amazonaws.com/
4830600b8bc8

$ curl http://fargate-nginx-1422336731.us-east-1.elb.amazonaws.com/
6827a8661118

4830600b8bc86827a8661118이 번갈아가며 출력되는 것을 확인할 수 있습니다. 이를 통해 2개의 컨테이너에서 nginx가 실행중이라는 것을 확인할 수 있습니다.

마지막으로 더 이상 사용하지 않는다면, 지금까지 생성한 리소스들을 삭제해줍니다.

마치며

ECS를 비롯한 컨테이너 오케스트레이션 도구를 사용해봤다면 클러스터에 속한 인스턴스를 관리하는 작업이 가장 귀찮은 일 중 하나라는 것에 공감할 것입니다. 인스턴스에 설치된 오케스트레이션 도구의 작동 여부와 버전을 관리해야 하고, 특정 서비스나 컨테이너가 지속적으로 문제를 일으키면 서버에 직접 들어가야하는 상황도 종종 발생합니다. 파게이트는 우선 매니지드 서비스이기 때문에 이러한 번거로운 작업들을 필요로 하지 않습니다. 또한 일반적으로 호스트의 네트워크 환경을 공유하는 컨테이너들과 달리 독립적인 네트워크 환경을 가지고 실행되는 특수한 컨테이기 때문에 좀 더 유연한 환경 구성을 하는 것이 가능합니다. 현재는 ECS만 지원하지만, 추후에 EKS와 함께 사용할 수 있게 되면 활용 범위도 넓어질 것으로 보입니다.

같이 읽으면 좋은 문서들