개발 Dev/지속적 통합과 배포 CICD

GitOps와 AWS ECS 사용 시 베이스 도커 이미지를 활용한 배포 속도 개선 사례

Tap to restart 2024. 1. 21. 12:00
반응형

배경

사내에서 DRF로 개발하고 있으며, Github Action과 AWS ECR, ECS를 활용해서 배포를 하고 있다. Github Action에서 배포 실행 버튼을 누르면 아래와 같은 순서로 배포가 진행되었다.

1. 선택한 브랜치의 코드를 바탕으로 도커 이미지 생성해서 ECR로 이미지 업로드

2. 1번에서 업로드한 ECR 이미지로 API 서버, 워커 서버 등 배포 진행

 

문제

1번이 프로젝트가 커지고 외부 라이브러리나 팩키지 설치가 많아질수록 속도가 오래 걸렸다. 특히 PostGIS를 쓰게 됨에 따라 관련 해서 우분투에 libgdal-dev 팩키지 설치가 필요해졌는데 이 팩키지 설치만 몇 십초 씩 걸려 긴 시간이 소요되었다.

 

해결 방안

1. requirements.txt를 테스트 관련 팩키지 등을 제외하고 필수 팩키지만 남긴 requirements.base.txt로 분리한다.

2. develop으로 작업 브랜치를 병합할 때 requirements.base.txt와 DockerfileBase의 변경 사항이 있을 경우 베이스 도커 이미지를 미리 만든다.

3. 배포 때 미리 만든 베이스 도커 이미지를 사용해서 팩키지 설치 시간을 절약한다.

 

결과: 17.65% 배포 속도 개선

실제 Production 기준 8분 30초 걸리던 배포가, 7분 걸려 1분 30초를 절약할 수 있었다. 510초 -> 420초로 원래 시간 대비 (510-420)/510 × 100 ≒ 17.65% 개선되었다.

 

코드 예

DockerfileBase

FROM ubuntu:22.04

ARG PROJECT_PATH=app

RUN mkdir $PROJECT_PATH
ADD ./commons/requirements.base.txt /$PROJECT_PATH/
WORKDIR $PROJECT_PATH


RUN apt-get update && apt-get install -y python3 python3-pip libgdal-dev gettext
RUN ln -s /usr/bin/python3 /usr/bin/python

RUN pip install --upgrade pip
RUN pip install -r requirements.base.txt
RUN rm -r /$PROJECT_PATH/

 

 

create-base-docker.yaml

name: Create base docker image

on:
  push:
    branches:
      - develop
    paths:
      - deploys/DockerfileBase
      - commons/requirements.base.txt

env:
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  AWS_REGION: ap-northeast-2

jobs:
  create-base-docker-image-to-ecr:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Creating a Base Docker Image"
      - run: |
          echo $AWS_ACCESS_KEY_ID
          echo $AWS_SECRET_ACCESS_KEY
          echo $AWS_REGION

      - name: Checkout
        uses: actions/checkout@v3

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Login ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build Image
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: taptorestart/backend-base
          IMAGE_TAG: latest
        run: |
          docker build -f deploys/DockerfileBase -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG

 

Dockerfile

실제 배포 때 사용할 도커 이미지를 만들 때 기존에 만든 베이스 도커 이미지를 사용한다. 이미 필수 팩키지가 다 설치된 이미지를 사용하므로 팩키지 설치 시간이 절약된다.

FROM ECR_REGISTRY/taptorestart/backend-base:latest

...

 

반응형