CI / CD

양치는 하셨나요·2024년 9월 13일
1
post-thumbnail

지난 Dev Ops 에서 클라우드 관련 이야기를 하며 간단히 나왔던 단어이다. 그때 CI / CD는 내용이 좀 있으니 따로 다루겠다고 하였으니 이렇게 작성해 본다.

CI(Continuous Integration)

배경

CI가 적용되기 이전 기존 환경에서 개발자는 기존 코드의 수정을 위해 저장소에서 코드의 복사본을 받아 작업한다. 이때 다른 개발자가 코드를 변경하고 코드 저장소에 업로드 했다면 개발자가 받아온 복사본과 저장소의 코드가 달라진다. 이때 단순히 달라지는 것을 넘어 라이브러이 같은 의존성이 추가 되는 등의 큰 변화가 생길 수도 있다.

이런 일이 반복적으로 일어나 중첩 된다면 저장소와 개발자의 코드가 너무 많이 달라지는 통합의 지옥에 빠질 수 있다.

이런 문제를 피하기 위해 나온 것이 CI, 지속적 통합이다.

개념

위의 배경을 기억하고 이전 글에 썼던 부분과 위키백과에서의 정의를 살펴본다.

CI(Continuous Integration, 지속적 통합)
- 코드의 수정 사항을 레포지토리에 자동으로 자주 통합하는 것
- 필요성
- 버그를 빨리 찾을 수 있다.
- 완료된 코드에 대한 빠른 전달이 가능하다.
- 지속적 배포가 가능하다.

지속적 통합(continuous integration, CI)은 지속적으로 품질 관리(Quality Control)를 적용하는 프로세스를 실행하는 것이다. - 작은 단위의 작업, 빈번한 적용. 지속적인 통합은 모든 개발을 완료한 뒤에 품질 관리를 적용하는 고전적인 방법을 대체하는 방법으로서 소프트웨어의 질적 향상과 소프트웨어를 배포하는데 걸리는 시간을 줄이는데 초점이 맞추어져 있다. 대표적인 CI 툴에는 젠킨스(Jenkins)가 있다.

위의 배경과 정의를 보면 알 수 있는 내용이 몇가지 있다.

  • 기존의 환경에서 발생할 수 있는 문제인 통합의 지옥과 같은 문제를 해결하기 위해 지속적인 품질 관리 프로세스를 적용하고 실행하는 것이다.
  • 작은 단위의 작업과 빈번한 적용, 지속적인 통합을 한다.
  • 소프트웨어의 질적 향상과 배포까지 걸리는 시간을 줄이는 데 초점이 맞춰져있다.

→ 기존 환경에서 통합의 지옥 문제와 더불어 통합 시 생기는 문제들로 인한 재작업 등의 문제를 해결하고 더불어 배포까지 걸리는 시간도 단축 시키기 위해 작은 단위의 작업과 빈번한 적용, 지속적 통합 등을 하는 방법이다.

적용

이러한 방법, 프로세스는 개발 단계 중에서 Code, Build, Test 단계에 적용 가능하다.

  • Code : 개발자가 코드를 원격 코드 저장소 (Ex. github repository)에 push하는 단계.
  • Build : 원격 코드 저장소로부터 코드를 가져와 유닛 테스트 후 빌드하는 단계
  • Test : 코드 빌드의 결과물이 다른 컴포넌트와 잘 통합되는 지 확인하는 과정

이런 단계에서 적용하는 방법은 아래의 과정을 통해 CI를 만족한다.

  1. 코드 버전 관리 시스템

    위의 단계들에서 우리는 원격 저장소를 비롯한 다양한 저장소를 사용 하는데 이 중에서 버전 관리 시스템을 사용 하여 주기적으로 자주 Push를 하여 코드를 업로드 한다.

  2. 빌드의 자동화

    이렇게 올라온 코드들을 병합하는 과정을 자동화 하여 빌드까지의 과정을 자동으로 진행 되도록 한다.

    병합의 자동화는 우리도 어느정도 알 수 있다. git에서 merge를 하는 것이 바로 그것인데, merge를 할 때 기본적으로 추가된 내용이나 삭제된 내용에 대해서는 자동으로 반영되도록 하고 이런 자동화 알고리즘에서 오류가 생길 수 있는 부분(같은 부분에 서로 다른 내용이 있어 어떤 내용이 먼저 와야 하는지 모를 때 등)만 선택해주면 나머지는 자동으로 병합된다.

  3. 테스트의 자동화

    이렇게 성공한 빌드를 자동으로 유닛 테스트(Unit Test) 및 통합 테스트를 실행하여 코드의 성공 여부와 품질을 확인한다.

특징

위의 적용 방법에서도 유츄 가능한 내용이지만 한 번 더 정리해보자면 아래와 같다.

  • 자동화된 테스트 코드 변경 시마다 테스트가 자동으로 수행되므로 버그가 초기에 발견 가능하다.
  • 빠른 피드백 위의 테스트에서 나온 결과를 통해 오류나 문제를 빠르게 발견하고 수정할 수 있다.
  • 자주 통합 코드 충돌을 줄이고, 코드베이스의 일관성을 유지하여 안정적인 프로젝트 진행이 가능해진다.
    • 코드베이스: 소프트웨어 or 프로젝트의 소스코드 집합

장점

  • 버그 조기 발견 특징에서 이어 오는 내용인데 자동화된 테스트를 통해 작은 코드 변경에도 자동으로 테스트가 수행 할 수 있어 버그를 빨리 찾아 문제를 빨리 고칠 수 있다.
  • 지속적인 코드 품질 향상 자동화된 테스트 과정으로 코드가 자주 테스트 될 수 있어 프로젝트 전체적인 품질 관리가 쉬워진다.

단점

  • 초기 설정 비용 CI 시스템을 도입하기 위해서는 초기 설정과 인프라 구성이 필요하다. Git을 비롯해 자동화된 병합 시스템과 테스트 시스템이 필요하기 때문에 이에 대한 적용과 이해가 필요하다.
  • 테스트 의존성 테스트가 커버 가능한 영역이 부족하거나 잘못된 테스트가 작성되면 제대로 된 CI 결과를 얻기 어렵다. 이럴 경우 자동화 테스트를 이용해서 오류를 못 찾는 것보다 사람이 테스트를 진행해 더 명확한 테스트를 하는 것이 긍정적일 수도 있다.

CD (Continuous Delivery or Deployment)

개념

CD는 CI와 같이 나오는 개념 혹은 방법인데 이 또한 CI처럼 지난 글에서 썼던 내용과 위키백과의 내용을 살펴본다.

CI에서 통합된 수정 사항들이 자동화된 테스트 환경을 거쳐 업로드 하여 따로 테스트를 진행하지 않고도 바로 배포 가능하도록 하는 것
- 특징
- 지속적 배포 = 지속적 통합 + 지속적 전달
- 코드의 변경 = 배포
- 프로비저닝
- 사용자의 요구에 맞게 시스템을 제공하는 것.

지속적 전달(Continuous delivery, CD)은 팀이 짧은 주기로 소프트웨어를 개발하는 소프트웨어 공학적 접근 방법으로, 소프트웨어를 언제든지 신뢰 가능한 수준으로 출시할 수 있도록 보증하기 위한 것이다. 지속적 전달은 소프트웨어를 더 빠르게 주기적으로 빌드하고 테스트하고 출시하는 것을 목표로 한다. 이러한 접근은 더 많은 증분 업데이트를 제품 단계의 애플리케이션에 적용할 수 있게 함으로써 비용, 시간과 변경사항의 배포에 따른 위험을 줄일 수 있게 한다. 단순하고 반복할 수 있는 배포 프로세스는 지속적 전달에 있어 중요한 요소이다.

여기서 몇가지 중요 포인트를 뽑아 본다.

  • 팀이 짧은 주기로 개발하는 소프트웨어의 공학적 접근 방법이다.
  • 소프트에어를 신뢰 가능한 수준으로 출시할 수 있도록 보증하기 위해 하는 것이다.
  • 빠른 주기로 빌드, 테스트, 출시를 목표로 한다.
  • 더 많은 증분 업데이트를 제품 단계의 애플리케이션에 적용 할 수 있게 하여 변경에 대한 위험을 줄인다.

→ 프로젝트에서 애플리케이션을 배포하는 과정에서 CI를 활용해 테스트 단계까지 진행 하고 이를 배포하는 과정까지 빠르게 적용 할 수 있도록 하는프로세스를 말한다.

적용

CD는 개발 단계에서 Release, Deploy, Operate 단계에서 적용된다.

  • Release : 배포 가능한 소프트웨어 패키지를 작성.
  • Deploy : 프로비저닝을 실행하고 서비스를 사용자에게 노출 => 실질적인 배포
  • Operate : 서비스 현황을 파악하고 생길 수 있는 문제를 감지

이 단계에서 CD는 아래의 과정으로 적용 가능하다.

  1. CI 완료

    CD는 CI를 통해 코드가 빌드되고 테스트된 후 배포가 가능한 상태가 된 것을 기반으로 하기 때문에 CI가 적용되고 동작하는 상태에서 시작한다.

  2. 자동화된 배포 준비

    CI를 통해 테스트 완료 되고 빌드된 코드가 프로덕션 환경에서 동작 준비가 완료된다. 이를 위해 스테이징 환경에 배포하여 배포 전 최종 테스트를 진행 할 수 있다.

  3. 자동화된 배포 (CD)

    Continuous Deployment의 경우, 테스트가 끝나면 현재 배포 중인 환경에 자동으로 배포된다.

    • 여기서 CD의 두가지 면이 혼동 될 수 있어 추가 하자면 CD는 Delevery와 Deployment가 혼용된다. Delevery는 전달이란 뜻으로 CI의 과정을 포함하여 배포 직전 단계까지 지속적인 업데이트를 한다는 의미이고 Deployment는 배포란 뜻으로 이렇게 전달 된 데이터를 지속적으로 배포 단계에 반영하여 업데이트 내용을 지속적으로 배포 한다는 의미이다.

특징

  • 지속적 배포 코드가 배포 가능한 상태인지 항상 확인 가능하고, 필요 시 즉시 배포까지 할 수 있다.
  • 자동화된 배포 파이프라인 빌드, 테스트, 배포를 자동화하여 개발자의 개입 없이 시스템이 동작 가능하다.

장점

  • 빠른 제품 출시 특징에서 나온 것처럼 자동화된 배포 덕분에 변경 사항이 빠르게 사용자에게 전달 가능하다.
  • 높은 신뢰성 배포 프로세스가 자동화되어 배포 중 실수나 문제를 최소화 할 수 있다.

단점

  • 배포 안정성 문제 모든 변경 사항이 자동으로 배포된다는 장점이 있지만 반대로 자동 배포라는 시스템이 예상치 못한 문제나 버그가 생겨 자동 배포 단계에서 문제가 생길 수 있다.
  • 복잡한 설정 배포 환경을 자동화하기 위한 설정이 복잡할 가능성이 있다. 특히 프로젝트가 큰 규모가 된다고 하면 더욱 세세하게 설정 해야 하기 때문에 이 단점이 더 크게 다가올 수 있다.

CI + CD

사실 CD가 CI의 개념을 포괄하고 있기 때문에 CD를 적용 하는 것이 곧 CI를 적용 하는 것이라 볼 수 있긴 하다. 그래서 CI와 CD를 같이 적용 하는 방법과 이런 과정을 지원하는 도구들 몇가지를 소개한다.

적용

  1. CI 파이프라인 구성

    코드가 버전 관리 시스템에 Push되면 자동으로 빌드 및 테스트가 진행되도록 설정한다.

    • 파이프라인: 하나의 과정을 여러 단계로 나누고 각 단계에서 동시에 작업들을 처리 하는 것
  2. CD 파이프라인 구성

    빌드 및 테스트가 완료된 후, 자동으로 스테이징 환경에 배포되도록 설정하고 마지막 테스트를 수행한 뒤, 프로덕션에 배포할지 결정한다.

  3. 자동화 툴 사용

    Jenkins, GitLab CI, CircleCI 등의 CI/CD 도구를 사용하여 전체 파이프라인을 구성 가능하다.

  4. 환경 분리

    개발, 테스트, 프로덕션 환경을 분리하여 단계별로 검증 후 배포까지 진행한다.

Tools

  1. GitHub Actions
    • 개인 프로젝트를 위한 가장 인기 있는 도구이다.
    • 깃허브 중 어떤 이벤트든지 상관 없이 워크 플로우를 만들 수 있다.
    • public 리포지터리에는 무료, private 에는 유료이다.
    • 클라우드를 이용해 동작하므로 호스팅에 대한 부담이 적다.
    • 러닝커브는 쉬운편이지만 사용하는데 문제점들이 조금씩 있다고 한다.
    • 폭넓은 플랫폼 및 라이브러리를 지원한다.
  2. Jenkins
    • 오픈소스이며 무료이다.
    • 서버를 직접 호스팅 해야 한다.
      • 호스팅을 직접 관리 하므로 관련된 모든 부분이 관리 가능하다.
      • 프로젝트의 규모에 따라 리소스 낭비가 발생할 수 있다.
    • 많은 플러그인을 지원하고, 쉽게 사용자 설정이 가능하다.
    • 많은 회사에서 사용하고 있다고 한다.
  3. GitLab CI
    • GItLab 서비스에 내장되어 있다.
    • 온프레미스 방식으로 호스팅하거나 웹으로 사용할 수도 있다.
      • 온프레미스: 기업이 자체적으로 인프라를 소유하고 관리하는 것.
    • Runner 가 도커 컨테이너 기반이라 도커 친화적이다.
      • 도커: 가상화 컨테이너 기술 중 하나로 운영체제가 아닌 응용프로그램 만을 가상화 하여 응용프로그램들을 격리하고 실행하여 배포 할 수 있는 기술이다. 이 또한 내용이 좀 많아서 추후 기회가 되면 추가 조사 해 보겠다.
    • 플러그인의 종류가 위의 도구에 비하면 빈약하다.

선택

어떤 도구를 선택 할 것인가를 따지면 Jenkins이지 않을까 생각한다. 일단 무료인 것이 가장 크게 느껴지고 다양한 회사에서 사용 하고 있으며 다양한 플러그인 지원과 사용자 설정이 자유로운 환경을 제공 해 줄 수 있다고 한다.

추가로 다른 사람이 이 세가지를 비교해 둔 표가 있어 이를 가져오며 마무리 한다.

JenkinsGithub ActionsGitLab
서버별도의 서버 필요.클라우드로 동작. 별도의 설치 X.클라우드 or 설치형 두 개.
비용툴 자체 라이선스는 무료.하지만 젠킨스 서버를 유지하는 비용 소모.Private Repository는 한달에 500MB,2,000분 까지 무료로 사용.초과되는 Minutes 마다 추가 비용 지불.무료로 400분의 CI/CD 사용 지원. 추가 이용하기 위해선 유료 라이선스 必.
OS모든 OS 호환 가능.모든 OS 호환 가능.모든 OS 호환 가능.
플러그인약 1,400 개의 플러그인 존재.Jenkins에 비해 적음.스크립트로 플러그인 추가 가능.Jenkins에 비해 적음.
동기 / 비동기젠킨스 파이프라인을 통한 비동기 처리 가능.비동기 CI / CD 가능.비동기 처리 가능.
사용성GUI라 친근하지만 초기 설정이 까다로움.Github에 친숙한 개발자에게는 더 좋음.초기 설정이 쉬움.Github에 친숙한 개발자에게는 더 좋음.초기 설정이 쉬움.
문서화전 세계 많은 사람들이 이용하기 떄문에 문서가 다양.Jenkins에 비해 문서가 적음.Jenkins에 비해 문서가 적음.
REST APIREST API 지원.Github API 지원.REST API 지원.
공유성공유할 수 없음.Github 마켓 플레이스에서 Workflow 공유 가능.공유할 수 없음.
장점자동화 테스트 수행.정적 코드 분석에 의한 코딩 규약 준수여부 체크.프로젝트 표준 컴파일 환경에서의 컴파일 오류 검출.프로파일링 툴을 이용한 소스 변경에 따른 성능 변화 감시.빌드 파이프라인의 구성을 간단히 할 수 있음.각종 배치 작업의 간략화.Github 마켓 플레이스를 통한 Workflow 복제가 용이.Github에 친숙한 개발자들에게 접근성이 좋음.실행 및 디버깅이 쉬움.Github API를 통해 쉽게 액세스 가능.서버를 직접 관리하지 않아도 되며, Github 페이지에서 모든 과정을 확인 가능.Auto-Scaling CI Runner를 제공.다른 Tool에 비해 UI가 깔끔. 모바일 Web, App으로도 사용 가능.오픈 소스 그룹이 활발해서 주기적인 업데이트가 있음.파이프라인 내의 모든 Job들이 독립적.
단점프로젝트의 규모가 작은 경우, 설정하는데 리소스 낭비가 발생.호스팅을 직접해야하기 때문에 서버 운영 및 관리 비용 발생.플러그인을 최신 상태로 유지해야하며 업데이트 하지 않을 경우 장애가 발생 할 수 있음.Public Repository에서는 무료로 사용 가능하지만, Private Repository에서는 요금이 발생.참고할만한 문서가 비교적 부족.Workflow에서 단일 작업만 다시 실행할 수 없음.Push, Pull 수행 속도가 Github보다 느림.모든 job에 대해 artifact를 정의 및 업로드/다운로드 해야함.
총평새로 생긴 CI툴에 비해 초기 설정이 어렵다는 단점이 있지만, 많은 플러그인과 비용이 무료라는 이점들이 있기에 대규모 프로젝트를 운영함에 있어서 적합하다.최신 CI 툴이며 Github에서 사용해 친숙하며, 별도의 설치 없이 클라우드에서 관리를 하기 때문에 편리하다는 장점이 있지만, IIS 서버를기반으로 한 CD가 불가능 하다는 단점이 있다.Github에서 기존에 제공하던 형상관리 기능과 더불어CI 기능까지 제공하지만, GitLab과 관련된 참고문서가 적고 기존 Repository를 옮겨야 한다는 단점이 있다.
요금정책별도의 서버 유지 비용을 제외하면 무료.사용 환경, 용량, 사용 시간에 따라 요금이 상이하다.기본 400분 사용 가능하고 유료 이용 시 1000분 사용 가능하다. 또한 사용자 별 월단위 결제 등의 방법도 가능하다.

결론

  • CI는 개발 과정에서 지속적이고 빠른 주기로 코드 업로드를 하고 자동화된 테스트와 빌드 과정을 거쳐 배포 이전까지의 단계를 빠르게 하기 위한 방법이다.
  • CD는 이런 CI와 함께 하여 빌드된 프로젝트를 자동화된 배포를 이용하여 지속적인 개발 및 빌드의 전달과 이런 빌드의 배포를 포괄하는 소프트웨어 개발 방법이다.
profile
프로그래밍을 잘하고 싶어요..

0개의 댓글