위와 같은 인프라 아키텍쳐를 구성하기 위해서 이번에 AWS ECS를 구성해보도록 하겠습니다.
구성하기 전에, AWS ECS를 간략하게 살펴보고 구성해보도록 하겠습니다!
1. AWS ECS란?
AWS ECS는 Elastic Container Service로, AWS 공식문서에서는 다음과 같이 설명되어 있습니다.
Amazon Elastic Container Service(Amazon ECS)는 컨테이너화된 애플리케이션을 쉽게 배포, 관리, 스케일링할 수 있도록 도와주는 완전 관리형 컨테이너 오케스트레이션 서비스입니다.
ECS를 컨테이너 오케스트레이션 서비스로 소개하고 있습니다.
따라서, ECS를 구성하기 위해서는 컨테이너 환경(Docker)을 이해하고 애플리케이션을 컨테이너 환경에서 구성해야 합니다.
ECS 내부의 요소들은 Docker 기반 컨테이너로 구성되어 ECS가 관리하게 됩니다.
ECS의 역할은 일반적인 역할은 다음과 같습니다.
- 컨테이너 수명주기(생성, 종료) 관리
- 로드 밸런싱
- 클러스터링
- 장애 복구
- 스케쥴링
또한 공식문서에서 ECS의 주요 기능에 다음과 같이 CI/CD 부분도 설명되어 있습니다.
- 지속적인 통합 및 지속적인 배포(CI/CD). 이는 Docker 컨테이너를 기반으로 하는 마이크로서비스 아키텍처의 일반적인 프로세스입니다. 다음 작업을 수행하는 CI/CD 파이프라인을 생성할 수 있습니다.
- 소스 코드 Repository 변경 사항 모니터링
- 해당 소스로 새로운 Docker Image 빌드
- Amazon ECR or Docker Hub와 같은 이미지 레포지토리에 Image 푸쉬
- 애플리케이션에서 새로운 이미지를 사용하도록 Amazon ECS 서비스 업데이트
제 개인 프로젝트에서는 이러한 CI/CD 부분을 활용하기 위해 ECS를 도입하게 되었습니다.
2. AWS ECS의 구성요소
ECS를 구성하는 구성 요소들은 다음과 같습니다.
- Cluster
- Task & Task Definition
- Service
- Container Instance
이러한 구성 요소를 나타낸 그림을 먼저 살펴보고 하나씩 간략하게 살펴보겠습니다.
2-1. Cluster
ECS의 Cluster는 구성 요소 중 가장 큰 단위로, ECS의 하위 요소들의 논리적인 그룹입니다.
ECS 구성 요소 그림을 보면 모든 하위 요소를 그룹화하는 단위임을 알 수 있습니다.
2-2. Task & Task Definition
ECS의 Task는 컨테이너를 실행하는 최소 단위입니다. (컨테이너의 그룹 단위)
Task는 최소 1개 이상의 컨테이너로 구성됩니다.
쉽게 말하면, 여러 컨테이너를 하나로 묶어서 실행하는 단위입니다.
ECS의 Task Definition은 앞에서 말한 Task 구성을 사전에 정의해놓은 개념입니다.
따라서, 컨테이너 이미지, CPU/메모리 리소스 할당 설정, port 매핑, volume 설정 등 컨테이너 관련 설정이 포함됩니다.
이러한 Task Definition 구성 기반으로 실제로 생성된 컨테이너들의 집합을 Task라고도 합니다.
Task와 Task Definition은 다음과 같은 그림으로 나타낼 수 있습니다.
위의 그림을 보면 미리 정의된 Task Definition들에 의해 실제 Task가 생성되는 것을 알 수 있습니다.
2-3. Service
ECS의 Service는 Task의 수명주기를 지속적으로 관리하는 상위 그룹 단위입니다.
ECS Service의 역할은 다음과 같습니다.
- Cluster에 배포할 Task 수 결정
- Task의 배포 방식 결정 (롤링 or Blue/Green)
- AutoScale 설정 등 ELB와 관련한 작업
위의 ECS 구성 요소 그림을 보면 Cluster 내에 모든 Task를 하위 요소로 가지고 관리하고 있음을 알 수 있습니다.
앞서 말했던 최신 소스 코드를 배포하는 CD 작업에서 이러한 ECS Service가 하위에 있는 모든 Task(Docker Container)에
최신 소스 코드 도커 이미지를 배포하여 CD를 구성할 수 있습니다.
2-4. Container Instance
ECS의 Container Instance는 Task가 배포되어 실제 Docker 컨테이너가 실행되는 EC2 Instance라고 할 수 있습니다.
ECS에서는 Container Instance에 ECS Container Agent를 설치함으로써 오케스트레이션 명령 수행을 가능케합니다.
위의 구성 요소 그림처럼 하나의 Cluster에 여러 개의 Container Instance가 있을 수 있고,
하나의 Container Instance에 여러 개의 Task가 존재할 수 있습니다.
(만약 Service 구성 시에 Task 실행을 EC2가 아닌 Serverless 환경의 Fargate를 선택했다면 Cluster 내에 따로 Container Instance 없이 Serverless하게 서비스를 구성할 수 있습니다.)
3. AWS ECS 구성해보기(ECS 마이그레이션)
위에서 간략한 개념 및 구성 요소까지 살펴봤으니이제 직접 개인 프로젝트의 AWS ECS를 구성해보도록 하겠습니다.
저는 기존 인프라 구조가 다음과 같이 존재했습니다.
이러한 구조에서 ECS Cluster를 구성할 EC2는 WAS EC2 2대입니다.
해당 WAS EC2 2대를 ECS로 마이그레이션 해보겠습니다.
해당 EC2들의 Spec 및 환경 다음과 같습니다.
- OS Image : Amazon Linux 2023 AMI
- Architecture : x86_64(amd64)
- 인스턴스 유형 : t2.micro
- Storage : 1 volume - 8GB
- VPC 동일 / 각각 다른 Subnet
이러한 EC2들을 ECS로 마이그레이션 해보겠습니다.
(구성 시 필요한 ECR은 이미 구성된 상태로 진행해보겠습니다.)
3-1. ECS Cluster 생성
AWS 콘솔에서 ECS에 접속하면 클러스터를 생성할 수 있습니다.
3-1-1. Cluster 구성
먼저, 구성할 Cluster의 이름을 지정해줍니다.
3-1-2. 인프라 구성
그 후에, 인프라 설정을 위와 같이 해줍니다.
- EC2 인스턴스 체크
- Auto Scaling Group 생성
- Container는 최소 2개로 생성
3-1-3. ECS EC2 인스턴스 네트워크 설정
- 기존 EC2가 속한 VPC 선택
- 기존 서브넷 2개 선택
- 기존 보안그룹 선택
3-2. AWS ALB 생성
이제 Cluster와 하위 Container Instance가 생성되었습니다.
그 다음으로는 Container Instance에 접근하는 트래픽을 관리하는 로드 밸런서를 생성해야 합니다.
EC2 탭 하위의 로드 밸런서 페이지에서 로드 밸런서를 생성할 수 있습니다.
3-2-1. 로드 밸런서 유형 선택
AWS ELB 종류 중에서 HTTP를 이용하는 웹 애플리케이션을 가동할 것이기 때문에
로드밸런서로 Application Load Balancer인 ALB를 선택하겠습니다!
3-2-2. 기본 구성
이름 및 내부/외부 경계, IP 주소 유형 등을 설정합니다.
외부 사용자에게서 오는 트래픽을 관리할 것이기 때문에 인터넷 경계를 선택해주었습니다.
3-2-2. 네트워크 매핑
이전 ECS Cluster에서 인프라(Container Instance) 구성 시에 선택한 VPC와 서브넷들을 선택해줬습니다.
3-2-3. 보안 그룹 설정
적절한 보안그룹을 설정해줬습니다.
3-2-4. 리스너 및 라우팅 & 대상 그룹 생성
로드 밸런서의 리스너 구성을 해줍니다.
이때, 리스너의 대상 그룹을 지정해야 하는데 아직 생성 전이므로 '대상 그룹 생성'을 통해 먼저 대상 그룹을 생성합시다.
대상 그룹 기본 유형은 ECS EC2 Container Instance 대상이므로 인스턴스를 선택합니다.
그 다음에는 이름 지정 및 ECS Container Instance의 프로토콜, 포트, IP 주소 유형, VPC 등을 설정해줍니다.
그리고 나머지는 기본 설정에 따랐습니다.
대상 등록 단계에서 앞서 생성한 ECS Container Instance를 등록해줬습니다.
그 후에, 대상 그룹을 생성하고 앞서 ALB 리스너 및 라우팅에서 생성한 대상그룹을 지정한 후에 ALB를 생성했습니다.
3-3. ECS Task Definition 생성
3-3-1. 태스크 정의 패밀리(이름) 설정
생성하려는 Task Definition의 이름을 지정합니다.
3-3-2. 인프라 설정
Task의 인프라 환경을 설정합니다.
기존 EC2의 OS/아키텍쳐와 t2.micro 인스턴스보다 적은 메모리를 설정해줬습니다.
(처음에 1 vCPU, 1 GB로 구성해서 배포를 진행했는데 insufficient memory 에러가 뜨면서 배포가 실패했습니다!)
네트워크 모드는 4가지 모드가 존재하는데, Linux 환경에서의 일반적인 bridge를 선택했습니다.
- awsvpc : Task를 호스팅하는 EC2에 ENI와 기본 프라이빗 IPv4 주소 할당, Fargate 사용 시 해당 모드를 선택해야 함
- bridge : Task를 호스팅하는 EC2에 Linux에서의 docker의 기본 가상 네트워크 사용
- default : Task를 호스팅하는 EC2에 Windows에서의 Docker 기본 가상 네트워크 이용
- host : Task를 호스팅하는 EC2의 ENI에 직접 매핑 -> EC2 인스턴스 하나에서 동일 태스크에 대해 다중 인스턴스화 불가능
3-3-3. 컨테이너 설정
Task 내에 실행될 Docker Container 관련 설정입니다.
컨테이너의 이미지 URI는 등록되어 있는 ECR의 이미지 URI를 지정했습니다.
(ECR 생성 및 ECR 이미지 푸쉬는 되어 있다고 가정하고 진행합니다.)
포트 매핑에서는 컨테이너 포트를 생성했던 80으로 하고, 호스트 포트는 지정하지 않고 동적으로 매핑되도록 설정했습니다.
리소스 할당은 실행되는 애플리케이션 및 EC2 인스턴스에 맞게 적절히 조절해서 설정했습니다.
나머지 Optional 옵션(환경 변수, 로깅, ...)들은 기본 설정으로 진행했습니다.
3-4. ECS Service 생성
그 다음으로는 ECS Cluster 내의 Task들을 관리하는 Service를 생성해보겠습니다.
3-4-1. 배포 구성
- 애플리케이션 유형 :
- 서비스 : 중지, 다시 시작 가능한 애플리케이션
- 태스크 : 실행, 종료만 단순하게 있는 애플리케이션
Task는 웹 애플리케이션이므로 서비스 유형을 선택했습니다.
그 다음으로 이전에 정의해뒀던 Task Definition을 지정했습니다.
그리고 Task 수는 WAS EC2의 수가 2대였기 때문에 2개로 지정하여 2개의 Task가 실행되도록 지정했습니다.
배포 옵션에서 배포 유형으로는 점진적으로 구버전에서 신버전으로 배포가 되는 롤링 업데이트를 선택했습니다.
3-4-2. 로드 밸런싱 설정
그 다음으로 로드 밸런싱 설정을 진행했습니다.
이전에 ALB를 먼저 생성해놨기 때문에 기존에 생성했던 ALB에 맞춰서 설정을 마무리했습니다.
이렇게 모든 설정이 마무리 되었다면, 구성한 ALB의 DNS로 접속하면 잘 접속이 되는 것을 확인할 수 있습니다.
Reference
https://boostbrothers.github.io/technology/2020/01/29/AWS-ECS-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0/
https://yoo11052.tistory.com/141
'Infra' 카테고리의 다른 글
[INFRA] 개인 프로젝트 INFRA, CI/CD 구축기 - (2) 인프라 아키텍쳐 수정 (0) | 2024.01.29 |
---|---|
[INFRA] 개인 프로젝트 INFRA, CI/CD 구축기 - (1) 초기 설계 (0) | 2024.01.17 |