🐱 ECS Cats and Dogs 🐶
📄 워크숍 개요
이 워크숍에서는 고양이의 사진이나 개의 사진(사용자가 선택한 내용에 따라 다름)을 무작위로 표시하는 컨테이너화/자동 확장 웹 애플리케이션을 빌드하고 배포합니다. 또한 컨테이너 관측성 도구를 구현하고 웹 애플리케이션에서 부하 테스트를 수행하고 결과를 모니터링합니다.

🗺️ 전체 아키텍처

📄 Service 개요

- 웹은 ALB의 DNS 이름으로 접근할 수 있는 main 웹 페이지입니다. I♥Cats 또는 I♥Dogs를 클릭하면 해당 ECS 서비스(cats 또는 dogs)로 리디렉션됩니다.
- EC2 작업인 Cats는 웹 페이지를 새로 고칠 때마다 무작위로 고양이 사진을 표시합니다.
- Fargate 작업인 Dogs는 웹 페이지를 새로 고칠 때마다 무작위로 강아지 사진을 표시합니다.
🔧 실습 환경 구성
[1] 실습 준비

CloudFormation 배포
1. 템플릿 파일 업로드
- 다운 받은 ecs-workshop-personal.yaml 템플릿 파일 업로드

2. 스택 이름 및 VSCode 비밀번호 입력
- 스택 이름 : catsndogs-ecs-workshop
- VSCodeServerPassword : sidsiddleodeoddl!!

3. 스택 옵션 구성 제일 하단에 ‘기능’ 부분 체크
- AWS CloudFormation이 IAM 리소스를 생성할 수 있음을 인정합니다’ 체크 후 다음 클릭

4. 검토 및 생성 – 검토 후 제출

5. 스택 생성 후 상태 확인

[2] EC2 상에 VSCode IDE 환경 설정
CloudFormation 템플릿 배포 결과 확인
1. CloudFormation 배포 스택 출력값 확인
- 출력(Outputs) 항목의 VSCodePassword, VSCodeServerURL 값 복사하여 기록 (실습에서 IDE로 사용 VSCode server 접속 url과 비밀번호)
- CloudFormation > 스택 > 배포된 ‘catsndogs-ecs-workshop’ 스택 클릭 후 출력(Outputs) 항목 선택

2. VSCode IDE Server 접속
- VSCodeServerURL 로 접속 후 VSCodePassword 입력하여 접속


3. Folder 열기
- File > Open Folder 클릭 후 ‘/home/ec2-user/’ 입력 후 OK 클릭


4. 새 터미널창 열기
- Terminal > New Terminal 클릭하거나 우측 상단 버튼을 클릭하여 터미널창 열기

5. Role 올바르게 적용되었는지 확인
- 입력
aws sts get-caller-identity | grep "VSCodeInstanceRole"
- 실행 결과
"Arn": "arn:aws:sts::824980384452:assumed-role/catsndogs-ecs-workshop-VSCodeInstanceRole-m2pnGzbLWr9X/i-00284315bd47d5edd"
6. 실습에 사용할 코드가 잘 다운되었는지 확인
- 입력
ls -l ~/ecs-cats-dogs
- 실행 결과

total 156
-rw-rw-r--. 1 ec2-user ec2-user 17 Aug 24 17:26 README.md
drwxrwxr-x. 2 ec2-user ec2-user 62 Aug 24 17:26 cats
-rw-rw-r--. 1 ec2-user ec2-user 80 Aug 24 17:26 cluster_loadtest.sh
drwxrwxr-x. 2 ec2-user ec2-user 62 Aug 24 17:26 dogs
-rw-rw-r--. 1 ec2-user ec2-user 71460 Aug 24 17:26 ilovecats.jpg
-rw-rw-r--. 1 ec2-user ec2-user 73357 Aug 24 17:26 ilovedogs.jpg
-rw-rw-r--. 1 ec2-user ec2-user 80 Aug 24 17:26 service_loadtest.sh
drwxrwxr-x. 2 ec2-user ec2-user 79 Aug 24 17:26 web
7. CLI 도구 업데이트 및 설치
- 입력
sudo pip install --upgrade awscli
sudo yum install -y jq
- 실행 결과

8. 리전 설정
- 현재 실습중인 리전을 기본값으로 설정하기 위해 명령어 입력
TOKEN=`curl -X PUT "<http://169.254.169.254/latest/api/token>" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
export AWS_REGION=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" <http://169.254.169.254/latest/meta-data/placement/region>)
echo "export AWS_REGION=${AWS_REGION}" | tee -a ~/.bash_profile
aws configure set default.region ${AWS_REGION}
- 실행 결과

9. 계정 ID 환경 변수로 등록
- 입력
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
echo "export AWS_ACCOUNT_ID=${AWS_ACCOUNT_ID}" | tee -a ~/.bash_profile
- 실행 결과

🚀 콘솔로 배포
[1] ECR(Elastic Container Registry)
ECR repository 생성
- 실습에서 사용할 코드 내 web, cats, dogs 디렉토리가 사용할 ECR 리포지토리를 생성

1. 프라이빗 리포지토리 생성 (web, cats, dogs)

💡 ‘이미지 태그 변경 가능성(Tag immutability)’ 이란?
- Mutable : 이미지 태그를 덮어쓸 수 있음
- Immutable : 이미지 태그를 덮어쓸 수 없음
⇒ 이미지 태그 중복(덮어쓰기)이 되지 않도록 할 수 있는 설정
⇒ Immutable(중복 방지) 상태에서 이미 존재하는 태그가 지정된 이미지를 푸시하면 ImageTagAlreadyExistsException 오류가 반환됨
2. 생성한 리포지토리 확인

도커 이미지 빌드
1. VSCode Server 브라우저 화면으로 전환
2. web, cats, dogs 의 Dockerfile 확인
- ecs-cats-dogs > cats > Dockerfile
- 도커는 Dockerfile 을 읽어 자동으로 이미지를 빌드하기 때문에 각각의 디렉토리 내 Dockerfile의 내용을 열어 확인합니다.

3. VSCode 의 터미널창에서 cats 빌드
- 입력
source ~/.bash_profile
docker build -t cats ~/ecs-cats-dogs/cats/
- 실행 결과

4. dogs, web 도 빌드 진행
- 입력
docker build -t dogs ~/ecs-cats-dogs/dogs/
docker build -t web ~/ecs-cats-dogs/web/
- 실행 결과

이미지 태그하고 ECR로 푸시하기
- 앞 단계에서 작업한 도커 이미지를 latest로 태깅한 후 web, cats, dogs 리포지토리로 푸시
1. 터미널 환경 변수 설정
- 브라우저 화면 리프레시로 환경변수가 초기화 되었을 경우를 대비해 VSCode 터미널에서 아래 명령어를 실행하여 환경변수를 설정
source ~/.bash_profile
2. Cats 이미지 태그하고 푸시하기


# 1. Docker 클라이언트를 레지스트리에 인증
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 824980384452.dkr.ecr.ap-northeast-2.amazonaws.com
# 3. 이미지에 태그 지정
docker tag cats:latest 824980384452.dkr.ecr.ap-northeast-2.amazonaws.com/cats:latest
# 4. 이미지를 리포지토리로 푸시
docker push 824980384452.dkr.ecr.ap-northeast-2.amazonaws.com/cats:latest
- 실행 결과

3. Dogs, Web 이미지 태그하고 푸시하기
- Dogs
docker tag dogs:latest 824980384452.dkr.ecr.ap-northeast-2.amazonaws.com/dogs:latest
docker push 824980384452.dkr.ecr.ap-northeast-2.amazonaws.com/dogs:latest

- Web
docker tag web:latest 824980384452.dkr.ecr.ap-northeast-2.amazonaws.com/web:latest
docker push 824980384452.dkr.ecr.ap-northeast-2.amazonaws.com/web:latest

4. ECR 리포지토리 확인
- Cats

- Dogs

- Web

[2] ECS(Elastic Container Service)
- ECS 클러스터 / web, cats, dogs 서비스에 대한 ECS 작업 정의 / web, cats, dogs 작업을 실행하는 서비스 / ALB 생성

ECS 클러스터
1. ALB 및 ECS 클러스터 보안그룹 생성
- EC2 > 보안그룹 > 보안그룹 생성 클릭

- ALB 보안그룹

- ECS 클러스터 보안그룹

2. ECS 클러스터 생성
- ECS > 클러스터 > ‘클러스터 생성’ 클릭



- AWS Fargate, EC2 모두 선택
- 컨테이너 인스턴스 : Amazon Linux 2
- EC2 인스턴스 유형 : m5.large
- 원하는 용량 : 최대 2 / 최소 2
- 루트 EBS 볼륨 크기 : 100GiB


- 네트워크 설정
- VPC 및 Private Subnet 만 선택 후 미리 생성해둔 보안그룹 설정

- 모니터링
- Container Insights 활성화

3. 클러스터 생성 완료

ECS 작업 정의
- Amazon ECS에서 Docker 컨테이너를 실행하려면 작업 정의(Task Definition)이 필요함
- Amazon ECR 실습에서 생성한 web, cats, dogs의 도커 이미지를 참조하는 webdef, catsdef, dogsdef 작업 정의 생성
1. Web 작업 정의 생성
- 태스크 정의 패밀리 : webdef
- Launch type :
Amazon EC2 instances
- Operation system/Architecture :
Linux/X86_84
- Network mode :
bridge
- Task size
- CPU :
0.5 vCPU
- Memory :
1 GB
- CPU :
- Task execution role :
Create new role
orecsTaskExcutionRole



- ECR web 리포지토리 URI 복사

- Container 설정
- Container name:
web
- Image URI:
실습자의 web latest 이미지 URI
- Container port :
80
- Protocol :
TCP
- Port name :
web-80-tcp
- App protocol :
HTTP
- Container name:

- Logging 설정

2. Cats 작업 정의 생성
- ECS 콘솔 > 태스크 정의 > ‘JSON을 사용하여 새 태스크 정의 생성’

- ECR cats 리포지토리 URI 복사

- ECR IMAGE URI, REGION, ACCOUNT ID 수정 필요
{
"requiresCompatibilities": [
"EC2"
],
"family": "catsdef",
"containerDefinitions": [
{
"name": "cats",
"image": "<YOUR CATS ECR IMAGE URI>",
"portMappings": [
{
"name": "cats-80-tcp",
"containerPort": 80,
"hostPort": 0,
"protocol": "tcp",
"appProtocol": "http"
}
],
"essential": true,
"environment": [],
"environmentFiles": [],
"mountPoints": [],
"volumesFrom": [],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/catsdef",
"awslogs-region": "<YOUR REGION>",
"awslogs-stream-prefix": "ecs"
}
}
}
],
"volumes": [],
"networkMode": "bridge",
"memory": "1024",
"cpu": "512",
"runtimePlatform": {
"cpuArchitecture": "X86_64",
"operatingSystemFamily": "LINUX"
},
"executionRoleArn": "arn:aws:iam::<YOUR ACCOUNT ID>:role/ecsTaskExecutionRole"
}

3. Dogs 작업 정의 생성
- ECR dogs 리포지토리 URI 복사


4. ECS 작업 정의 생성 완료

5. ECS 작업 IAM 역할 수정
- IAM > 역할 > ecsTaskExecutionRole 검색

- 권한 추가 > 정책 연결 > CloudWatchFullAccess 정책 추가



ECS 서비스
1. ALB 생성
- EC2 > 로드밸런서 > 로드밸런서 생성 > ALB 생성





- 대상그룹 생성


- 대상 설정은 건너 뛰고 우선 생성

- 80 포트 대상그룹으로 web 설정 후 ALB 생성


2. Web 서비스 생성
- ECS > 클러스터 > 생성한 클러스터 내 서비스 > 서비스 생성

- 시작 유형 : EC2

- 배포 구성 설정

- 로드 밸런싱 설정


- Web 서비스 및 태스크 생성 완료


3. Cats 서비스 생성
- 배포 구성 설정

- 로드 밸런싱 설정


- Cats 서비스 및 태스크 생성 완료


4. Dogs 서비스 생성
- 시작 유형 : Fargate

- 배포 구성 설정

- 네트워킹 설정

- 로드 밸런싱 설정


- Dogs 서비스 및 태스크 생성 완료


ECS 서비스 확인
1. ECS 클러스터 서비스 상태 확인

2. ECS 클러스터 태스크 확인

3. ALB DNS 접속


- I ❤️ CATS 클릭


이번 글에서는 ECS 를 이용한 웹 애플리케이션 빌드 및 배포 Workshop을 진행해봤습니다.
자세한 내용은 아래의 AWS 공식 문서를 참고해주시길 바랍니다.
- AWS ECS : Amazon Elastic Container Service란 무엇입니까? – Amazon Elastic Container Service
- AWS ECS Workshop : Workshop Studio
NDS는 많은 클라우드 경험을 통해 서비스 도입에 도움을 드릴 수 있습니다. 관련하여 문의 사항이나 기술 지원이 필요하신 경우 NDS Sales팀으로 연락주시길 바랍니다.