ECS 클러스터 생성 + 태스크 정의 + 서비스 생성
- 아키텍처 개요 (링크)
- CodeBuild + ECR 생성 (링크)
- VPC + 서브넷 생성 (링크)
- 인터넷 게이트웨이 + NAT 게이트웨이 생성 및 라우트 테이블 설정 (링크)
- 로드밸런서(ALB) + 보안 그룹(Security Group) + 대상 그룹(Target Group) 생성 (링크)
- ECS 클러스터 생성 + 태스크 정의 + 서비스 생성 (현재 글)
- S3 버킷 생성 + CodePipeline 설정 및 최종 배포 (링크)
ECS란?
Amazon에서 제공하는 완전관리형 컨테이너 오케스트레이션 툴로써, Docker 컨테이너를 이용하여 인프라 환경을 좀 더 편리하게 운영, 관리할 수 있게 해주는 서비스이다.
AWS가 제공하는 컨테이너 서비스
- 제어 플레인 : 컨테이너 기술에서는 Control plane이란 컨테이너를 관리하는 기능을 의미하며 ECS와 EKS가 존재한다.
- ECS란
- AWS에서 제공하는 완전 관리형 컨테이너 오케스트레이터로 컨테이너를 동작시키는 실행 환경을 제공하는 서비스는 아니다.
- EKS란
- 완전 관리형 쿠버네티스 서비스로 쿠버테니스 제어 플레인 관리를 AWS에 위임하여 유지할 수 있는 서비스다.
- ECS란
- 데이터 플레인 : 컨테이너가 실제로 동작하는 자원 환경을 지정한다. (EC2, Fargate 등)
- EC2
- AWS에서 가상머신을 이용 가능한 서비스이며, 제공되는 가상 이미지를 인스턴스 라고 한다.
- Fargate
- 컨테이너용 서버리스 컴퓨팅 엔진
- EC2
클러스터 생성
클러스터 구성은 클러스터의 이름을(자유롭게) 작성해준 후, 네임스페이스를 설정해 준다. 이 네임스페이스는 자동으로 이름 작성 시 생성된다.
인프라의 경우 AWS의 Fargate를 선택해 주었다.
모니터링, 암호화, 태그 부분은 기본 설정 그대로 두었다.
클러스터란?
클러스터란, Task 또는 Service의 논리적인 그룹이다. 기본적으로 컴퓨팅 자원을 포함하지 않으며, ECS에서 컨테이너를 실행시키기 위해서는 컨테이너 인스턴스가 클러스터에 포함되어야 한다.
이러한 클러스터는 컨테이너 인스턴스를 조작할 수 있는 권한을 가지고 있으며, 클러스터에서 서비스나 태스크를 실행하면 조건을 만족하는 컨테이너 인스턴스를 찾아 해당 인스턴스에 컨테이너를 실행하게 된다. ⇒ 하지만 AWS Fargate를 사용하면 컨테이너 인스턴스 없이 컨테이너를 실행할 수 있다 (서버리스이기 때문)
서버리스(Serverless)란?
서버가 없다는 뜻으로 직접 서버를 관리하지 않아도 되는 아키텍처를 칭한다.
네임스페이스란?
프라이빗 호스팅 영역에 생성되는 DNS Name이다.
태스크 정의 생성
태스크 정의는 태스크 정의 패밀리(그룹)의 이름을 정해준 후 인프라 요구 사항을 다음과 같이 설정한다.
- AWS Fargate를 선택
- 운영 체제/아키텍처는 리눅스를 선택해주었고, 네트워크 모드는 기본 설정으로 해주었다.
- 태스크의 크기는 애플리케이션과 프로젝트 규모에 알맞게 선택해 준다 (juice shop에 맞는 설정으로 적당히 설정해 주었다.)
- 태스크 역할의 경우 기본적으로 지원하는 역할을 부여해 주었다. (사진 속에는 태스크 실행 역할만 지정되어 있지만 최종적인 설정으로는 태스크 역할도 똑같은 ecsTaskExecutionRole로 설정했다.)
- 그 외의 인프라 요구 사항은 지정해주지 않았다.
컨테이너는 하나만 설정해 주었으며, 내용은 다음과 같다.
- 컨테이너의 이름은 Juice-shop-scp로 설정해 주고, 이미지의 URL은 ECR에 저장된 Docker 이미지의 경로로 설정해 주었다.
- 필수 컨테이너는 기본 설정인 예로 해주었는데 이는 컨테이너가 반드시 실행되어야 한다는 의미이다.
- 프라이빗 레지스트리 인증은 이미지 접근을 위한 인증을 해야 할 것인지 선택하는 것인데 이는 비활성화해주었다.
- 포트 매핑은 컨테이너 내부의 접근을 외부에서 할 수 있도록 연결해 주는 설정이다.
- 컨테이너 포트는 컨테이너 내부에서 애플리케이션이 실행되는 포트로 3000으로 설정했다.
- 프로토콜과 앱 프로토콜은 TCP와 HTTP로 설정해 주었고, 포트 이름도 따로 작성해 주었다.
- 그 외의 설정들은 모두 기본 설정으로 두었다.
Task 정의란?
Task 정의는 Task를 실행하기 위한 설정을 저장하고 있는 단위이다.
컨테이너 별로 실행하고자 하는 이미지를 지정할 수 있으며, CPU나 Memory와 같은 정보도 지정할 수 있고, 하나 혹은 둘 이상의 Task 정의를 포함할 수 있다.
이러한 Task는 클러스터에 종속되어 있지 않다.
Task란?
Task 정의에서 정의된 대로 배포된 컨테이너 세트를 Task라고 부른다.
즉, Task 안에는 한 개 이상의 컨테이너들이 포함되고 있으며 ECS에서 컨테이너를 실행하는 최소 단위는 Task이다.
이러한 Task는 Task 정의로 직접 실행할 수도 있고, 서비스를 정의하여 실행할 수도 있다.
⇒ 하지만 Task 정의로 직접 실행된 Task는 한 번이 실행된 이후 관리되지 않음
서비스 생성
생성해 둔 클러스터에서 서비스 생성을 눌러 서비스를 생성해 주었다.
용량 공급자 전략으로 FARGATE_SPOT를 선택하고, 플랫폼 버전은 LATEST으로 선택했다.
배포 구성의 애플리케이션 유형은 서비스로 선택하고, 패밀리의 경우 생성해 둔 Task 정의를 선택했다. 개정의 경우 가장 최신 또는 1로 설정해 두면 된다.
서비스 이름은 scp-juice-shop로 설정해 두고, 서비스 유형은 복제본으로 해주었다.
Task 개수는 2개로 설정해 주고, 가용영역 리밸런싱은 기본 설정 그대로 켜두었다.
배포 옵션은 Rolling Update로 선택하고 최소 실행 작업 비율은 50%, 최대 실행 작업 비율은 200%로 해주었다.
네트워킹에서는 생성한 VPC를 선택하고, 프라이빗 서브넷 2개를 매핑했다.
보안 그룹은 기존에 생성한 ECS Task용 보안 그룹만 선택해 주었다.
로드 밸런싱을 사용으로 해준 후 ALB를 선택하였다.
컨테이너는 자동으로 선택된 juice-shop-scp 3000:3000으로 설정하였고, 기존의 로드밸런서인 juice-shop-scp를 선택하였다.
상태 검사 유예 기간은 기존에 설정을 안 해두었기에 일단 0초로 두었다.
리스너도 기존의 리스너로 선택하고 HTTP(80)으로 설정했다.
대상 그룹의 경우도 기존의 대상 그룹을 선택하여 juice-shop-target-group으로 선택했다.
서비스란?
서비스란 클러스터에서 지정된 수의 작업을 동시에 실행하고 관리할 수 있게 해주는 구성이다.
서비스는 Task를 포함하며, Task와 관련된 Auto Scaling와 로드밸런싱을 관리한다.
서비스는 하나의 태스크 정의와 연결되며 이를 통해 태스크를 실행시킬 수 있다.
- 용량 공급자 전략을 FARGATE_SPOT으로 설정한 이유는 비용 절감을 위해서다. 이를 선택하면 FARGATE에 비해 최대 70% 저렴하게 이용 가능하며 AWS가 용량이 부족할 경우 태스크를 중단시키게 된다.
- Task 개수를 2개로 설정한 이유는 Rolling Update 배포 방식에서 기존의 태스크를 새 태스크로 교체하는 방식으로 동작하는데, 이때 2개의 태스크를 실행하면 하나의 태스크가 업데이트 중 중단되더라도 나머지 태스크가 트래픽을 처리하여 무중단으로 배포가 가능하기 때문이다.
- 최소 실행 작업 비율을 50으로 설정하면 전체 태스크의 절반은 항상 실행 상태를 유지할 수 있고, 최대 실행 작업 비율을 200으로 설정하면 현재 실행 중인 태스크 외에 최대 기존 태스크 수만큼 추가 태스크를 실행할 수 있다.
- 네트워킹에서 프라이빗 서브넷만 매핑한 이유는 프라이빗 서브넷이 인터넷에 직접적으로 접근할 수 없는 서브넷이기에 직접 인터넷 노출을 방지시켜 보안을 강화시킬 수 있기 때문이다. ⇒ NAT 게이트웨이를 통해 프라이빗 서브넷에 태스크를 배치하고 인터넷에 접근시킬 수 있음
참고 문헌
https://countrymouse.tistory.com/entry/awsecs