파이썬 프레임워크
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를 적용한다.
위 그림과 같이 VPC / 서브넷을 구성하였다.
인스턴스 대상으로 타겟그룹을 위와 같이 생성하였으며 컨테이너 인스턴스가 자동으로 대상그룹에 추가 되도록 인스턴스는 추가하지 않은채로 대상그룹을 생성하였다.
적절한 로드밸런서 이름 선정
스키마: 인터넷 경계
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로 들어가서 확인
프라이빗으로 설정하고 리포지토리 이름을 설정하고 생성하였다.
생성을 완료하였으면 해당 리포지토리로 이동하고 푸시명령 보기를 클릭한다.
해당 창이 뜰텐데 순서대로 커맨드를 실행한다.
EC2 인스턴스로 실행할 것이며 ASG을 생성한다.
이곳에서 생성할 경우 자동으로 ECS 최적화 ami를 선택해준다.
본인의 Docker Image에 맞는 크기에 맞춰 인스턴스 유형을 선택한다.
클러스터 VPC설정을 하고 ECS가 실행되는 서브넷을 선택한다.
태스크는 클러스터내에서 태스크 정의를 인스턴스화 하는것이다.
ECS에서 애플리케이션에 대한 태스크 정의를 사용하는 이유는 클러스터에서 실행할 작업의 수를 지정할 수 있다.
테스크 정의는 애플리케이션을 구성하는 하나 이상의 컨테이너를 설명하는 텍스트 파일이다.
최대 10개의 컨테이너를 설명할 수 있고, 애플리케이션의 블루프린트 역할을 수행한다.
또한, 애플리케이션에 대한 다양한 파라미터를 지정할 수 있다.
예를들어 운영체제에 대한 파라미터, 사용할 컨테이너, 애플리케이션에 대해서 오픈할 포트,
작업 컨테이너와 함께 사용할 데이터 볼륨을 지정할 수 있다.
이때, 태스크 역할과 태스크 실행 역할에 ecsTaskExecutionRole을 설정하고 싶었지만
역할창에 뜨지 않아서 아래 공식문서를 참고하였다.
해당 역할을 사용한 이유는 MQ와 통합하여 작업하기 위해서 권한을 부여하기 위해 사용하였다.
전에 Docker에서 push한 이미가 리포지토리에 올라와 있을텐데 리포지토리에서 URI를 복사하여
입력한다.
클러스터에 정상적으로 컨테이너 인스턴스가 올라왔다면 서비스를 실행해야한다.
위와같이 설정 후 서비스를 실행하였다.
정상적으로 접근에 성공하였다.
처음 클러스터를 구성하고 서비스를 실행하려고 하였을 때 컨테이너 인스턴스가 올라오질 않았다.
인스턴스는 정상적으로 올라왔는데 컨테이너 인스턴스가 등록되지 않아 이유에 대해서 찾아보니
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