[ bottle-note ] 배포 파이프라인을 구축하기 여정

DeadWhale·2024년 4월 24일
0

bottle-note

목록 보기
3/4

#bottle-note #ecs #aws

이 게시글에서 세세한 설정은 다루지 않겠습니다 저 또한 다른 분들의 매우 좋은 글을 참고했습니다.

개요

Bottle-Note 프로젝트의 프로덕션 배포 시기가 다가오면서,
프론트엔드 팀이 API 요청을 보다 원활하게 수행할 수 있도록 개발 서버 환경 구축이 필요해졌습니다.
개발서버를 구축하며 따라 운영 서버도 고민을 할 시기였는데 선택할 수 있는 배포 옵션은 다양하지만,
이미 다른 서비스에 대한 자원을 많이 사용 중인 개인 서버를 고려할 때,
클라우드 서비스를 사용하는 것이 배포의 안정성, 편의성, 확장성 측면에서 유리합니다.
이 중에서도 AWS를 선택한 배경은 아래와 같습니다:

  • NCP는 신뢰성이 점차 감소
  • GCP는 사용 가능한 크레딧이 모두 소진
  • AWS는 EC2, ECS, EKS 등 다양한 서비스 제공

EC2 VS ECS

EC2는 가상 서버 인스턴스를 제공하며 사용자가 직접 서버 관리를 해야 합니다.
반면, ECS는 컨테이너 오케스트레이션 서비스로, AWS가 클러스터 관리를 담당하며 사용자는 컨테이너 관리에 집중할 수 있습니다.

이미지 설명: EC2와 ECS의 관리 책임 구분을 나타내는 다이어그램. EC2는 운영체제와 가상 서버를 사용자가 관리하는 반면, ECS에서는 이러한 부분이 AWS에 의해 관리됩니다.

선택 이유

ECS를 선택한 이유는 아래와 같습니다:

  • 사용자 관리 범위 축소: ECS에서는 운영체제 및 하드웨어 관리가 필요 없음.
  • 개발 효율성: 컨테이너 기반으로 애플리케이션 배포와 관리가 간소화됩니다.

ECR (Elastic Container Registry)

ECR은 Docker 이미지를 저장하는 서비스로, ECS 및 EKS와 통합되어 컨테이너 이미지를 효율적으로 관리할 수 있게
도와줍니다. GitHub Actions를 사용하여 아래와 같이 ECR로 이미지를 푸시하는 과정은 매우 간단합니다:

  • 아래 yml 은 github action 에서 제공되는 설정입니다.
  
on:  
  push:  
    branches: [ "main" ] # main 브랜치에서만 진행    
permissions:  
  contents: read # 코드를 읽기만 가능하도록 설정    
# 환경변수 설정  env:  
  # Spring Boot Active Profile    
  # ACTIVE_PROFILE: ${{ github.ref == 'refs/heads/main' && '' || 'develop' }}    
  # AWS Region    
  AWS_REGION: ap-northeast-2  
  # 도커 컨테이너명    
  CONTAINER_NAME: example-container-01  
  # ECR 리포지토리명    
  ECR_REPOSITORY: develop-example-application  
  # ECS 클러스터명    
  ECS_CLUSTER: develop-example-application  
  # ECS 서비스명    
  ECS_SERVICE: develop-example-application  
  # ECS Task definition 파일명    
  ECS_TASK_DEFINITION: task-definition-develop.json  
  
jobs:  
  job:  
    name: Build & Deploy  
    runs-on: ubuntu-latest  
    environment: production  
    steps:  
      # 체크아웃    
      - name: Checkout  
        uses: actions/checkout@v3  
      # JDK 설정    
      - name: Set up JDK 17  
        uses: actions/setup-java@v3  
        with:  
          java-version: '17'  
          distribution: 'temurin'  
      # 권한 부여    
      - name: Run chmod to make gradlew executable  
        run: chmod +x ./gradlew  
      # Gradle clean build    
      - name: Build with Gradle  
        uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1  
        with:  
          arguments: clean build  
  
      # AWS 자격 인증 설정    
      - name: Configure AWS credentials  
        uses: aws-actions/configure-aws-credentials@v1  
        with:  
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}  
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}  
          aws-region: ${{ env.AWS_REGION }}  
      # ECR 로그인    
      - name: Login to Amazon ECR  
        id: login-ecr  
        uses: aws-actions/amazon-ecr-login@v1  
      # ECR에 도커 이미지 Push    
      - name: Push docker image to ECR  
        id: build-image  
        env:  
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}  
          IMAGE_TAG: latest  
        run: |  
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .    
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG    
          echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT    

ECR에 Push에 해당하는 부분인대 github action을 안다는 전제하에 보면 매우 간단한 흐름입니다.

  1. 코드 빌드:
    • 코드 체크아웃
    • JDK 설정
    • 권한 부여
    • Gradle을 이용한 빌드
  2. 이미지 푸시:
    • AWS 자격 인증 설정
    • ECR 로그인
    • ECR로 도커 이미지 푸시

이렇게만 해도 ECR 활용에 문제가 없습니다.

다만 추후 관리 시 이미지 라이프사이클은 관리하도록 설정하는것이 좋습니다.


ECS 선택: EC2 vs Fargate

일단 ECS와 EC2중에는 ECS를 선택했습니다.
> 이유는 컨테이너만 관리하면 되기 때문에 사용자가 서버에 대한 관리 오버헤드가 없기 때문입니다.
> 또한 image registry도 매우 쉽고 편하게 사용 가능한 ECR을 채택했습니다.
> 이제 고민해야 할 부분은 ECS on EC2와 ECS on Fargate중 어떤것을 선택할지 입니다.

ECS on EC2

이 옵션에서는 데이터 제어를 ECS가 맡고, 데이터플레인은 EC2가 담당합니다.
EC2 환경에서 다수의 ECS 작업이 실행되며, 인프라 관리가 필요합니다.
이에 따른 비용이 발생하며, SSH 등을 통한 직접적인 인스턴스 접근이 가능합니다.

  • EC2 환경에 여러개의 ECS 작업 실행된다.
  • 관리
    • 인프라 관리 , OS 관리 , 보안 패치 , 백업등의 작업이 필요
    • ECS에 대한 관리는 AWS에서받을 수 있다.
    • 직접 인스턴스에 접속해 문제해결이 좋다 ( ssh 등 )
  • 비용
    • 운영 비용이 높다 ( 보안 패치등 EC2 환경 관리에 대한 비용이 발생)
    • EC2환경에 대한 정보가 많아 학습 또는 문제 해결이 쉽다.
  • 확장성
    • 수평적인 확장은 조금 불편하다. ( EC2 스펙안에서만 확장됨 )
    • EC2의 스펙을 조절할 수 있다 ( 장단점을 다 가짐 )
    • 자원의 확장 자체는 쉬운편
    • 이미지 캐시가 가능

ECS on Fargate

Fargate에서는 ECS가 데이터 제어와 데이터플레인을 모두 관리합니다.
실행 호스트에 대한 접근이 제한되어 있으며, 보안 및 규정 업데이트가 자동으로 관리됩니다.
초단위 과금이 적용되어 비용 효율이 높습니다.

  • 데이터의 제어는 ECS가 데이터플레인이 Fargate
  • fatgate 환경에 하나의 ECS 작업 실행된다.
  • 관리
    • 실행 호스트에 접근할 수 없음 amazon ECS Exec 를 활용해야한다.
    • 보안 , 규정 업데이트 , 백업 등의 오케스트레이션 작업은 fargate가 관리해줌
  • 비용
    • 데이터 플레인을 관리하지 않아 EC2에 비해 운영비용이 저렴
    • ECS 태스크 작업종료 시점 까지 초단위 과금
  • 확장성
    • 이미지 캐시가 불가능, 구동시 이미지를 가져옴
    • 컨테이너 단위로 작동해 리소스 확장이 매우 쉽고 자동적으로 구현

실질적인 운영 비용은 fargate가 더 비싸다.

이미지 설명: Fargate 비용 예시. 4vCPU, 8GB RAM, 20GB 스토리지 구성 시 예상 비용


결론

전체적으로 고려해보았을때 ECS on fargate를 선택하고자 하였습니다.

그 이유로는 프로젝트의 규모와 관리 용이성과
초단위 과금과 관리의 편리성이 주된 이유입니다.

개인적으로 파일럿으로 구축해보면서 편한 부분과 난해한 부분들을 모두 느꼈습니다.

특히 ecs , ecr의 비용보다 nat gateway 비용등이 더 무서워

이런 부분들의 개선방법을 고안해봐야할것 같습니다.

0개의 댓글