본문 바로가기

backend/CICD

배포자동화 CI/CD AWS EC2, Git Action, Docker

CI/CD

Continuous Integration" 및 "Continuous Deployment"의 약자
소프트웨어 개발 프로세스의 자동화된 방식을 말함.
CI/CD는 개발자들이 애플리케이션을 효율적으로 개발, 테스트 및 배포하기 위해 사용.

AWS

아마존 닷컴에서 제공하는 클라우드 컴퓨팅 플랫폼
= 가상 서버 제공 서비스
#### 가상 서버의 필요성
    - 자원 활용, 비용절감 : 여러 가상 서버 운영가능 => 서버 구축의 효율성, 비용적 효율성
    - 확정성, 유연성 : 쉬운 생성, 복제, 확장 및 축소를 동적으로 조정 가능, 트래픽 변동에 가능 등 여러 편의성
    - 격리, 보안 : 독립적인 서버, 보안 강화
    - 테스트, 개발 : 테스트 및 개발에 유용함, 또한 실제 운영 환경과 비슷한 환경 테스트 가능
    - 운영의 편의성 : 중잉화 및 관리의 편의성, 운영 간소화

AWS EC2

EC2(Elastic Compute Cloud)는 클라우드 컴퓨팅 서비스 중 하나, 가상 서버를 제공하는 서비스
이를 통해 사용자는 필요한 만큼의 가상 서버를 생성하고 운영 가능
인스턴스라는 가상 서버를 통해서 관리 가능

Git action

github에서 제공하는 CI/CD 기능
해당 기능은 이벤트 트리거 제공
어느 리포짓토리의 변경에 대해 감지하고 작성된 워크플로우를 실행
해당 기능을 통해 CI/CD 파이프라인을 설계 가능

Docker

컨테이너 기반의 가상화 플랫폼으로, 애플리케이션의 개발, 배포, 실행을 단순하고 효율적으로 관리에 도움
Docker는 애플리케이션과 해당 애플리케이션을 실행하는 데 필요한 모든 종속성 및 설정을 포함하는 독립적인 컨테이너를 생성

Docker 이미지를 통해 컨테이너를 생성.
Docker 컨테이너는 하나의 프로세스 같이 관리되고 실행됨.
어떠한 서비스에 대한 이미지를 실행하여 컨테이너를 구성하게 되고 이 컨테이너는 하나의 역할을 하는 프로세스를 구축하게 됨.

Docker 이미지는 컨테이너를 생성하는 데 필요한 모든 파일과 설정을 포함하는 템플릿
이미지는 응용 프로그램의 실행 환경과 응용 프로그램 자체를 캡슐화하고, 버전 관리 및 공유가 가능.

CI/CD 과정

  1. 프로젝트의 루트 디렉토리에서 Docker File를 통해 Docker 이미지 생성에 대한 설정 저장
    # 파이썬 3.9 버전으로 실행 FROM python:3.9
    # work 디렉토리를 지정하여 해당 프로젝트가 어디서 실행되는지 알려줌 WORKDIR /app
     # work 디렉토리에서 ./app 경로에 있는 파일 및 디렉토리를 컨테이너 내부의 /app 경로로 복사 COPY ./app /app
    # Dockerfile에서 사용되는 빌드-타임 변수(argument)를 정의 ARG OPENAI_API_KEY
    # 정의된 빌드-타임 변수를 사용하여 런타임 환경 변수(environment variable)를 설정 ENV OPENAI_API_KEY=$OPENAI_API_KEY
    # 해당 이미지를 통해 컨테이너 실행 했을 때의 명령어, requirements 내의 파일을 설치 RUN pip install --no-cache-dir -r /app/requirements.txt # 이후 명령어를 통한 서버 시작 구문 CMD ["uvicorn", "--host", "0.0.0.0", "--port", "8000", "main:app"]
  2. Git Action
    해당 yaml 파일을 통해 git action를 실행한다. 기본적인 구성은 이벤트 트리거를 통해 해당 repository에서 push가 일어날 경우 아래 동작이 실행된다.
    1. bulid 이미 구현된 여러 action을 통해서 repository 내의 dockerfile을 통해 docker image를 만든다.
    2. deploy 이후 해당 인스턴스가 이전 실행된 컨테이너를 종료, 삭제, 이미지 제거 이후 새로운 이미지의 컨테이너를 실행한다. 추가적으로 해당 프로젝트는 OPENAI_API_KEY를 다루는데 이 키값이 공개되면 자동적으로 삭제한다. 그렇기 때문에 github의 secret 값을 통해 컨테이너 실행에 key값을 할당했다.
    3. 러너 설정 및 ci/cd 구축 해당 git action과 인스턴스를 연결해야한다. 이를 "런너"라고 말하며 인스턴스의 환경에 따라 설정하는 방법이 다르다. 연결이 완료되면 git action과 aws ec2의 인스턴스를 통해 ci/cd 구축이 완료된다.`
  3. # 도커 이름 name: CI/CD Docker # 이벤트 트리거, main에 push 할 때마다 on: push: branches: [ main ]
    # 개발 환경 설정 env: # 도커 이미지는 해당 리퍼짓토리에서 가져온다. DOCKER_IMAGE: ghcr.io/${{ github.actor }}/gptsummaryapi VERSION: ${{ github.sha }} NAME: fastapi_cicd
    # 이후 작업을 나열 jobs: # build 작업 build: name: Build # GitHub Actions에서 제공하는 Ubuntu 운영 체제의 최신 버전 runs-on: ubuntu-latest # 해당 build 단계 steps: # action 가져오기 => 이미 완성된 함수를 재사용
    # checkout@v2 # 현재 레포지토리의 코드를 워크스페이스에 체크아웃한다.
    # 이는 워크플로우가 실행되는 환경에서 코드를 사용할 수 있도록 한다. - uses: actions/checkout@v2 - name: Set up docker buildx id: buildx
    # setup-buildx-action@v1 # Docker Buildx 플러그인을 설정하고 사용할 수 있도록 환경을 설정한다. # Buildx는 Docker 이미지를 빌드하고 관리하는 데 사용되는 확장 도구이다. uses: docker/setup-buildx-action@v1 - name: Cache docker layers # actions/cache@v2 # Docker 레이어를 캐시하여 이전에 빌드된 이미지 레이어를 재사용한다.
    # 캐시는 빌드 속도를 향상시키고 중복 다운로드를 방지한다. uses: actions/cache@v2 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ env.VERSION }} restore-keys: | ${{ runner.os }}-buildx- - name: Login to ghcr
    # docker/login-action@v1 # GitHub Container Registry (ghcr.io)에 로그인한다.
    # 이 작업은 Docker 이미지를 푸시하기 위해 레지스트리에 인증하는 데 사용된다.
    # GitHub Actions에서 제공되는 GITHUB_TOKEN을 사용하여 인증합니다. uses: docker/login-action@v1 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push id: docker_build
    # docker/build-push-action@v2 # Docker 이미지를 빌드하고 레지스트리에 푸시한다. # 이 작업은 Dockerfile을 기반으로 Docker 이미지를 빌드하고, 빌드된 이미지를 지정된 레지스트리에 푸시 uses: docker/build-push-action@v2 with: context: . builder: ${{ steps.buildx.outputs.name }} push: true tags: ${{ env.DOCKER_IMAGE }}:latest build-args: | OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }} env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} # Deploy 작업 deploy: needs: build name: Deploy runs-on: [ self-hosted, label-go ] steps: - name: Login to ghcr uses: docker/login-action@v1 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Docker run run: |
    # 현재 동작 중인 컨테이너를 중지합니다. 중지에 실패하더라도 에러를 발생시키지 않습니다. sudo docker stop ${{ env.NAME }} || true
    # 이전에 실행 중이던 컨테이너를 제거한다. sudo docker rm ${{ env.NAME }} || true
    # 이전에 빌드된 이미지를 제거한다. sudo docker rmi ${{ env.DOCKER_IMAGE }}:latest || true
    # 새로운 컨테이너를 실행합니다. 포트는 8000:8--, 설정된 OPENAI_API_KEY를 셋하여 해동 도커 이미지를 통해 컨테이너를 실행한다. sudo docker run -d -p 8000:8000 --name fastapi_cicd --restart always -e OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }} ${{ env.DOCKER_IMAGE }}:latest

추가적으로 도움이 된 docker 명령어

    # 컨테이너 목록
    docker ps
    # 이미지 리스트
    docker image ls
    # 컨테이너 중지
    docker stop ${{container PID}}
    # 컨테이너 강제 중지
    docker kill ${{container PID}}
    # 이미지 삭제
    docker rmi ${{image PID}}
    # 컨테이너 삭제
    docker rm ${{container PID}}

'backend > CICD' 카테고리의 다른 글

Mixed Content 에러 해결  (0) 2024.08.01
JWT 인증을 nginx에서 처리하기 위한 방법 lua  (2) 2024.07.31
CORS 문제  (1) 2024.07.31