[CI/CD] Github Action으로 CI/CD 구축하기 - 1. Flow 설계

Ogu·2024년 9월 6일
0
post-thumbnail

CI/CD 도입

이전까지 졸업작품이나 사이드 프로젝트를 진행했을 때는 .jar파일을 수동으로 빌드하여 Elastic Beanstalk 또는 EC2에 직접 수동배포를 진행했습니다.
그러다보니 매번 Github에 Build하여 확인 및 하는 과정, Github에 Push 이후 배포하는 과정이 통합되어있지 않아 귀찮기도 하고 비효율적이라는 생각이 들어 다음에 하는 프로젝트에서는 꼭 CI/CD를 적용해 자동화해보고 싶었습니다.

특히나 이번 프로젝트는 애자일 방법론을 채택함에 따라 빠르게 만들고, 빠르게 dev브랜치에 merge하고, 빠르게 테스트하는 과정이 요구되어 더욱 지속적인 통합, 지속적인 배포의 필요성이 대두되었고 이번 Clothstar 팀프로젝트에 CI/CD를 적용하여 빠른 빌드테스트 & 배포를 진행해보기로 했습니다.

Github Action을 선택한 이유

실무에서는 비록 Jenkins를 많이 사용하고 있지만 모든 설정을 구축하기까지 꽤나 복잡합니다.
따라서 현재 프로젝트에서 빠르게 CI/CD를 도입하여 테스트를 하는 것에 있어 Jenkins를 통한 구축은 오버스펙일 수도 있다고 판단했습니다.

또한 Github Action은 비교적 친숙한 YAML파일로 직접 작성할 수 있고, 코드 호스팅 플랫폼인 Github의 해당 Repository에서 직접 관련한 모든 설정이 가능하며, CI/CD를 위한 서버를 직접 제공하여 현재 우리 프로젝트에 빠르게 적용해볼 수 있겠다는 생각이 들어 채택하게 되었습니다.

Jenkins와 Github Actions의 차이점에는 아래와 같은 사항들이 있습니다.
(출처 : https://choseongho93.tistory.com/)

  • 설치 및 유지 관리: Jenkins는 자체 서버를 필요로 하고 설치 및 유지 관리가 필요하지만, GitHub Actions는 GitHub에서 제공하는 클라우드 기반 서비스로, 추가 서버 설정 없이 바로 사용할 수 있습니다.
  • 구성 파일: Jenkins는 XML 기반의 구성이 필요한 반면, GitHub Actions는 YAML 파일을 사용해 좀 더 간결하게 워크플로를 정의할 수 있습니다.
  • 플러그인 및 커뮤니티 지원: Jenkins는 많은 플러그인을 제공하며 커스터마이징이 가능하지만, GitHub Actions도 빠르게 성장하며 많은 공식 및 비공식 액션을 지원합니다.

Github Action

GitHub Actions는 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD(연속 통합 및 지속적인 업데이트) 플랫폼입니다. 리포지토리에 대한 모든 PR 요청을 빌드 및 테스트하거나 mergede된 PR을 Production 환경에 배포하는 워크플로를 만들 수 있습니다.

GitHub Actions은(는) 단순한 DevOps 수준을 넘어 리포지토리에서 다른 이벤트가 발생할 때 워크플로를 실행할 수 있도록 합니다. 예를 들어 누군가가 리포지토리에서 새 이슈를 만들 때마다 워크플로를 실행하여 적절한 레이블을 자동으로 추가할 수 있습니다.

Github Action에 관한 자세한 설명은 아래 공식 문서에서 확인할 수 있습니다.
GitHub Actions 설명서

Docker를 선택한 이유

Docker는 컨테이너 기반 가상화 플랫폼으로, 애플리케이션과 그 종속성을 함께 패키지화하여 어디서나 일관되게 실행할 수 있는 큰 장점이 있습니다.

Docker를 선택한 이유는 다음과 같습니다:

  • 일관된 환경 제공: Docker는 애플리케이션과 그 종속성을 컨테이너 이미지로 패키징하여 어떤 환경에서도 동일하게 실행될 수 있습니다. 이를 통해 “개발 환경에서는 잘 동작했는데, 운영 환경에서는 문제가 발생하는” 상황을 방지할 수 있습니다.

  • 이식성(Portability): Docker 컨테이너는 운영 체제에 독립적이므로, 애플리케이션이 클라우드, 온프레미스 서버, 로컬 개발 환경 등 다양한 환경에서 일관되게 동작할 수 있습니다.

  • 격리된 환경: 컨테이너는 애플리케이션과 그 환경을 다른 애플리케이션으로부터 격리시킵니다. 이를 통해 의존성 충돌을 방지하고, 여러 애플리케이션이 동시에 실행될 때도 안정성을 유지할 수 있습니다.

  • 빠른 배포와 스케일링: 컨테이너는 경량화되어 있어 가상 머신보다 빠르게 시작하고 중단할 수 있습니다. 이를 통해 배포 시간을 단축하고, 필요에 따라 애플리케이션을 빠르게 확장할 수 있습니다.

  • 효율적인 리소스 사용: Docker는 가상 머신과 달리 호스트 운영체제의 커널을 공유하기 때문에, 리소스 사용이 더 효율적이며, 더 많은 애플리케이션을 동시에 실행할 수 있습니다.

  • 풍부한 에코시스템: Docker Hub와 같은 공개 레지스트리에는 수많은 공식 및 비공식 이미지가 있어, 개발에 필요한 다양한 서비스를 빠르게 설정하고 사용할 수 있습니다.

Docker Compose를 선택한 이유

Docker Compose와 Kubernetes는 모두 컨테이너화된 애플리케이션의 오케스트레이션 도구입니다.

특히 Kubernetes는 대규모의 클러스터 관리와 복잡한 배포에 적합하고 그 구성이 꽤나 복잡합니다.

현재 프로젝트는 규모가 작고 사이드 프로젝트의 성격을 띠고 있기 때문에, 간단한 설정 파일로 여러 개의 Docker 컨테이너를 정의하고 실행할 수 있어 작은 팀 프로젝트나 테스트 환경에서 더 빠르고 쉽게 사용할 수 있는 Docker Compose를 사용해 보기로 했습니다.

CI/CD 아키텍쳐 설계

아키텍쳐 개요 및 Flow

  1. IntelliJ를 통한 코드 푸시 (IntelliJ)
  • IntelliJ IDE를 사용하여 소스 코드를 작성하고, 변경 사항을 GitHub 저장소에 Push 또는 PR(Pull Request)을 생성합니다. 이 작업은 파이프라인의 시작점으로, 코드 변경이 감지되면 GitHub Actions가 자동으로 트리거됩니다.
  1. GitHub 및 GitHub Actions
  • GitHub는 소스 코드 저장소로 사용되며, develop 브랜치로의 코드 Push 또는 PR/Merge가 발생할 때마다 GitHub Actions가 트리거됩니다.
  • GitHub Actions는 CI/CD 파이프라인을 자동화하는 도구로서, 코드가 변경되면 빌드 및 테스트를 수행하고, Docker 이미지를 build한 후 Docker Hub에 Push합니다.
  1. Docker Hub
  • Docker Hub는 Docker 이미지를 저장하는 레지스트리 역할을 합니다. GitHub Actions가 Docker 이미지를 빌드하고 푸시하면, 이 이미지는 Docker Hub에 저장됩니다.
  • Docker Hub에 저장된 이미지는 이후 배포 단계에서 AWS EC2 인스턴스가 Docker Compose를 통해 Pull하여 사용하게 됩니다.
  1. Amazon EC2 인스턴스와 Docker Compose
  • Amazon EC2 인스턴스는 실제 애플리케이션이 배포되는 서버 환경입니다. 여기서 Docker Compose를 사용하여 여러 Docker 컨테이너(Nginx와 Spring Boot)를 관리하고 실행합니다.
  • 배포 프로세스는 Docker Hub에서 최신 Nginx와 Spring Boot 이미지를 Pull한 후, Docker Compose 명령을 통해 두 컨테이너를 실행시킵니다.
  • Nginx 컨테이너는 80 포트에서 애플리케이션에 대한 요청을 수신하며, Spring Boot 컨테이너는 8080 포트에서 애플리케이션 서버로서 동작합니다. Nginx는 Spring Boot 애플리케이션으로의 트래픽을 리버스 프록시 방식으로 전달합니다.
  1. AWS RDS (MySQL)
  • AWS RDS (Relational Database Service)는 MySQL 데이터베이스를 관리하기 위한 서비스입니다. Spring Boot 애플리케이션은 데이터 저장 및 관리를 위해 RDS 인스턴스와 연결됩니다.
  • 데이터베이스 연결 정보와 자격 증명은 안전한 방식으로 관리되어야 하며, 이 정보를 Spring Boot 애플리케이션이 안전하게 접근할 수 있도록 설정되어 있습니다.
  1. Amazon EC2와 HashiCorp Vault
  • HashiCorp Vault는 자격 증명, API 키, 토큰과 같은 중요한 정보를 안전하게 저장하고 접근할 수 있는 도구입니다. Vault를 위한 AWS EC2 서버를 따로 두어 SpringBoot 애플리케이션에 필요한 민감한 정보를 안전하게 관리 및 제공합니다.
  • Spring Boot 애플리케이션은 Vault와 통신하여 MySQL 데이터베이스 자격 증명, 인코딩 Key 또는 기타 비밀 정보를 안전하게 조회하고 사용할 수 있습니다.
  1. Discord WebHook Alarm
    마지막으로 각 Github Action CI/CD 파이프라인의 결과를 Discord Webhook을 활용해 report를 알림으로 보냄으로써 팀원들이 즉각적으로 확인할 수 있도록 돕습니다.

상세 Flow

상세한 Flow 과정은 아래와 같습니다.

Github Acton Flow

기존에 테스트코드 빌드를 확인하기 위한 Github Action코드가 있었는데요, 테스트와 배포의 책임을 명확하게 분리하기 위해 AWS 배포를 위한 CI/CD 파이프라인과 테스트코드 빌드를 위한 파이프라인을 분리하기로 결정했습니다.

  • AWS CI/CD : dev-aws-CI-CD.yml
  • Test Build: gradle.yml

테스트 빌드와 배포의 책임을 분리했을 때의 장점은 아래와 같습니다.

  1. 유연한 운영: 각 파이프라인을 개별적으로 관리함으로써 코드 변경이 배포될 준비가 되지 않았을 때 테스트 파이프라인만을 통해 피드백을 받는 등 유연한 운영이 가능합니다.
  2. 빠른 피드백 루프: gradle.yml을 통해 테스트와 빌드를 빠르게 수행하여 개발자가 코드를 변경한 즉시 피드백을 받을 수 있도록 할 수 있습니다.
  3. 안정적인 배포: dev-aws-CI-CD.yml에서는 코드가 충분히 테스트된 후에만 배포되도록 하여 코드 품질과 안정성을 유지합니다.
  4. 효율적인 리소스 사용: 테스트와 빌드를 별도의 파이프라인으로 두어 배포를 위한 자원 사용을 최소화하고 효율적으로 관리할 수 있수있습니다.

AWS CI/CD

[AWS CI/CD] 에서는 GitHub Actions를 통해 자동으로 배포 프로세스를 트리거하고, 새로운 코드가 푸시되면 이미지를 build하고 AWS 인프라에 배포하는 전체 CI/CD 파이프라인을 관리합니다.
코드가 푸시되면 Spring Boot와 Nginx Docker 이미지를 빌드 및 Docker hub에 push합니다.
AWS EC2 인스턴스에서 Docker Compose를 통해 서버에 배포된 컨테이너를 자동으로 업데이트하고 실행합니다.

Test Build

[Test Build] 에서는 전체 프로젝트를 빌드하고, 테스트 코드(유닛 테스트)를 실행하여 코드가 올바르게 작동하는지 확인합니다.
코드가 develop 브랜치에 푸시되거나 PR(Pull Request)이 생성될 때 트리거되며, Gradle을 사용해 프로젝트를 빌드 및 테스트를 수행하고 테스트 결과를 report합니다.

다음 포스팅부터는 EC2 생성 및 환경 세팅부터 시작하여 실습 및 CI/CD에 필요한 파일/코드들을 작성해보도록 하겠습니다.

profile
Hello! I am Ogu, a developer who loves learning and sharing! 🐤🐤 <br> こんにちは!学ぶことと共有することが好きな開発者のOguです!🐤

0개의 댓글