카테고리 없음

CI/CD (GitHub Actions, Jenkins)

juuuuuuun 2025. 3. 25. 17:33

GitHub Actions

보통 CI 용도로 많이 쓰임

  • 코드 변경 감지
  • 애플리케이션 빌드
  • 테스트 실행
  • Docker 이미지 빌드
  • Docker Hub에 Docker 이미지 푸쉬

하지만 도커 컨테이너를 실행하고 배포하는 역할은 자동화 해주지 않기 때문에 이것을 처리 해 주는 Jenkins로 CD를 구성하면 좋음

Docker 컨테이너 자동 실행 방법 (CD)

  1. Actions + SSH(원격 접속)
    • Actions에서 서버로 SSH 접속 → docker run 명령어 실행해서 컨테이너 배포
    • 단점 : 서버에 직접 SSH 접속을 해야 하므로 보안 설정이 필요
  2. Actions + AWS ECS / GCP Cloud Run
    • Actions에서 ECS나 Cloud Run에 배포하면 컨테이너를 실행한다
    • 단점 : 설정이 많고, 인프라 관리가 복잡할 수 있다.
  3. Actions + Jenkins
    • Actions 역할
      • 코드 푸쉬 감지, Docker 이미지 빌드, Hub에 업로드
    • Jenkins 역할
      • 업로드된 이미지 가져와서 실행
      • 기존 컨테이너 종료후 새 컨테이너 실행
        • 그럼 이 과정에서 서비스가 중단될 수 있는거 아닌가? → 무중단 배포 (밑에 설명)
  • 서버에서 Docker 컨테이너 실행까지 자동으로 해주므로 Jenkins 설치만 한다면 가장 간단한 방법

Actions 예

name: CI/CD with Jenkins

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: 코드 체크아웃
        uses: actions/checkout@v3

      - name: Docker 이미지 빌드
        run: docker build -t my-app .

      - name: Docker Hub 로그인
        run: echo "${{ secrets.DOCKER_HUB_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" --password-stdin

      - name: Docker Hub에 푸시
        run: |
          docker tag my-app my-docker-repo/my-app:latest
          docker push my-docker-repo/my-app:latest

      - name: Jenkins 빌드 트리거
        run: |
          curl -X POST <http://jenkins.example.com/job/my-app/build?token=my-secret-token>

Jenkins 예

echo "Deploying new container..."

# 최신 Docker 이미지 가져오기
docker pull my-docker-repo/my-app:latest

# 기존 컨테이너 종료
docker stop my-app || true
docker rm my-app || true

# 새 컨테이너 실행
docker run -d --name my-app -p 8080:8080 my-docker-repo/my-app:latest

무중단 배포

  1. Blue-Green Deployment (가장 직관적)
    • 기존 컨테이너(blue) 실행 중
    • 새로운 컨테이너(green) 실행
    • API Gateway가 트래픽을 blue → green 전환
    • blue 컨테이너 종료
  2. Rolling Deployment (점진적 배포)
    • 새로운 컨테이너를 하나씩 추가 제거 하면서 원래 개수 유지
  3. Canary Deployment (점진적 트래픽 이동) (쿠버네티스)
    • 기존 컨테이너(90%) + 새로운 컨테이너 (10%) 실행
    • 문제 없으면 점진적으로 트래픽 전환
    • 100% 이동 후 기존 컨테이너 종료

새로운 컨테이너를 먼저 실행하면 똑같은 기능이 두개 떠있으니 문제가 발생하지 않는가?

  • API Gateway 또는 로드 밸런서를 이용해서 트래픽을 조정하면 문제없이 배포 가능
    • 새로운 컨테이너를 띄우고 트래픽을 전환 시킨 후 기존 컨테이너 종료하는 방식

공통된 GitHub Actuons를 여러 레포지토리에서 사용하는 법

  1. 한 개의 중앙 레포지토리를 만들어 재사용할 수 있는 워크플로우를 생성한다.
    • organization-name/reusable-workflows 레포지토리에 있는 .github/workflows/deploy.yml 불러와 사용
  2. jobs: deploy: uses: organization-name/reusable-workflows/.github/workflows/deploy.yml@main with: environment: production
  3. GitHub Actions 템플릿 사용
    • GitHub의 actions/chekout, actions/setup-node 같은 공용 액션을 사용하면, 여러 레포지토리에서 동일한 방식으로 설정 가능하다.
  4. Organization Level Actions 설정
    • GitHub Enterprise를 사용하면 Organization 레벨에서 공통된 Actions를 관리할 수 있다.
      • 기업에서 사용하는 유료 서비스이므로 이 방식은 적합하지 않음