AWS를 이용해 MSA 아키텍처 구축(구성) #1

임상규·2023년 10월 26일
1

AWS

목록 보기
26/33
post-thumbnail

FastAPI 앱 애플리케이션 만들기

FastAPI란

파이썬 프레임워크

  1. 빠름: (Starlette과 Pydantic 덕분에) NodeJS 및 Go와 대등할 정도로 매우 높은 성능
        사용 가능한 가장 빠른 파이썬 프레임워크 중 하나
  2. 빠른 코드 작성: 약200%에서 300%까지 기능 개발 속도 증가
  3. 적은 버그: 사람(개발자)에 의한 에러 약 40% 감소
  4. 직관적: 훌륭한 편집기 지원. 모든 곳에서 자동완성. 적은 디버깅 시간.
  5. 쉬움: 쉽게 사용하고 배우도록 설계. 적은 문서 읽기 시간
  6. 짧음: 코드 중복 최소화. 각 매개변수 선언의 여러 기능. 적은 버그.
  7. 견고함: 자동 대화형 문서와 함께 준비된 프로덕션 용 코드 제공
  8. 표준 기반: API에 대한 (완전히 호환되는) 개방형 표준 기반: OpenAPI(Swagger) 및 JSON 스키마

설치

pip install fastapi
pip install “uvicorn[standard]”

코드 내용

Main.py

from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello":"World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}

실행

uvicorn main:app --reload

브라우저에서 결과 확인

localhost:8000 ➡️ {"Hello":"World"}
localhost:8000/items/5?q=somequery ➡️ {"item_id":5,"q":"somequery"}

대화형 API 문서 (Swagger UI)
http://localhost:8000/docs

마이크로 서비스 아키텍처 설계하기

목표 아키텍처

주제

MSA에 기반하여 주문 / 관리자 페이지 / 관리 대시보드 서비스를 구축하고, Message Queue를 적용한다.

내용

  1. ALB를 사용해 각 서비스 접근 설정을 한다.
  2. MQ 클러스터를 구성하고 MQ 브로커를 설정한다.
  3. 주문 페이지에서 Message를 Producing 한다.
  4. 관리자 페이지에서 Message를 consuming 한다.

VPC 생성

위 그림과 같이 VPC / 서브넷을 구성하였다.

타겟그룹 생성

인스턴스 대상으로 타겟그룹을 위와 같이 생성하였으며 컨테이너 인스턴스가 자동으로 대상그룹에 추가 되도록 인스턴스는 추가하지 않은채로 대상그룹을 생성하였다.

ALB 생성

적절한 로드밸런서 이름 선정
스키마: 인터넷 경계
Ip address type: IPv4
VPC: 생성한 VPC
Mapping: a,c,b

애플리케이션 구성

애플리케이션은 샘플코드를 활용하여 생성

애플리케이션 실행하는데 필요한 라이브러리들을 requirements.txt에 작성

fastapi>=0.68.0,<0.69.0
pydantic>=1.8.0,<2.0.0
uvicorn>=0.15.0,<0.16.0
jinja2==3.0
aiofiles==22.1.0

Dockerfile

FROM python:3.9

WORKDIR /code

COPY ./static /code/static
COPY ./templates /code/templates
COPY ./requirements.txt /code/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

COPY ./app /code/app

EXPOSE 80

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]

Docker Build 하기

docker build -t order-app .

docker-compose.yml

version: "3.7"

services:
  fastapi:
    image: order-app
    command: uvicorn app.main:app --host 0.0.0.0 --port 80 --reload --reload-include templates
    ports:
      - 80:80
    volumes:
      - ./app:/code/app
      - ./templates:/code/templates

컨테이너 띄우기

docker-compose up

위 과정이 완료되면 localhost로 들어가서 확인

ECR 생성

Order Page 리포지토리 생성

프라이빗으로 설정하고 리포지토리 이름을 설정하고 생성하였다.

생성을 완료하였으면 해당 리포지토리로 이동하고 푸시명령 보기를 클릭한다.

해당 창이 뜰텐데 순서대로 커맨드를 실행한다.

클러스터 생성

EC2 인스턴스로 실행할 것이며 ASG을 생성한다.
이곳에서 생성할 경우 자동으로 ECS 최적화 ami를 선택해준다.
본인의 Docker Image에 맞는 크기에 맞춰 인스턴스 유형을 선택한다.

클러스터 VPC설정을 하고 ECS가 실행되는 서브넷을 선택한다.

태스크 정의 (작업 정의)

태스크는 클러스터내에서 태스크 정의를 인스턴스화 하는것이다.
ECS에서 애플리케이션에 대한 태스크 정의를 사용하는 이유는 클러스터에서 실행할 작업의 수를 지정할 수 있다.

테스크 정의는 애플리케이션을 구성하는 하나 이상의 컨테이너를 설명하는 텍스트 파일이다.
최대 10개의 컨테이너를 설명할 수 있고, 애플리케이션의 블루프린트 역할을 수행한다.
또한, 애플리케이션에 대한 다양한 파라미터를 지정할 수 있다.
예를들어 운영체제에 대한 파라미터, 사용할 컨테이너, 애플리케이션에 대해서 오픈할 포트,
작업 컨테이너와 함께 사용할 데이터 볼륨을 지정할 수 있다.

이때, 태스크 역할과 태스크 실행 역할에 ecsTaskExecutionRole을 설정하고 싶었지만
역할창에 뜨지 않아서 아래 공식문서를 참고하였다.

AWS Batch실행: IAM 역할

해당 역할을 사용한 이유는 MQ와 통합하여 작업하기 위해서 권한을 부여하기 위해 사용하였다.

전에 Docker에서 push한 이미가 리포지토리에 올라와 있을텐데 리포지토리에서 URI를 복사하여
입력한다.

서비스 실행

클러스터에 정상적으로 컨테이너 인스턴스가 올라왔다면 서비스를 실행해야한다.

위와같이 설정 후 서비스를 실행하였다.

Load Balancer URL로 접속

정상적으로 접근에 성공하였다.

Trouble Shooting

컨테이너 인스턴스 등록 실패

처음 클러스터를 구성하고 서비스를 실행하려고 하였을 때 컨테이너 인스턴스가 올라오질 않았다.

인스턴스는 정상적으로 올라왔는데 컨테이너 인스턴스가 등록되지 않아 이유에 대해서 찾아보니
EC2 인스턴스를 컨테이너 인스턴스로 등록하기 위해서는 Nat GW 나 Elastic IP를 EC2에 부착하여 ECS 클러스터와 통신을 할 수 있게 해주어야 한다고 한다.

따라서 my-msa-public-subnet-a에 Nat GW를 설치하여 해당 문제를 해결하였다.

클러스터 서비스 배포 실패

정상적으로 컨테이너가 등록되고 서비스를 배포하려고 하니

Resource handler returned message: "Error occurred during operation 'ECS Deployment Circuit Breaker was triggered'." (RequestToken: f4f4c1b0-3eb3-9fb4-3b45-5d9b5fe93254, HandlerErrorCode: GeneralServiceException)

해당 에러가 떴다.

위 에러에 대해서 찾아보니 이전 배포 실패, 시스템 부하, 네트워크 부하 등 여러 문제가 원인이라는 결과를 얻었다.

하지만 인스턴스 유형도 적당한 걸 골라 시스템 부하는 아닐테고, 네트워크 구성도 하나하나 확인해 보았는데 문제가 될 부분은 없어 보였다.

그래서 다시 찾아보니 맥북 m1으로 도커 이미지를 빌드 시 Linux에서 정상적으로 배포를 할 수 없다는 내용을 찾았고 이미지를 다시 빌드하여 문제를 해결하였다.

Linux/amd64 (x86_64) 용 빌드

docker build my-image-name --platform linux/amd64 .

docker-compose도 실행할 때 platform을 명시할 수 있다.

Service:
  Web:
    platform: linux/amd64
profile
Cloud Engineer / DevOps Engineer

0개의 댓글