안녕하세요. 오픈소스컨설팅 Playce Cloud팀 임기환입니다. AA/DevOps 관련 업무를 담당하고 있으며 Application Architect를 넘어서 ‘All’ Architect를 꿈꾸고 있습니다.

이번 포스팅에서는, IT 개발자라면 누구나 한번을 들어봤을 CI/CD에 대해 설명하려고 합니다.

본 글을 다 이해하게 되면 아키텍처를 기준으로 CI/CD에 대해 이해할 수 있으며, 지속적인 빌드/배포가 가능한 파이프라인 사이클을 만들어 개발 생산성을 높일 수 있을 것입니다.

그러면 먼저 CI/CD란 무엇인가에 대해 설명하도록 할게요.


CI/CD가 의미하는것

IT 서비스를 만든다는 것은 궁극적으로 사용자에게 우리가 잘 만든 코드를 결과물로 만들어 보여주는 것입니다.
결과물을 잘 만들어서 고객에게 제공했다고 하더라도, 고객이 필요로 하는 내용이 빠져있거나, 버그 등으로 문제가 발생하는 경우가 빈번하게 발생합니다. 이러한 경우 빠르게 오류를 수정하거나 기능을 추가하여 다시 사용자에게 제공하기 위해 코드를 수정하고 수정된 코드가 제대로 작동하는 지 테스트 과정을 거치는데, 이 과정은 시간도 많이 걸리고 실수를 할 수도 있으며 상당히 반복적인 작업입니다.

이러한 작업을 자동화하여 실수를 줄이고 신속하게 처리할 수 있는 제공하는 방법이 CI/CD 입니다.

개념적으로 본다면, CI/CD (Continuous Integration/Continuous Delivery or Deployment)는 애플리케이션 개발 단계를 자동화하여 애플리케이션을 더욱 짧은 주기로 고객에게 제공하는 방법론입니다. 기본 개념은 지속적인 통합, 지속적인 서비스 제공, 지속적인 배포입니다.

  • 지속적 통합(Continuous Integration, CI): 자동화 프로세스를 통한 지속적인 통합을 의미합니다. 애플리케이션 코드의 새로운 변경 사항이 정기적으로 빌드 및 테스트를 거쳐 공유 리포지토리에 병합합니다. 공유 리포지토리를 사용할 경우, 여러 명의 개발자가 작업할 경우 발생하는 소스 코드 충돌 문제를 해결이 가능합니다.
  • 지속적 제공(Continuous Delivery, CD): 변경 사항을 버그 테스트를 거쳐 리포지토리에 자동으로 업로드하는 것을 의미합니다. 코드 변경 사항 병합부터 프로덕션에 적합한 빌드 제공에 이르는 모든 단계에는 테스트 자동화와 코드 릴리스 자동화가 포함되어야 하며, 이 프로세스를 완료하면 운영팀이 더욱 빠르고 손쉽게 애플리케이션을 프로덕션으로 배포할 수 있습니다.
  • 지속적 배포(Continuous Deployment, CD): 리포지토리에서 고객이 사용 가능한 프로덕션 환경까지 자동으로 릴리스하는 것을 의미합니다. 지속적 배포 환경이 구성되면, 수동 배포로 인한 프로세스를 줄이며, 개발자와 운영자가 간의 가시성 및 의사 전달에 도움이 됩니다. 실제 사례에서 지속적 배포란 개발자가 애플리케이션에 변경 사항을 작성한 후 몇 분 이내에 클라우드 애플리케이션을 자동으로 실행할 수 있습니다.

CI/CD의 목표

앞서 말씀드린 대로, 일반적인 서비스의 목표는 개발된 소스 코드를 사용자가 사용할 수 있도록 배포하는 것입니다.
조금 더 자세히 이야기하자면, 개발자가 신규 기능이나 변경 내용에 대해 소스 코드를 수정하고 형상관리 시스템(gitlab, github 등)에 소스 코드를 기록하는 것부터 업무가 시작됩니다. 그 이후 소스 코드 리뷰 및 테스트를 거치게 되며, 문제가 없다면 주어진 환경에 맞게 바이너리 또는 이미지 등의 형태로 배포하게 됩니다.

이런 작업은 수많은 사람들이 밀접하게 연계되어 있으며, 매끄럽고 원활하게 동작하려면 많은 노력이 필요하며, 버그 및 기능 개선 등으로 빈번히 발생합니다.

만약 이 과정을 한 개인이 수동으로 진행한다면 많은 문제가 발생할 수 있습니다. 그래서 작업 시간을 줄이고 불편함을 최소화하기 위해 관련된 업무 프로세스를 도출하여 자동화하는 업무를 수행합니다. 이런 업무와 프로세스는 서비스가 발전하면서 발생하는 변화를 끊임없이 따라가며 지속적으로 개선해 나가는 것이 제일 중요합니다.

CI/CD와 DevOps 관계

우리가 CI/CD를 얘기하다 보면 DevOps를 많이 이야기하는데요. CI/CD와 DevOps와 같은 개념으로 생각하기 쉬운데, 같으면서도 다른 개념입니다. DevOps와 CI/CD 관계에 대해 설명하려고 합니다.

DevOps란

DevOps는 개발(Development)와 운영(Operation)을 결합해 탄생한 개발 방법론입니다.
시스템 개발자와 운영을 담당하는 정보기술 전문가 사이의 소통, 협업, 통합 및 자동화를 강조하는 소프트웨어 방법론입니다.

출처: https://www.atlassian.com/devops

DevOps에서의 CI/CD

DevOps는 개발(Develop)과 운영(Operation)의 합성어로 애플리케이션과 서비스를 빠른 속도로 제공할 수 있도록 하는 문화, 프로세스 도구의 조합입니다.
DevOps에서의 CI/CD는 기술, 프로세스적인 부분을 의미합니다.

DevOps의 요소

DevOps에서는 CI/CD를 통한 프로세스적인 내용과 msa, IasC 등의 기술적, 커뮤니케이션의 소통의 요소를 가집니다.

  • 지속적 통합
  • 지속적 전달
  • 마이크로 서비스
  • 코드형 인프라
  • 모니터링 및 로깅
  • 커뮤티케이션 및 통합

DevOps 요소의 상세 내용은 https://aws.amazon.com/ko/devops/what-is-devops/ 을 참고하여 자세하게 알 수 있습니다.

CI/CD 프로세스

컨테이너(쿠버네티스) 환경에 맞는 자동화된 CI/CD 프로세스에 대해 알아보겠습니다.

배포 환경의 변화

프로세스를 알아보기 전에 어플리케이션 배포 환경이 어떻게 변화하고 발전했는지 알아보겠습니다.

배포 방식에 따른 시스템 구조에 대한 차이를 아래 그림으로 표현할 수 있습니다.

출처: https://kubernetes.io/docs/concepts/overview

전통적인 배포 시대: 초기 조직은 애플리케이션을 물리 서버에서 실행했었습니다. 한 물리 서버에서 여러 애플리케이션의 리소스 한계를 정의할 방법이 없었기에, 리소스 할당의 문제가 발생했습니다. 예를 들어 물리 서버 하나에서 여러 애플리케이션을 실행하면, 리소스 전부를 차지하는 애플리케이션 인스턴스가 있을 수 있고, 결과적으로는 다른 애플리케이션의 성능이 저하될 수 있었습니다. 이에 대한 해결책으로 서로 다른 여러 물리 서버에서 각 애플리케이션을 실행하였습니다. 그러나 이는 리소스가 충분히 활용되지 않는다는 점에서 확장 가능하지 않았으며, 조직이 많은 물리 서버를 유지하는 데에 높은 비용이 들었습니다.

가상화된 배포 시대: 그 해결책으로 가상화가 도입되었습니다. 이는 단일 물리 서버의 CPU에서 여러 가상 시스템(VM)을 실행할 수 있게 합니다. 가상화를 사용하면 VM 간에 애플리케이션을 격리하고 애플리케이션의 정보를 다른 애플리케이션에서 자유롭게 액세스할 수 없으므로, 일정 수준의 보안성을 제공할 수 있습니다.
가상화를 사용하면 물리 서버에서 리소스를 보다 효율적으로 활용할 수 있으며, 쉽게 애플리케이션을 추가하거나 업데이트할 수 있고 하드웨어 비용을 절감할 수 있어 더 나은 확장성을 제공합니다. 가상화를 통해 일련의 물리 리소스를 폐기 가능한(disposable) 가상 머신으로 구성된 클러스터로 만들 수 있습니다.
각 VM은 가상화된 하드웨어 상에서 자체 운영체제를 포함한 모든 구성 요소를 실행하는 하나의 완전한 머신입니다.

컨테이너 개발 시대: 컨테이너는 VM과 유사하지만 격리 속성을 완화하여 애플리케이션 간에 운영체제(OS)를 공유합니다. 그러므로 컨테이너는 가볍다고 여겨집니다. VM과 마찬가지로 컨테이너에는 자체 파일 시스템, CPU 점유율, 메모리, 프로세스 공간 등이 있습니다. 기본 인프라와의 종속성을 끊었기 때문에, 클라우드나 OS 배포본에 모두 이식할 수 있는 장점이 있습니다.

간략하게 표로 비교하면 아래와 같이 표현할 수 있습니다.

시대정의장점단점
전통적인 배포 시대물리적인 서버에 애플리케이션을 직접 배포
간단하고 직관적인 접근 방식
리소스 활용도 낮음, 확장성 및 유지보수 어려움

가상화 배포 시대가상화 기술을 사용하여 물리적 서버를 가상 머신으로 분할하여 애플리케이션 배포
리소스 활용도가 높아지고, 환경 구성의 일관성 유지 쉬움
OS 레벨에서의 오버헤드, 가상화 환경 관리를 위한 추가 리소스 필요

컨테이너 개발 시대컨테이너 기술을 사용하여 애플리케이션과 그 종속성을 컨테이너에 패키징하여 배포
가벼움, 시작 시간이 빠름, 환경 구성의 일관성 보장
보안과 네트워킹 관리 복잡, 컨테이너 오케스트레이션 관리를 위한 새로운 기술 필요

CI/CD 배포 프로세스

컨테이너 배포 환경으로 발전하면서 반복적이고 빈번한 배포가 일어났습니다. 이를 해소하기 위해 자동화된 CI/CD 배포를 도입하여 휴먼 에러를 줄이고 어플리케이션 배포에 용이하게 되었습니다.
그러면 일반적인 배포와 CI/CD 가 도입된 프로세스에 대한 프로세스 차이에 대해서 알아볼게요.

일반적인 배포 프로세스

  1. 개발자들이 개발하여 코드를 수정
  2. 각자의 feature 브랜치에 코드를 push
  3. 각자의 코드를 git에 올리고 통합(Intergration)
  4. 에러가 발생했지만 어느 부분에서 에러가 났는지 모르므로 다시 어느 부분에 에러가 있는지 디버깅하고 코드를 수정
  5. (1) ~ (4)의 과정을 반복
  6. 많은 시간을 할애하여 에러가 해결되었으면 배포를 시작( 개발자가 직접 배포하므로 많은 시간이 소요)
출처: https://www.geeksforgeeks.org/ci-cd-continuous-integration-and-continuous-delivery

CI/CD 자동화가 도입된 프로세스

  1. 개발자들이 개발하여 코드를 수정
  2. 각자의 feature 브랜치에 코드를 push
  3. CI서버( Jenkins, Tekton 등)에서 push 명령을 트리거링하여 자동으로 빌드, 테스트 등을 실행
  4. 에러가 발생하였다면 개발자에게 결과를 전송하여 오류를 수정
  5. 빌드, 테스트가 정상적으로 수행되었다면 CD서버가 자동으로 배포를 수행
출처: https://www.geeksforgeeks.org/ci-cd-continuous-integration-and-continuous-delivery

컨테이너 환경에서의 배포 프로세스

컨테이너 환경에서는 빌드 된 어플리케이션을 구동할 수 있는 컨테이너 이미지를 생성하고 이미지 레지스트리에 추가하는 과정이 추가됩니다.

위에서 설명한 내용을 아래 표를 보면 기존 방식과 컨테이너 환경에서의 배포 방식의 차이를 좀 더 자세히 알 수 있습니다.

항목기존 배포CI/CD 배포
자동화 여부전담 인력에 의한 수작업CI 도구를 이요한 자동 빌드 및 자동 배포
패키징배포 담당자가 수작업으로 취합하여 정리형상관리를 통한 자동 취합
배포 시간수 십분 소요수 분 수요
무중단 배포배포 담당자에 의한 수작업에 의한 무중단 배포자동화된 무중단 배포
롤백일부 파일 및 반 자동화 된 롤백기존 운영 버전으로 롤백
휴먼 에러발생 가능성 있음없음
배포 검증자동화 불가테스트 케이스, 정적분석 등 다양한 기술을 배포 단계에 적용 가능

CI/CD 환경

CI/CD를 구성할 때 사용성을 높이기 위해 몇 가지 적용하는 정책 및 환경에 대해 알아보겠습니다.

형상관리 및 브랜치 전략

형상관리란 소스코드 변경에 대한 모든 관리를 말합니다. 형상관리 전략이란 그 변경을 추적하고 처리하는 메커니즘을 체계적으로 관리하기 위한 전략을 의미하며, 여러 가지 방식들의 브랜치 전략에 대해 정의해 보겠습니다.

브랜치 전략

대규모 개발 환경에서의 개발 또는 배포시 아래와 같은 질문을 자주 받을 수 있습니다.

  • 최신 브랜치는?
  • 어떤 브랜치를 이용하여 개발하여야 하나?
  • 배포는 어떤 브랜치로?
  • 핫픽스 사용 시 베이스가 되는 브랜치는?

위의 내용을 해소하기 위해 브랜치 전략을 도입 합니다.

Git-Flow

아래 그림은 Git을 이용하여 작업 시 브랜치 전략을 도입한 예시 입니다.

  • master – 가장 core가 되는 브랜치 중 하나로 패키징 용 브랜치이며 모든 변경사항이 결국은 master로 머지 되어야함
  • dev – 패키징 할 준비가 된 가장 안정적인 브랜치로 master 브랜치로 머지 하기 전 개발된 모든 feature들이 dev에 머지 됨
  • release – dev 브랜치에 어느 정도 feature 들을 머지하고, 패키징 시점에 생성하는 브랜치로 dev 브랜치로부터 생성 (통합테스트 용)
  • feature – 새로운 기능이 추가되어야 할 때 사용되는 브랜치로 dev 브랜치로부터 생성이 되며, 개발이 완료된 후 dev 브랜치로 머지
  • hotfix – 패키징 된 버전에서 발생한 버그같은 것을 수정해야 할 때 생성되는 브랜치로 수정이 완료된 후 master와 dev 브랜치에 머지
  • bugfix – feature 브랜치가 dev로 머지된 후 해당 기능에 버그가 발생한 경우 또는 release 브랜치에 대한 통합테스트 시 버그가 발생된 경우 생성되는 브랜치로 개발 완료 후 dev, release에 머지

브랜치 사용 방법

브랜치를 이용한 개발 순서는

  1. master 브랜치 생성 (프로젝트 생성)
  2. dev 브랜치 생성 (master pull)
  3. feature 브랜치 Jira 이슈로 생성 (dev pull)
  4. 개발 진행
  5. dev merge (feature PR)
  6. release 브랜치 버전 명시 생성 (dev PR)
  7. master 업데이트 (release PR)

로 진행하며 아래 사항을 주의하여 개발을 진행합니다.

  • master, dev 브랜치는 항상 1개만 존재
  • release 브랜치는 버전별로 존재
  • 릴리즈가 빈번히 발생하여 브랜치가 많아질 경우 삭제 주기를 설정이 필요
    예) 최신 5개의 버전을 제외한 브런치는 삭제
  • master, dev, release 브랜치는 직접 commit하지 않고, 반드시 Pull Request를 통해 Merge
  • 소스코드 commit 전에 반드시 pull로 변경사항을 확인하여, 소스코드가 유실되는 현상을 해소

Git-Ops

Git-Ops란, 이름에서 나타나듯 애플리케이션의 배포와 운영에 관련된 모든 요소를 코드화하여 깃(Git)에서 관리(Ops) 하는 것을 의미합니다. 기본 개념은 코드를 이용하여 인프라를 프로비저닝 하고 관리하는 IaC(Infrastructure as Code)에서 나온 것으로 Git-Ops는 이를 인프라에서 전체 애플리케이션 범위로 확장하여 사용합니다.

형상 관리 도구인 ‘Git’을 통해 개발자에게 익숙한 방식으로 인프라 또는 애플리케이션의 선언적인 설정 파일을 관리하고 배포합니다.

CI/CD 프로세스는 CD 영역을 담당하며, ArgoCD와 연동하여 사용하며 아래 그림과 같은 워크플로우를 가집니다.

출처: https://www.gspann.com/resources/blogs/continuous-delivery-for-kubernetes-with-gitops-and-argo-cd

GitOps를 사용할 경우 아래와 같은 장점을 가집니다.

  • 신뢰할 수 있는 정보의 공유
    • 서비스의 설정값, 배포 정보에 대해 직접 서버를 접근할 필요 없이 확인이 가능
    • 이력 관리를 통해 이전 배포 환경에 대한 정보를 알 수 있어 에러 복구 시간이 감소
  • 익숙한 절차
    • 개발자에게 익숙한 git 명령어를 그대로 적용

지금까지는 CI/CD가 무엇이며, 어떻게 발전해 왔고, 일반적인 배포 방식과 차이에 대해 알아봤는데요.
실제 CI/CD가 어떻게 구성되는지를 알아보도록 할게요.

CI/CD 구성도

파이프라인이란

Pipeline의 사전적 의미는 ‘석유, 천연가스 등 유체의 수송을 위해 만든 관로’입니다.
컴퓨팅 기술에서 Pipeline은 프로세서에서 성능을 높이기 위해서 명령어 처리 과정으로 명령어 처리를 여러 단계로 나누어 단계별로 동시에 수행하여 병렬화를 시키는 것을 말합니다.

CI/CD에서 말하는 Pipeline은 애플리케이션을 만들고 배포함에 있어 일련의 과정들의 관로처럼 나열하여 순차적으로 실행하는 것을 의미합니다.

파이프라인 구성도

일반적인 파이프라인은 아래 그림과 같은 구성을 가집니다.

CI/CD 프로세스에서 언급했던 GitOps를 포함하여, 소스코드를 빌드 하여 어플리케이션을 배포하며, 슬랙 등으로 알람을 받을 수도 있습니다.

파이프라인 구성에는 정답이 없으며, 프로젝트 상황에 맞는 모델을 적용하고 지속적으로 발전해 나가는 것이 중요합니다.

컨테이너 기반 CI/CD 구성요소

CI/CD를 구성함에 있어, CNCF에서 검증된 SW Stack 중에 가볍고, 사용성이 많은 요소를 선정하여 최적화된 파이프라인을 제공합니다. ( CNCF Landscape )

CI/CD SW Stack을 구성함에 있어 어떤 툴을 사용하며 선정 이유에 대해 표로 작성한 내용입니다.

분류SW선정 이유
형상관리Gitea가볍고 필요한 git 서버 기능은 모두 지원
빌드 라이브러리 관리Nexus성능 및 가용성이 높으며 많은 사용자 보유
Code InspectionSonarqube다양한 프로그래밍 언어의 정적 코드 검사 및 DevOps 연동 지원
도커 레지스트리Harbor제품은 조금 무겁지만 플러그인으로 UI 및 helm chart 지원 이미지 보안 검사 기능을 지원
배포 툴ArgoCD클라우드 베이스의 배포 지원 및 다양한 배포방식(Rollout, Blue/Green, Canary) 및 플러그인 지원
빌드 파이프라인JenkinsKubernetes 자원을 기반으로 구축되어 자원 확장 및 구성/관리가 용이
Tekton범용적으로 많이 사용하는 제품으로 많은 플러그인과 파이프라인 예제가 있음

CI/CD 파이프라인 구성

파이프라인은 컨네이너 환경에 배포하는 것을 기준으로 구성합니다.
위에서 정의한 프로세스, SW Stack을 조합하여 아래와 같이 구성할 수 있습니다.

  1. 개발자가 Gitea에 소스 commit 및 push
  2. 형상관리에서 Jenkins 로 자동으로 Webhook 전송
  3. Jenkins에서 발생한 Trigger에 맞춰 파이프라인을 실행
    1. Gitea에서 소스코드 Clone
    2. 소스코드 빌드
    3. 컨테이너 배포를 위한 이미지 빌드
    4. 도커 레지스트리에 이미지 Push
    5. 배포한 이미지에 대한 정보를 git-ops에 반영
    6. ArgoCD로 배포 명령 전송
    7. git-ops에 설정한 값으로 쿠버네티스에 배포
  4. 배포 결과를 슬랙으로 전송

위의 과정은 개발자가 형상관리에 소스를 push 함과 동시에 배포까지 자동으로 실행되는 프로세스입니다.

마치며…

지금까지 CI/CD 아키텍처에 대해 알아보았습니다.

앞서 말씀드린 대로, CI/CD를 도입하고 구성함에 있어 정답은 없으며, 우리에게 얼마나 잘 맞게 구성하느냐가 중요합니다.

CI/CD 초기 도입 시에 많은 개발자분들이 왜? 굳이?라는 의문을 가질 수 있습니다. 현재 시스템도 잘 쓰고 있고 배포가 잘 이루어지는데 도입 공수에 비해 필요가 없다고 느낄 수 있지만, CI/CD는 선택이 아니라 필수입니다.

본 포스팅으로 CI/CD에 대한 이해가 완료되면, 실제 파이프라인을 구성해 볼 수 있는데요.
저희 블로그에 관련된 자료가 있으니 참고해 보시면 좋습니다.

오픈소스컨설팅 Playce Cloud 팀에서 근무하고 있는 임기환입니다. All Architect를 목표로 달려갑니다.

Leave a Reply

Your email address will not be published. Required fields are marked *