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 과정
- 프로젝트의 루트 디렉토리에서 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"] - Git Action
해당 yaml 파일을 통해 git action를 실행한다. 기본적인 구성은 이벤트 트리거를 통해 해당 repository에서 push가 일어날 경우 아래 동작이 실행된다.- bulid 이미 구현된 여러 action을 통해서 repository 내의 dockerfile을 통해 docker image를 만든다.
- deploy 이후 해당 인스턴스가 이전 실행된 컨테이너를 종료, 삭제, 이미지 제거 이후 새로운 이미지의 컨테이너를 실행한다. 추가적으로 해당 프로젝트는 OPENAI_API_KEY를 다루는데 이 키값이 공개되면 자동적으로 삭제한다. 그렇기 때문에 github의 secret 값을 통해 컨테이너 실행에 key값을 할당했다.
- 러너 설정 및 ci/cd 구축 해당 git action과 인스턴스를 연결해야한다. 이를 "런너"라고 말하며 인스턴스의 환경에 따라 설정하는 방법이 다르다. 연결이 완료되면 git action과 aws ec2의 인스턴스를 통해 ci/cd 구축이 완료된다.`
# 도커 이름 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 |