DevOps/CI & CD

지속적인 통합(Continuous-Integration) & 지속적인 배포(Continuous-Deploy) 적용하기 - 1편(CI란 무엇인가?)

Hooligans 2020. 12. 3. 01:25

개요

 최근 프로젝트 완성이 얼마 남지 않아 배포에 관하여 검색하면서 CI/CD라는 단어를 만나게 되었습니다. 이전에 배포 경험이 아예 없었던 건 아니지만, CI/CD라는 개념을 통해 놀라울 정도로 편해진 배포 경험을 나누고자 포스팅을 하려고 합니다.

 

 그럼 CI부터 CD까지 차례대로 알아보겠습니다.

 

CI가 무엇일까요?

 CI란 지속적인 통합(Continuous Integration)을 의미합니다. CI를 알기 위해서 단어 하나하나 차례대로 알아봅시다. 먼저 통합(Integration)은 개발 과정에서 어떤 행위를 의미할까요?

 

 요즘 대부분의 개발자는 소스코드가 담긴 레포지토리를 Git을 통해 버전 관리를 하며, 더 나아가 GitHub이나 GitLab과 같은 클라우드 원격 저장소에서 관리하고 있습니다. 이러한 원격 저장소는 개인 프로젝트도 유용하게 사용할 수 있으나, 여러 대형 프로젝트 혹은 팀 단위 프로젝트에서 더 큰 힘을 발휘합니다.

 

출처: https://github.com/logos, https://www.flaticon.com/kr/authors/eucalyp

 위 그림에서 알 수 있듯이 우리는 원격 저장소에 공용 레포지토리를 생성하고, 이를 로컬로 Pull 하여 개발을 진행합니다. 개발이 완료되거나, 저장이 필요할 때, Commit을 하고 Push를 하게 되면 원격 저장소로 버전이 저장되게 됩니다.

 

 즉, 공용 레포지토리에 개인이 개발한 내용이 담긴 브랜치를 저장할 수 있습니다. 이렇게 개발을 한다면 하나의 프로젝트를 여러 사람이 병렬적으로 개발할 수 있으니 효율적으로 개발할 수 있겠죠?

 

 그러나 개인이 작업하는 정도에 따라 소스코드의 변화가 생기게 되고, 동시에 여러 사람이 작업한 내용을 병합하려면 그만큼 문제가 발생할 확률도 높아집니다.

 

 그러므로 이러한 환경에서 개인이 작업한 내용이 신뢰성을 가질 수 있도록 단위 테스트, 빌드 등 부가적인 작업들을 추가해야만 합니다. 이를 '퀄리티 컨트롤' 혹은 '품질 관리'라는 단어로 쓰기도 합니다. 

 

 위의 작업을 마치게 되면 브랜치를 관리하는 전략에 따라 Push 한 브랜치에 대해서 코드 리뷰를 받은 후에 Approve가 되면 master와 같은 중앙 브랜치로 병합(merge)을 할 수 있는데, 여기까지 과정을 통합(Integration)이라고 부릅니다.

 

 다시 말해서 통합은 개인이 작업한 코드를 공용 작업 환경에 올리고 병합하는 과정을 의미합니다. 아래 그림을 참고하면 전반적인 통합과정에 대해 이해할 수 있습니다.

 

출처: https://git-scm.com/downloads/logos, https://maven.apache.org/, https://junit.org/junit5/

 

 그렇다면 지속적인 통합은 어떤 의미일까요?


 지속적이라는 의미는 고전적인 통합 방식과 비교하면 쉽게 이해할 수 있습니다.

 

 고전적인 통합 방식의 경우, 개발자들이 각자 개발한 소스코드를 위와 같이 퀄리티 컨트롤을 거치지 않고 커밋을 하고, 대부분의 기능 개발이 끝나게 되는 마지막에 통합을 하고 테스트를 진행하는 방식을 의미합니다.

 

 이러한 방식은 커밋을 하는 중간에 별도의 퀄리티 컨트롤을 거치지 않기 때문에 버그 및 장애를 일으키는 이슈들이 쌓이게 되고, 설상가상으로 통합을 하는 시점에 모두 해결해야 합니다.

 

 당장 만든 소스코드의 버그를 찾는데도 긴 시간이 소요되는데 이렇게 쌓인 이슈들을 찾아내려면 훨씬 더 어렵겠죠?

 

 이를 해결하기 위해서 통합을 짧은 주기로 자주! 즉, 지속적으로 하게 되면 이러한 문제 요소들을 조기 식별할 수 있으며, 공용 레포지토리에는 신뢰성 있는 소스코드들만 남길 수 있게 되므로 소프트웨어의 품질과 생산성이 향상할 수 있습니다.

 

 지금까지 CI란 무엇인지 알아보았습니다! 그럼 CI를 적용하기 위해서 무엇이 필요한지 알아볼까요?

 

CI에는 무엇이 필요할까요?

 첫 번째는 바로 '버전 관리 도구'입니다.

 

출처: https://git-scm.com/downloads/logos

 

 익숙한 로고가 보이죠? 맞습니다! CI에는 git과 같은 버전 관리 도구가 필요합니다. 이유는 버전 관리 도구가 소스코드의 수정과 백업을 자동화할 수 있고, 여러 명이 공동으로 개발한 내용을 동기화할 수 있도록 도와주기 때문입니다. 

 

 즉, 버전 관리 시스템에서 관리되지 않는 소스코드는 개발 단계에서부터 자동화되지 않기 때문에 개발의 생산성을 떨어뜨리게 되고, 이러한 상황에서 CI를 적용하는 것은 무의미한 일이 됩니다.

 

 그러므로 버전 관리 도구는 CI의 가장 중요한 요소 중 하나로, git 이외에도 Subversion, Mercurial 등 다양한 버전 관리 도구를 필요에 따라 사용하실 수 있습니다.

 

 두 번째는 CI 과정 전반을 관리하는 'CI 도구'가 필요합니다.

 

 CI 도구를 사용하면 스크립트 실행을 통해 다양한 작업을 할 수 있습니다. 예를 들어, 버전 관리 시스템에서 소스코드를 주기적으로 폴링 하고, 테스트를 실행하거나, 빌드를 하는 등 python, groovy, shell과 같은 스크립트 언어를 사용하여 CI 과정을 통제할 수 있습니다.

 

출처: https://www.jenkins.io/artwork/

 CI 도구의 종류에는 Jenkins, Team City, Travis CI, Circle CI 등 많은 툴이 존재합니다. 이번 프로젝트의 CI 도구는 Jenkins를 활용하였고, 선정 이유와 CI 도구를 설정하는 방법의 경우, 차례차례 포스팅하도록 하겠습니다.

 

 세 번째로 '빌드 자동화 도구'가 필요합니다.

 

 빌드는 소스코드를 컴파일하고, 오브젝트 파일을 생성하여 링킹 작업을 통해 jar 혹은 war와 같은 라이브러리 파일로 만드는 것을 의미합니다. 글로 봐도 복잡해 보이지 않나요? 이를 자동화하면 생산성이 더 높아지겠죠?

 

출처: https://maven.apache.org/

 이러한 작업을 가능하게 해주는 도구가 많이 알고 계시는 Maven, Gradle, ANT 등의 빌드 툴입니다.

 

 CI에서 빌드 자동화 개념은 하나 더 추가되는데, 이는 버전 관리 시스템에 수정사항이 생기면 주기적으로 혹은 변화가 생긴 시점에 빌드를 다시 함으로써 컴파일 오류나 빌드 오류 등을 발견하여 신뢰성 있는 소스코드를 유지하도록 해야 합니다.

 

 마지막으로 '테스트 자동화 도구'가 필요합니다.

 

출처: https://junit.org/junit5/

 빌드 자동화를 통해 컴파일, 빌드 중 발생하는 오류를 예방하였다면 단위 테스트를 통해서 개발자가 의도하는 방향으로 기능이 수행되는지 검증할 수 있어야 합니다. 이를 도와주는 도구가 java 언어를 위한 JUnit, python의 Selenium 등이 있습니다.

 

 이외에도 정적 분석 툴, 코드 커버리지 분석 툴과 같은 퀄리티 컨트롤을 위한 도구들은 많이 있지만, 위의 4가지 도구들은 그중 CI에서 가장 기본이 되는 요구사항들이라고 생각하여 소개하였습니다.

 

 지금까지 CI에 대해서 알아보았습니다. 그렇다면 가장 중요한 내용인 CI가 왜 필요한지에 대해서 알아보도록 하겠습니다.

 

CI를 적용하면 어떤 점이 좋을까요?

 위에서 글을 읽어보셨다면 이미 CI가 어떤 장점을 제공하는지는 아실 수 있을 것이라고 생각합니다. 제 글이 두서없이 정리되어 이해가 어려우실 수 있기 때문에 지금부터 장점만 따로 정리하여 알아보겠습니다.

 

 우선, 지속적인 통합을 한다는 점에서 한 번에 많은 통합 과정을 진행하던 과거에 비해 훨씬 소스코드 병합이 쉬워지고, 병합 과정에서 이슈를 빠르게 발견할 수 있다는 점이 큰 장점입니다. 이를 통해 소스코드의 높은 퀄리티를 유지할 수 있습니다.

 

 또한 커밋만 하면 위의 통합 과정이 자동으로 실행되기 때문에 개발자들이 개발에만 신경 쓸 수 있는 환경을 구성할 수 있어서 개발의 생산성을 높일 수 있다는 장점이 있습니다.

 

결론

  1. 통합은 개인이 작업한 코드를 공용 작업 환경에 올리고 병합하는 과정을 의미합니다.
  2. 통합을 지속적으로 하게 되면 작업의 단위가 작아져서 병합이 쉬워지고, 이슈를 조기 식별하여 해결할 수 있으므로 소스코드의 퀄리티와 개발자의 생산성이 향상할 수 있습니다.
  3. CI에는 버전 관리 도구, CI 도구, 빌드 자동화 도구, 테스트 자동화 도구 등이 필요합니다.

참고

  • 초보를 위한 젠킨스 2 활용 가이드 2/e, 니킬 파타니아 지음, 이상욱 옮김, 에이콘 출판사
  • 지속적인 통합(CI: Continuous Integration), happystory.tistory.com/89

 

프로젝트 참고

 

f-lab-edu/sns-agora

Contribute to f-lab-edu/sns-agora development by creating an account on GitHub.

github.com

 

다음 포스팅에는

 최근 포스팅이 뜸했네요ㅠ 다시 마음잡고 열심히 포스팅 해봐야겠습니다. 이번 시간에 CI 개념에 대해 알아보았으니 다음 포스팅에는 CD에 대해서 알아보겠습니다!