Docker 기반 CI·CD 파이프라인 구축

CI/CD - CI/CD가 무엇인가?

wy-family 2024. 12. 4. 08:04

핵심은 자동화!

소프트웨어를 통한 자동화!


CI/CD(Continuous Integration/Continuous Delivery 또는 Continuous Deployment)는 소프트웨어 개발 및 배포 과정에서 효율성을 높이고, 품질을 유지하며, 신속한 배포를 가능하게 하는 핵심적인 방법론입니다. 이를 차근차근 설명해드릴게요.


1. CI/CD란 무엇인가요?

CI/CD는 크게 두 가지 주요 프로세스로 나뉩니다:

  1. CI(Continuous Integration): 개발자가 작성한 코드를 주기적으로 통합(Integration)하고 테스트하는 프로세스입니다. 목표는 코드 충돌을 빠르게 발견하고 해결하여 코드 품질을 높이는 것입니다.
  2. CD(Continuous Delivery 또는 Continuous Deployment): CI 이후의 단계를 다룹니다.
    • Continuous Delivery: 통합된 코드를 안정적으로 릴리스 가능한 상태로 유지하고, 배포(Deployment)를 자동화할 준비를 합니다. 하지만 최종 배포는 수동으로 진행될 수 있습니다.
    • Continuous Deployment: 모든 배포 단계까지 자동화하여, 코드가 통합되면 자동으로 프로덕션 환경에 배포됩니다.

2. CI/CD의 핵심 목표

  • 빠른 피드백: 코드 변경 사항에 대한 테스트 결과를 즉시 제공.
  • 자동화: 수작업을 줄이고 오류 가능성을 낮춤.
  • 효율성: 개발에서 배포까지의 시간을 단축.
  • 안정성: 일관되고 신뢰할 수 있는 배포 프로세스를 제공.

3. CI/CD 파이프라인의 주요 단계

CI/CD는 파이프라인이라는 구조를 통해 단계적으로 진행됩니다.

1단계: Code Commit (코드 커밋)

  • 개발자는 로컬에서 코드를 작성한 후 버전 관리 시스템(Git 등)에 커밋합니다.
  • 모든 커밋은 CI/CD 파이프라인의 시작점이 됩니다.

2단계: Build (빌드)

  • 커밋된 코드가 빌드 도구(Maven, Gradle 등)를 사용해 컴파일되고 실행 파일(예: JAR, WAR)이 생성됩니다.
  • 이 단계에서 코드 종속성(Dependency)이 올바르게 설치되었는지도 확인합니다.

3단계: Automated Testing (자동화 테스트)

  • 코드에 대해 작성된 단위 테스트(Unit Test), 통합 테스트(Integration Test), UI 테스트 등이 실행됩니다.
  • 목표: 코드가 예상대로 동작하는지 확인하고, 버그를 조기에 발견.

4단계: Release (릴리스 준비)

  • 코드가 테스트를 통과하면 배포 가능한 상태로 패키징됩니다.
  • Continuous Delivery에서는 이 상태에서 릴리스 관리자 또는 운영팀의 승인이 필요합니다.

5단계: Deploy (배포)

  • Continuous Deployment에서는 패키징된 코드가 자동으로 프로덕션 환경에 배포됩니다.
  • 롤링 업데이트, 블루-그린 배포 같은 기술이 사용됩니다.

6단계: Monitoring (모니터링)

  • 배포된 애플리케이션이 예상대로 동작하는지 모니터링합니다.
  • APM(Application Performance Monitoring) 도구를 사용해 성능 및 오류를 추적합니다.

4. CI/CD 도입 시 사용되는 도구

  • 버전 관리 시스템: Git, GitHub, GitLab, Bitbucket
  • CI/CD 도구:
    • Jenkins
    • GitHub Actions
    • GitLab CI/CD
    • CircleCI
    • Travis CI
  • 빌드 도구: Maven, Gradle
  • 테스트 도구: JUnit, Selenium, TestNG
  • 배포 도구: Kubernetes, Docker, Ansible

5. CI/CD의 실질적인 효과

  1. 빠른 배포 주기:
    • 고객 피드백을 더 빨리 반영 가능.
  2. 품질 향상:
    • 코드 변경마다 테스트가 실행되어 품질 유지.
  3. 자동화된 프로세스:
    • 수작업 배포에 의한 실수를 방지.

6. CI/CD의 실제 사례

가정:

  • 한 개발 팀이 전자상거래 애플리케이션을 개발 중입니다.
  1. 개발자는 제품 페이지의 새로운 기능을 구현하고, 로컬에서 테스트 후 GitHub에 푸시합니다.
  2. Jenkins가 자동으로 코드를 빌드하고, 단위 테스트와 통합 테스트를 실행합니다.
  3. 테스트가 성공하면 Jenkins가 패키지를 만들어 Docker 컨테이너로 생성합니다.
  4. Continuous Deployment가 설정된 경우, Kubernetes가 컨테이너를 자동으로 프로덕션 환경에 배포합니다.
  5. 애플리케이션 성능을 실시간으로 모니터링하고, 문제 발견 시 알림이 전송됩니다.

7. CI/CD 구축의 도전 과제

  • 초기 설정에 시간이 소요될 수 있음.
  • 테스트 코드 작성과 같은 추가 작업 필요.
  • 조직 문화 변화: 자동화 및 지속적인 통합/배포에 대한 팀의 이해와 협업 필요.

CI/CD는 현대 소프트웨어 개발에서 필수적인 요소로 자리 잡았으며, 이를 통해 더 나은 품질과 빠른 배포 주기를 달성할 수 있습니다. 한 걸음씩 자동화를 도입하고, 테스트를 강화하며, 팀의 협업을 높이는 과정에서 자연스럽게 CI/CD 환경이 정착될 것입니다.


과거에도 CICD는 있었을거 같은데, 과거의 CICD와 현재의 CICD에서 가장 중요한 차이점은 뭐야?
과거의 CI/CD와 현재 CI/CD의 가장 중요한 차이점은
**"자동화와 지속적인 피드백을 통한 속도와 효율성의 극대화"**

 

과거의 CI/CD와 현재의 CI/CD 차이점

1. 자동화 수준

  • 과거: 많은 과정이 수작업으로 이루어졌습니다. 빌드, 테스트, 배포 등이 개별적으로 실행되었고, 사람의 개입이 많아 시간이 오래 걸렸으며, 실수가 발생하기 쉬웠습니다.
    • 빌드: 수동으로 명령 실행.
    • 테스트: 수동 테스트가 주를 이룸.
    • 배포: 운영팀이 직접 서버에 배포.
  • 현재: 빌드, 테스트, 배포의 대부분이 자동화되었습니다. CI/CD 파이프라인 도구를 통해 코드가 변경되면 모든 과정이 자동으로 실행됩니다.
    • 도구: Jenkins, GitHub Actions, GitLab CI/CD 등으로 전 과정 자동화.
    • 결과: 빠르고 안정적인 프로세스.

2. 피드백 주기

  • 과거: 변경 사항에 대한 피드백이 느렸습니다. 코드를 통합하거나 테스트하는 데 며칠에서 몇 주가 걸릴 수도 있었습니다.
    • 문제 발견 시 수정에 오랜 시간이 소요.
  • 현재: 변경 사항이 발생하면 몇 분 또는 몇 시간 내에 테스트와 피드백이 제공됩니다.
    • 문제를 초기에 발견하고, 수정 주기가 짧아짐.

3. 배포 방식

  • 과거: 배포는 수동적이고, 정기적인 릴리스 주기에 의존했습니다.
    • 예: "한 달에 한 번" 또는 "분기별 릴리스".
    • 배포마다 위험 부담이 높았고, 대규모 업데이트가 일반적이었음.
  • 현재: 배포는 지속적이고 점진적으로 이루어집니다.
    • Continuous Deployment를 통해 하루에도 여러 번 배포가 가능.
    • 롤링 업데이트, 블루-그린 배포 등 안정성을 보장하는 전략 도입.

4. 도구와 환경

  • 과거: CI/CD 환경 구축이 복잡하고 비용이 많이 들었습니다. 서버를 직접 관리하거나 커스텀 스크립트를 작성해야 했습니다.
    • 예: 서버 환경 설정, 수동 빌드 스크립트 작성.
  • 현재: 클라우드 기반 도구와 컨테이너 기술(Docker, Kubernetes)로 간단하고 효율적으로 CI/CD 환경을 구축할 수 있습니다.
    • SaaS 기반 CI/CD 도구(GitHub Actions, CircleCI)로 설정이 단순화됨.
    • 확장성과 이동성이 높은 컨테이너 기반 배포.

핵심 차이

과거의 CI/CD는 부분적인 자동화와 긴 배포 주기로 인해 속도와 유연성이 낮았지만, 현재의 CI/CD는 완전한 자동화와 지속적인 피드백으로 신속하고 안정적인 배포를 가능하게 한다는 점이 가장 큰 차이입니다.

현대 CI/CD는 기술 발전(클라우드, 컨테이너)과 개발 문화(DevOps, Agile)의 영향을 받아 개발과 배포가 긴밀히 연결된 **"지속적 혁신의 도구"**가 되었습니다.


CI (Continuous Integration)

**Continuous Integration(지속적 통합)**은 소프트웨어 개발 과정에서 개발자들이 작업한 코드를 정기적으로 공유 리포지토리에 병합(Merge)하고, 병합된 코드가 자동으로 빌드 및 테스트되는 과정을 뜻합니다. CI의 목표는 변경 사항을 빨리 통합하고, 코드 충돌이나 오류를 빠르게 발견하고 해결하는 것입니다.


1. CI의 주요 개념

  1. 코드 통합
    • 개발자들이 각자 로컬 환경에서 작업한 코드를 **하나의 중앙 리포지토리(GitHub, GitLab 등)**에 주기적으로 병합합니다.
    • 병합된 코드가 서로 충돌하는지 확인하고, 통합된 상태를 유지합니다.
  2. 자동화된 빌드
    • 코드가 병합되면 CI 도구(Jenkins, GitHub Actions 등)가 자동으로 코드를 빌드합니다.
    • 빌드는 컴파일, 의존성 다운로드 등을 포함하며, 이 과정에서 문제가 있으면 즉시 알림을 보냅니다.
  3. 자동화된 테스트
    • 빌드가 성공하면 **자동화된 테스트(Unit Test, Integration Test 등)**가 실행됩니다.
    • 테스트를 통해 코드가 의도한 대로 동작하는지 확인하고, 실패 시 원인을 알려줍니다.
  4. 피드백
    • 빌드 및 테스트 결과가 개발자에게 즉시 피드백으로 제공됩니다.
    • 문제가 발생한 경우 개발자는 빠르게 수정 작업을 진행할 수 있습니다.

CI 파이프라인의 주요 구성 단계

1. Code Repository (코드 리포지토리)

  • CI 파이프라인은 코드가 저장된 버전 관리 시스템(GitHub, GitLab, Bitbucket 등)과 연동됩니다.
  • 개발자는 새로운 코드를 커밋하고 푸시하면, 이를 CI 도구가 감지하여 파이프라인을 실행합니다.

2. Build Stage (빌드 단계)

  • 작성된 코드를 컴파일하고, 필요한 라이브러리를 가져와 실행 파일로 만듭니다.
  • 사용하는 빌드 도구:
    • Java: Maven, Gradle
    • JavaScript: npm, Yarn
    • Python: pip, setuptools

3. Test Stage (테스트 단계)

  • 자동화된 테스트를 실행하여 코드 품질과 기능을 검증합니다.
    • Unit Tests (단위 테스트): 개별 함수나 모듈 테스트.
    • Integration Tests (통합 테스트): 모듈 간 상호작용 확인.
    • Code Coverage (테스트 커버리지): 테스트가 코드의 몇 %를 커버하는지 측정.

4. Packaging Stage (패키징 단계)

  • 빌드와 테스트를 통과한 코드를 패키징(예: .jar, .war, .zip 등)합니다.
  • 이 단계는 애플리케이션을 배포 가능한 형태로 준비하는 역할을 합니다.

5. Deploy Stage (배포 단계)

  • Continuous Integration에서 배포는 필수는 아니지만, 패키징된 파일을 테스트 환경(Staging)에 배포하는 설정을 추가할 수 있습니다.

6. Notification Stage (알림 단계)

  • 빌드 및 테스트 결과를 개발자에게 자동 알림으로 전송합니다.
    • 이메일, Slack, Microsoft Teams 등과 연동 가능.
  1.  

CD (Continuous Delivery/Continuous Deployment)

**Continuous Delivery(지속적 전달)**와 **Continuous Deployment(지속적 배포)**는 CI(Continuous Integration) 이후의 단계에서 소프트웨어를 릴리스 가능한 상태로 유지하고, 이를 배포 환경까지 자동화하는 프로세스를 뜻합니다.

두 개념의 차이를 먼저 간단히 설명한 뒤, 상세히 알아보겠습니다.


Continuous Delivery vs Continuous Deployment

  1. Continuous Delivery:
    • 릴리스 가능한 상태로 코드를 준비합니다.
    • 배포는 자동화되지만, 최종 배포는 수동 승인 후 진행됩니다.
    • 안정성과 검증이 더 중요한 환경에서 주로 사용.
  2. Continuous Deployment:
    • 릴리스 가능한 코드가 자동으로 배포됩니다.
    • 모든 단계가 자동화되어, 변경 사항이 즉시 프로덕션에 반영됩니다.
    • 빠른 배포와 피드백이 중요한 환경에서 적합.

1. CD의 주요 개념

Continuous Delivery

  1. 배포 준비 자동화:
    • CI를 통해 통합된 코드가 프로덕션 배포가 가능한 상태로 유지됩니다.
    • 테스트 환경에서 테스트를 모두 통과한 후, 릴리스를 승인하면 배포가 진행됩니다.
  2. 테스트 환경 배포:
    • 애플리케이션이 스테이징 환경에서 실행되어 실제 환경과 유사한 조건에서 테스트됩니다.
  3. 수동 승인:
    • 배포 전 최종 관리자의 승인이 필요하며, 승인 후 프로덕션에 배포됩니다.

Continuous Deployment

  1. 배포의 완전 자동화:
    • 코드 변경 → 테스트 → 빌드 → 배포가 모두 자동화됩니다.
    • 변경 사항이 승인 없이 프로덕션 환경에 바로 반영됩니다.
  2. 빠른 피드백 루프:
    • 실시간으로 사용자에게 변경 사항을 전달하여 피드백을 수집합니다.

2. CD 파이프라인의 주요 단계

CD는 CI 이후 단계를 확장한 것입니다. CI/CD 파이프라인에서 CD의 주된 단계는 다음과 같습니다:

1단계: 테스트 환경에 배포

  • CI에서 통합된 코드를 테스트 환경(스테이징)으로 배포합니다.
  • 스테이징 환경은 실제 프로덕션과 유사하게 설정되어 문제를 미리 발견합니다.

2단계: 최종 테스트

  • 성능 테스트, 보안 테스트, 회귀 테스트 등 추가 테스트를 실행하여 애플리케이션이 안정적인지 확인합니다.

3단계: 프로덕션 배포

  • Continuous Delivery:
    • 관리자의 수동 승인을 통해 프로덕션에 배포합니다.
  • Continuous Deployment:
    • 테스트 성공 시 자동으로 프로덕션 환경에 배포됩니다.

4단계: 모니터링

  • 배포 후 애플리케이션의 성능, 사용자 피드백, 오류를 실시간으로 모니터링합니다.
  • 문제가 발생하면 롤백(이전 버전으로 복구)을 수행합니다.

 
 

 


CI/CD 전체 파이프라인 (시각적 표현)

+---------------------+
| 개발자가 로컬에서   |
| 코드를 작성합니다.  |
+---------------------+
          |
          v
+---------------------+
| 작성한 코드를       |
| 리포지토리에 푸시  |
| (GitHub, GitLab)   |
+---------------------+
          |
          v
+---------------------+
| CI 도구가 변경사항을|
| 감지하고 빌드를 실행|
+---------------------+
          |
          v
+---------------------+
| 자동화된 테스트     |
| 실행 (Unit Test 등) |
+---------------------+
          |
      (성공/실패)
          |
          v
+---------------------+
| 스테이징 환경에     |
| 코드 배포           |
| (테스트 서버)       |
+---------------------+
          |
          v
+---------------------+
| 성능/보안 테스트    |
| 등 최종 테스트 실행 |
+---------------------+
          |
      (성공/실패)
          |
     ┌───────────┬───────────────────────────┐
     |           |                           |
     v           v                           v
+---------+  +---------------------+  +---------------------+
| 수동 승인|  | 자동으로 프로덕션  |  | 프로덕션 모니터링 및|
|          |  | 환경에 배포        |  | 로그 수집          |
+---------+  +---------------------+  +---------------------+
 
 

CI/CD 전체 파이프라인 (영어로 ASCII 스타일 표현)

 
+-------------------+
| Developer writes  |
| code locally      |
+-------------------+
          |
          v
+-------------------+
| Pushes code to    |
| repository (Git)  |
+-------------------+
          |
          v
+-------------------+
| CI Tool detects   |
| code changes      |
+-------------------+
          |
          v
+-------------------+
| Code is built     |
| (Maven, Gradle)   |
+-------------------+
          |
          v
+-------------------+
| Automated tests   |
| are executed      |
+-------------------+
          |
    (Pass/Fail)
          |
          v
+-------------------+
| Deploy to staging |
| environment       |
+-------------------+
          |
          v
+-------------------+
| Run additional    |
| tests (Performance|
| and security)     |
+-------------------+
          |
    (Pass/Fail)
          |
     ┌────────────┬────────────────────────────┐
     |            |                            |
     v            v                            v
+---------+  +-------------------+      +-------------------+
| Manual  |  | Automatic Deploy |      | Monitoring & Logs |
| Approval|  | to production    |      | in production      |
+---------+  +-------------------+      +-------------------+

요약

  1. CI 과정: 코드 작성 → 푸시 → 빌드 → 테스트 → 피드백 전달.
  2. CD 과정: 테스트 통과 후 → 스테이징 환경 배포 → 최종 테스트 → (수동/자동) 프로덕션 배포 → 모니터링.

 

CI에서의 테스트 vs CD에서의 테스트

CI에서의 테스트CD에서의 테스트는 모두 소프트웨어의 안정성을 확인하는 데 목적이 있지만, 목적과 범위가 다릅니다.


CI에서의 테스트

  • 목적: 코드의 기능적 정확성을 확인.
  • 종류:
    1. 단위 테스트 (Unit Test):
      • 개별 함수, 클래스 등의 작은 코드 조각이 올바르게 동작하는지 테스트.
      • 예: 계산기의 add() 함수가 정확히 덧셈을 수행하는지 확인.
    2. 통합 테스트 (Integration Test):
      • 서로 다른 모듈이 올바르게 상호작용하는지 확인.
      • 예: 사용자 인증 모듈과 데이터베이스 연결이 제대로 작동하는지 확인.
    3. 정적 코드 분석:
      • 코드 스타일, 포맷, 코드 복잡도 등을 자동 분석.
    4. 테스트 커버리지 측정:
      • 작성된 테스트가 코드의 몇 %를 검사하고 있는지 확인.
  • 주요 특징:
    • CI에서 테스트는 빠르게 실행되어야 함(몇 분 이내).
    • 개발자 피드백용으로 설계되며, 테스트 실패 시 바로 수정 가능.

CD에서의 테스트

  • 목적: 전체 시스템의 안정성을 확인.
  • 종류:
    1. 스모크 테스트:
      • 스테이징 환경에서 가장 기본적인 기능이 동작하는지 확인.
      • 예: 웹사이트의 홈 페이지가 로드되는지 확인.
    2. 회귀 테스트 (Regression Test):
      • 새로운 코드가 기존 기능에 영향을 미치지 않는지 확인.
    3. 성능 테스트 (Performance Test):
      • 시스템이 다양한 부하 조건에서 얼마나 잘 동작하는지 측정.
      • 예: 1,000명의 사용자가 동시에 로그인해도 서버가 견딜 수 있는지 확인.
    4. 보안 테스트:
      • 보안 취약점이 있는지 확인.
      • 예: SQL 인젝션이나 XSS(크로스 사이트 스크립팅) 취약점 탐지.
  • 주요 특징:
    • CD 테스트는 실제 프로덕션 환경과 유사한 스테이징 환경에서 실행됨.
    • 더 복잡하고 시간이 걸리는 테스트 포함(몇 시간 또는 더 길 수도 있음).
    • 프로덕션 배포 전, 전체 시스템이 안전하고 준비되었는지 확인.

CI/CD 실제 사례

가상 회사: ABC 전자상거래

목표: 전자상거래 웹사이트에서 장바구니 기능을 개선하고 새로운 할인 기능을 추가.


1. 개발(CI 단계)

  1. 개발자가 기능 구현:
    • 개발자 A는 "장바구니 할인 계산" 기능을 구현.
    • 개발자 B는 "결제 화면 UI 개선" 작업을 병행.
  2. 코드 커밋:
    • A와 B가 각각 자신의 코드를 GitHub 리포지토리에 푸시.
  3. CI 도구 작동:
    • Jenkins가 두 커밋을 감지하고, 자동으로 다음 단계를 실행:
      • 코드 빌드: 새 코드를 컴파일.
      • 단위 테스트:
        • A의 코드: 할인 계산이 정확한지 확인.
        • B의 코드: UI가 올바르게 렌더링되는지 확인.
      • 통합 테스트:
        • 장바구니와 결제 모듈이 제대로 연동되는지 확인.
  4. 테스트 피드백:
    • A의 할인 계산에 버그가 있어 CI가 실패 → A는 버그를 수정한 뒤 다시 푸시.
    • B의 코드는 성공적으로 통합 완료.

2. 배포 준비(CD 단계)

  1. 스테이징 환경 배포:
    • 통합된 코드를 테스트 환경(스테이징 서버)에 배포.
  2. 최종 테스트:
    • 스모크 테스트:
      • 장바구니에 상품을 추가하고 할인 코드 적용 후 총액이 올바르게 계산되는지 확인.
    • 회귀 테스트:
      • 기존 결제 기능이 여전히 정상 동작하는지 확인.
    • 성능 테스트:
      • 1,000명의 동시 사용자가 할인 코드를 사용하는 경우, 응답 속도가 유지되는지 확인.
  3. 수동 승인 (Continuous Delivery):
    • QA 팀이 테스트 결과를 검토하고 프로덕션 배포를 승인.
  4. 자동 배포 (Continuous Deployment):
    • 테스트와 승인 후, 프로덕션 환경으로 자동 배포.

3. 프로덕션 환경에서

  1. 모니터링:
    • 배포 후, 새로운 기능이 예상대로 동작하는지 실시간으로 모니터링.
    • 에러 로그와 사용자 피드백 수집.
  2. 롤백 준비:
    • 문제 발생 시, CD 도구를 통해 이전 버전으로 롤백.

결론

  • CI 테스트는 개발 단계에서 빠르게 실행되어, 코드가 의도대로 작동하는지 확인합니다.
  • CD 테스트는 실제 사용자와 유사한 환경에서 전체 시스템을 점검하며, 프로덕션 배포 준비 여부를 판단합니다.

CI/CD를 적용하면, ABC 전자상거래는 더 빠르고 안전하게 새로운 기능을 릴리스할 수 있으며, 고객 피드백에 신속히 대응할 수 있습니다.