Fairy ' s

Final Project 회고 본문

Devops Bootcamp

Final Project 회고

berafairy 2023. 6. 27. 15:42

 

목차

  1. 프로그램 개요
  2. 요구 사항
  3. 아키텍처
  4. 리소스 선택 이유
  5. 트러블 슈팅
  6. 향후 개선점
  7. 후기

 


프로그램 개요 및 요구사항

 


이 프로그램은 다수의 인원이 한 작업에 대해 역할을 나누어 프로젝트를 진행해야 할 때 이용할 수 있습니다. 사용자는 어떠한 내용의 Task를 생성할 수 있고, 특정 작업에 대한 담당자(가입되어 있는 사용자)를 지정합니다. 담당자는 그 작업을 진행하고, 담당자는 진행 상황이 바뀔 시 Task의 진행도를 바꿀 수 있고 진행도 혹은 Task 의 내용이 수정될 때마다 사용자에게 메일로 특정 로그 내용을 전송하여 보다 쉽게 수정된 내용을 확인할 수 있도록 합니다.


기능 요구사항

  • 작업의 진행상황을 체계적으로 관리할 수 있도록 업무를 분배하고 진행 상황을 관리할 수 있는 시스템을 구축해야한다.
  • 사용자는 개인 정보를 이용해 로그인을 할 수 있어야 한다.
  • 사용자는 새로운 Task를 생성하고, 생성한 Task를 수정하거나 삭제, 조회할 수 있어야 한다.
  • 사용자는 Task의 진행 상황을 대기 중, 진행 중, 완료 등으로 관리할 수 있어야 한다.
  • 사용자는 새로운 Task가 추가되거나, 업무 상태가 변경될 때 사용자에게 알림을 보낼 수 있어야 한다.
  • 특정 업무를 사용자에게 할당하고, 할당된 업무를 사용자가 확인할 수 있어야 한다.

 

필요한 리소스

  • 백엔드 개발:  JavaScript (Node.js)
  • 데이터베이스 관리:  Amazon RDS (MySQL)
  • 알림 시스템: AWS EventBridge, SES
  • 컨테이너화: Docker, AWS ECR, AWS ECS
  • CI/CD 파이프라인: GitHub Actions
  • 모니터링: CloudWatch 경보


인프라 요구사항

  • 사용되는 애플리케이션들은 컨테이너로 구동되어야합니다.
  • 시스템 전반에 가용성, 내결함성, 확장성, 보안성이 고려된 서비스들이 포함되어야 합니다.
  • 하나 이상의 컴퓨팅 유닛에 대한 CI/CD 파이프라인이 구성되어야합니다.
  • 시스템 메트릭 또는 저장된 데이터에 대한 하나 이상의 시각화된 모니터링 시스템이 구축되어야합니다.

최종 아키텍처

 

 

 이 프로그램은 다수의 인원이 한 작업에 대해 역할을 나누어 프로젝트를 진행해야 할 때 이용할 수 있습니다. 사용자는 어떠한 내용의 Task를 생성할 수 있고, 특정 작업에 대한 담당자(가입되어 있는 사용자)를 지정합니다. 담당자는 그 작업을 진행하고, 담당자는 진행 상황이 바뀔 시 Task의 진행도를 바꿀 수 있고 진행도 혹은 Task 의 내용이 수정될 때마다 사용자에게 메일로 특정 로그 내용을 전송하여 보다 쉽게 수정된 내용을 확인할 수 있도록 합니다.

 

 

1. 사용자는 Route53에서 배포된 도메인을 웹브라우저를 통해 접속합니다. Route53이 사용자로부터 요청을 받으면, Route53은 CloudFront에서 캐싱한 S3의 정적웹페이지를 사용자에게 보여줍니다.

2. API GateWay는 정적 웹페이지로부터 오는 트래픽을 메서드와 도메인 엔드 포인트 별로 분류해 로그인 요청 데이터는 인증 계층 Lambda로 보내고, 작업관리 요청 데이터는 VPC 경계의 ALB로 보냅니다. 이로써 ALB는 외부에 노출되지 않습니다. 반응 트래픽은 API Gateway를 통해 원래의 클라이언트로 반환됩니다. 

3. ALB(Application Load Balancer)의 주소는 외부에 노출되지 않고, API Gateway로부터 들어오는 요청을 현재 가동중인 ECS 서비스에 속한 EC2 컨테이너들로 보냅니다. 응답 트래픽은 API Gateway를 통해 원래의 클라이언트로 반환됩니다. 

4. 작업 관리를 위한 CRUD 트래픽은 ECS에 배포된 컨테이너의 EC2와 주고 받습니다. 사용자가 작업 관리 페이지에서 생성, 읽기, 업데이트, 삭제 (CRUD) 작업을 요청할 때, 이러한 요청은 ECS (Elastic Container Service)에서 실행되는 컨테이너로 전송됩니다.

5. Aurora와 통신하며, 저장된 작업 데이터를 사용해 작업 관리 페이지에서 들어오는 요청을 처리합니다. ECS의 각 인스턴스는 Amazon Aurora 데이터베이스와 연결되어 있으며, 사용자의 요청에 따라 데이터베이스에서 정보를 추출하거나 업데이트합니다.

6. ECS 인스턴스는 Amazon CloudWatch를 사용하여 ECS 인스턴스의 성능과 사용량을 실시간으로 모니터링 할 수 있습니다. 이를 통해 서비스의 건강 상태를 실시간으로 추적하고 필요한 경우 적절한 조치를 취할 수 있습니다.

7. Log DynamoDB는 사용자 요청에 따른 로그를 저장합니다, RDS에 로그가 쌓일 때마다, 사용자의 모든 요청에 대한 로그 데이터는 DynamoDB에 저장됩니다. 이를 통해 요청 처리의 성공 또는 실패, 그리고 서비스의 성능 문제 등에 대한 유용한 정보를 제공합니다.

8. EventBridge에서 설정한 규칙에 따라 로그가 필터링됩니다. Amazon EventBridge는 DynamoDB에 저장된 로그 데이터를 필터링하고 분석하는 역할을 합니다. 설정된 규칙에 따라 특정 이벤트에 대한 알림을 Lambda로 보냅니다.

9. Lambda를 통해 SES 자격증명 생성으로 보안 인증된 이메일에 로그 기록을 전송합니다. 필터링된 로그 데이터는 Lambda 함수를 사용하여 사용자의 이메일로 전송됩니다. 이를 통해 사용자는 중요한 이벤트에 대한 알림을 즉시 받을 수 있습니다.


리소스 선정 이유

 

  • Fargate vs EC2

     Fargate는 서버리스로 구동이 되고, 리소스 사용률이 높을수록 비용 방면에서 효율이 좋습니다. 하지만, ECS의 컨테이너를 구동할 때 사용하는 컴퓨팅 유닛으로 EC2를 사용하는 것이 리소스 사용률이 낮을 경우에는 Fargate가 EC2보다 평균적으로 비용이 13~18% 정도 비싸고, Cloudwatch를 통해서 리소스 예약률을 90% 이상 높게 유지하도록 auto scaling을 하도록 만들면 더 비용 절감을 할 수 있습니다.
     ASG(EC2)를 이용할 경우 인프라 관리가 어렵고 운영이 복잡할 수 있지만, 비용 방면을 고려하여 EC2를 사용하기로 결정하였습니다.

 

  • 로그 저장소 DynamoDB

     이벤트 로그 저장소 DB는 작업 변경 로그 메시지를 저장하는 것이 목적이기 때문에 매번 상황에 따라 형식과 내용이 바뀝니다. DynamoDB는 데이터가 key-value 형태로 저장되기 때문에 속성의 변경과 추가가 자유롭고 로그 메시지를 유동적으로 저장하기 용이하며, read 속도도 빨라 접속이 많이 발생해도 견딜 수 있습니다.
     구현한 아키텍처는 적은 양의 로그 데이터를 처리하기 때문에 처리 속도가 빠른 DynamoDB가 효과적일 것이라고 생각했습니다. DynamoDB는 AWS Lambda와 같은 이벤트 기반 처리 시스템과 잘 통합되어 실시간 로그 분석과 같은 복잡한 로그 처리 작업 또한 쉽게 구현할 수 있습니다.

 

  • EventBridge

     EventBridge는 분리되고 확장 가능한 이벤트 기반 시스템을 구축하는 데에 적합한 시스템 입니다. Rule을 적용해 필터링 기능을 사용할 수 있으며, 코드 작성 없이 직접 이벤트를 수신하여 다양한 서비스와 통합이 가능합니다.
     SNS, SQS 사용을 고려했을 때 가지는 장점인 엄격한 메세지 순서 보장, 높은 데이터 처리량 보다는 EventBridge 사용이 서비스에 더 적합하다고 판단하여 EventBridge를 사용하기로 결정했습니다.

 

 

 


트러블 슈팅

 

1. 서비스 컴퓨팅 옵션

 이전에는 서비스 생성을 할 때, 클러스터를 만들 때 설정했던 ASG를 용량 공급자 전략으로 설정하였었습니다. 이렇게 지정하게 되면 서비스에 태스크가 정상적으로 돌아가지 않았고, 문제 상황 파악 후 컴퓨팅 옵션의 시작유형을 EC2로 변경하려 하였습니다. 하지만, 클러스터에 등록된 EC2가 없어 시작유형 설정을 제대로 하지 못했습니다.

 

 문제는 클러스터를 연결할 때 생성했던 ASG가 관리하는 EC2 인스턴스의 IPv4 주소였는데, 위와 같이 인스턴스에 퍼블릭 IPv4 주소가 할당되어 있지 않았습니다. 이 문제의 원인은 ASG를 생성할 때 지정했던 VPC와 Subnet의 설정에 퍼블릭 IPv4 주소 자동 할당 여부에 있었습니다.

 

AWS의 콘솔에서 VPC의 Subnet 탭을 가보면 각 서브넷 별로 퍼블릭 IPv4 주소 자동 할당 옵션이 있는데, 만들었던 public subnet의 자동할당 옵션이 아니오로 되어 있었습니다. 이 여부를 '예'로 바꾸어 준 뒤 ASG를 생성하였더니 인스턴스에 퍼블릭 IP가 부여되어 클러스터 내에 인스턴스 컨테이너가 정상적으로 생성되었고, 컴퓨팅 옵션을 EC2로 지정할 수 있게 되었습니다.

 

또한, 인스턴스에 퍼블릭 IP가 부여 되지 않을 당시에는 컨테이너 인스턴스가 등록되지 않았는데, 인스턴스에 IP 주소가 생긴 후 컨테이너 인스턴스가 정상적으로 등록되는 것을 확인할 수 있었습니다.

 

2. 태스크용 컨테이너 미생성

태스크 생성 시 컨테이너가 잡히지 않았는데, 에러 로그의 내용을 살펴보니 생성된 EC2의 메모리의 크기가 컨테이너보다 작아서 발생 된 문제였습니다. 

 

클러스터를와 함께 ASG를 생성할 때 EC2 인스턴스 유형을 t3.nano 에서 m6i.large로 바꿔주어 생성했더니 정상적으로 컨테이너가 생성 되었습니다.

 

3. 배포 실패, Target Unhealthy

서비스에 태스크 생성 시 타겟의 상태가 unhealthy가 떴고, 원인은 타겟 그룹과 ALB 의 포트 매핑이 잘못되어 원활하게 포트를 못 잡고 있었습니다.

포트 매핑을 ALB (80) - Listener(80) - Target Group (3000) - 컨테이너 (3000) 로 다시 잡아주었습니다

또한, 보안 그룹에 불필요한 포트가 많아, 필요한 포트만 남게 정리하였습니다.

 

 

이런 이슈를 거친 후 마침내 배포를 성공했고, 로그에 상태 코드가 200으로 나오는 것을 볼 수 있었습니다.

또한 ALB 엔드포인트로 접속하였을때 DB에서 값을 정상적으로 불러오는 것도 확인하였습니다.

 

4. ECS 컨테이너 DynamoDB 접근 불가 Issue

 ECS 클러스터로 배포는 했지만 배포된 컨테이너가 다이나모 DB에 제대로 아이템을 넣지 못하는 문제가 있었습니다. 그래서 클러스터에 배포된 이미지와 같은 이미지를 로컬로 PULL 해온 뒤 테스트 했고, 화면처럼 RDS와 DynamoDB 모두와 잘 상호작용하는 모습을 확인해 이미지 문제가 아니라는 것을 알 수 있었습니다.

 

 ECR에 배포된 이미지가 정상임에도 실제 배포 환경에서 제대로 작동하지 않는 문제는 권한 문제가 원인일 수도 있다고 생각해 Task의 실행 역할을 확인했습니다. 확인해보니 역시나 DynamoDB의 엑세스 권한이 없었고 권한을 넣어주었습니다. 그러나 권한을 넣었음에도 제대로 작동하지 않았고, 다른 원인을 찾아보았습니다.

 

다른 원인을 찾아보던 중 아마존 공식 문서에서 관련된 내용을 찾을 수 있었습니다. VPC 엔드 포인트를 통해 DynamoDB에 엑세스할 수 있도록 설정했더니, 문제 없이 DynamoDB에 아이템이 들어가는 것을 확인할 수 있었습니다.

>> 관련 문서


아키텍처 보안 강화

 

 현재 저희가 구상한 아키텍처에는 ECS가 Public Subnet 에 위치하게 되어 보안 부분에 취약 할 수 있다는 우려가 있어 다음과 같이 아키텍처를 보완 하였습니다. ECS 와 DB서버를 Private Subnet에 위치하고 NAT Gateway를 Public Subnet으로 분리하여 ECS와의 통신은 유지 하면서 내부의 IP주소 노출 위험을 제거하였습니다. 실제 현업에서도 많은 기업의 아키텍쳐가 이렇게 구성 되어있다고 합니다.

AZ 하나당 1개의 NAT Gateway를 사용하는 이유

  • 비용 : AZ간의 통신에 비용발생
  • 고가용성 : 1개 AZ에서 문제 발생시 시스템 영향 최소화

후기


 처음엔 백지부터 주제도 직접 선정하고 요구사항과 아키텍처까지 하나하나 적어나가려고 하니 시작부터 막막한 기분이 들었습니다. 하지만 팀원마다 각자 다른 강점을 보유하고 있었고, 서로 모르는 점에 대해 열정적으로 알려주려 했고 이해하려 했기 때문에 서로 도움이 많이 되었습니다.

 또한 크고 작은 여러 트러블들을 겪으면서 그만큼 많은 시간을 투자하였는데, 이렇게 글로 결과만 정리해보니 생각보다 길지 않은 트러블을 많은 시간을 투자했었던 것 같습니다. 그래서 더욱 내가 투자한 시간들을 헛되이 하지 않게 이 문제들을 나의 것으로 만들어서 들고 가야겠다고 생각했습니다.

 문제가 발생하지 않았던 부분도 문제를 해결하기 위해서 수많은 테스트를 거치며 원래 알던 틀에서 세세한 부분까지 깊숙하게 공부하게 되었고 가치 있는 2주일을 보냈던 것 같습니다.

'Devops Bootcamp' 카테고리의 다른 글

[7. Apr] 발표  (0) 2023.04.07
[7. Apr] 아키텍처 / TIL  (0) 2023.04.07
[6. Apr] 발표  (0) 2023.04.06
[6. Apr] TCP/IP 4계층,OSI 7계층 / TIL  (0) 2023.04.06
[5. Apr] 1st project  (0) 2023.04.05
Comments