코드를 푸시하면 자동으로 테스트가 돌고, 문제가 없으면 바로 서버에 반영되는 구조를 어떻게 만들까요?

CI/CD는 현대 소프트웨어 개발의 기본 인프라입니다. 공부하다 보니 용어가 비슷비슷해서 헷갈리는 부분이 많았는데, 핵심 개념부터 차근차근 정리해보겠습니다.

CI — Continuous Integration

코드 변경을 메인 브랜치에 자주 통합하고, 매번 자동으로 빌드와 테스트를 실행하는 것입니다.

핵심 원칙:

  • 개발자가 하루에 한 번 이상 코드를 통합
  • 통합할 때마다 자동으로 빌드 + 테스트 실행
  • 실패하면 즉시 알림 → 빠른 수정

CI가 없으면 생기는 문제:

  • "내 로컬에선 되는데?" — 통합 환경에서만 발생하는 버그
  • 머지 데이 지옥 — 오랫동안 분리된 브랜치를 합칠 때 대량 충돌
  • "누가 깨뜨렸어?" — 빌드 실패 원인 추적이 어려움

CD — Continuous Delivery vs Continuous Deployment

여기서 많이 헷갈리는 부분이 있습니다. CD는 두 가지 의미가 있습니다.

Continuous Delivery (지속적 전달):

  • 프로덕션 배포 ** 준비 **까지 자동화
  • 실제 배포는 수동 승인(버튼 클릭)을 거침
  • 대부분의 기업이 채택하는 방식

Continuous Deployment (지속적 배포):

  • 모든 단계가 자동 — 테스트 통과하면 바로 프로덕션에 배포
  • 높은 테스트 커버리지와 모니터링이 전제
  • Netflix, GitHub 등 성숙한 조직에서 사용

면접에서 "CD가 뭐냐"고 물으면 둘 다 설명하고 차이를 명확히 하는 것이 포인트입니다.

파이프라인 구성

전형적인 CI/CD 파이프라인의 흐름입니다:

PLAINTEXT
코드 푸시 → 빌드 → 테스트 → 보안 검사 → 스테이징 배포 → 승인 → 프로덕션 배포

각 단계를 살펴보겠습니다:

  1. ** 소스** — 코드 푸시 또는 PR 생성 시 파이프라인 트리거
  2. ** 빌드** — 컴파일, 의존성 설치, 아티팩트(JAR, Docker 이미지) 생성
  3. ** 테스트** — 단위 → 통합 → E2E 순서로 실행
  4. ** 보안 검사** — SAST/DAST 도구로 취약점 스캔
  5. ** 스테이징 배포** — 프로덕션과 동일한 환경에서 검증
  6. ** 프로덕션 배포** — 승인 후 실제 사용자에게 배포

테스트 피라미드 적용

CI/CD 파이프라인에서 테스트는 피라미드 구조를 따릅니다:

PLAINTEXT
      /  E2E  \         ← 느리고, 비쌈 (소수)
     /  통합   \        ← 중간 (적당히)
    / 단위 테스트 \     ← 빠르고, 저렴 (다수)
  • ** 단위 테스트** — 함수/메서드 단위, 수초 내 실행. 전체의 70~80%
  • ** 통합 테스트** — DB, 외부 API 연동 검증. 전체의 15~20%
  • E2E 테스트 — 사용자 시나리오 전체 검증. 전체의 5~10%

파이프라인에서는 빠른 테스트부터 실행합니다. 단위 테스트가 실패하면 통합 테스트를 굳이 돌릴 필요가 없습니다.

GitHub Actions 기본 문법

2026년 기준 GitHub Actions가 CI/CD 도구의 사실상 표준입니다.

YAML
# .github/workflows/ci.yml
name: CI Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      # 소스 코드 체크아웃
      - uses: actions/checkout@v4

      # JDK 설정
      - uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'

      # 빌드 및 테스트
      - name: Build & Test
        run: ./gradlew build

      # 테스트 결과 리포트
      - name: Publish Test Report
        if: always()
        uses: dorny/test-reporter@v1
        with:
          name: Test Results
          path: build/test-results/test/*.xml
          reporter: java-junit

핵심 개념:

  • on — 트리거 조건 (push, PR, 스케줄 등)
  • jobs — 병렬 실행 가능한 작업 단위
  • steps — 순차 실행되는 각 단계
  • uses — 재사용 가능한 액션 (마켓플레이스)

브랜치 전략과 CI/CD

트렁크 기반 개발 (Trunk-Based)

PLAINTEXT
main ──●──●──●──●──●──●──
        \  /    \  /
      feature  feature
      (1~2일)  (1~2일)
  • 메인 브랜치에 자주 통합 (하루 1회 이상)
  • 피처 브랜치 수명 1~2일 이내
  • CI/CD와 궁합이 좋음 — 작은 변경을 자주 배포

Gitflow

PLAINTEXT
main ─────────────────────────
  └── develop ──●──●──●──●──
                 \      /
               feature branch
               (수일~수주)
  • 장기 피처 브랜치 + develop/release 브랜치 분리
  • 릴리스 주기가 긴 프로젝트에 적합
  • CI/CD 복잡도 증가 — 여러 브랜치에 파이프라인 설정 필요

최근 추세는 트렁크 기반 개발 + 피처 플래그 조합입니다.

시프트 레프트 보안

보안 검사를 개발/빌드 단계로 앞당기는 접근입니다. 2026년 기준 선택이 아닌 필수가 되었습니다.

  • SAST (Static Application Security Testing) — 소스 코드 정적 분석. 빌드 시점에 실행
  • DAST (Dynamic Application Security Testing) — 실행 중인 앱에 공격 시뮬레이션
  • SCA (Software Composition Analysis) — 의존성 라이브러리 취약점 검사
  • ** 시크릿 스캔** — 코드에 포함된 API 키, 비밀번호 탐지
YAML
# GitHub Actions에서 보안 스캔 예시
- name: Security Scan
  uses: github/codeql-action/analyze@v3
  with:
    languages: java

환경 분리

PLAINTEXT
dev → staging → production
  • dev — 개발자 로컬 또는 공유 개발 환경. 자유롭게 배포
  • staging — 프로덕션과 동일한 구성. QA 및 최종 검증
  • production — 실제 사용자가 접근하는 환경

각 환경별로 설정(DB 주소, API 키 등)을 분리하고, 시크릿은 환경 변수나 시크릿 매니저로 관리합니다.

배포 전략

블루-그린 배포

PLAINTEXT
Blue (현재) ──── 트래픽 ────→ 사용자
Green (새 버전) ── 대기 ──

배포 시:
Blue (이전) ──── 대기 ──
Green (새 버전) ── 트래픽 ──→ 사용자
  • 두 개의 동일한 환경을 운영
  • 트래픽을 한 번에 전환 (로드밸런서 설정 변경)
  • 롤백이 빠름 — 다시 블루로 전환하면 됨
  • 단점: 인프라 비용 2배

카나리 배포

PLAINTEXT
기존 버전 ── 95% 트래픽 ──→ 사용자
새 버전   ──  5% 트래픽 ──→ 사용자 (모니터링)
  • 소수 사용자에게만 새 버전 노출
  • 메트릭(에러율, 응답시간) 확인 후 점진적으로 비율 증가
  • 문제 발견 시 빠르게 롤백
  • 대규모 서비스에서 선호하는 방식

정리

  • CI 는 자주 통합하고 자동 테스트, CD 는 배포 자동화 (Delivery vs Deployment 구분)
  • 테스트 피라미드: 단위 > 통합 > E2E 순으로 많이 작성
  • GitHub Actions로 빌드 → 테스트 → 보안 검사 → 배포 파이프라인 구성
  • 시프트 레프트 보안은 더 이상 선택이 아닌 필수
  • 블루-그린은 빠른 롤백, 카나리는 점진적 검증에 적합
  • 트렁크 기반 개발이 CI/CD와 가장 잘 맞는 브랜치 전략
댓글 로딩 중...