서론
상용 IT서비스를 개발하기 위해서는 코드의 품질, 비즈니스적인 면도 중요하지만, 운영또한 매우 중요한 요소입니다.
토이프로젝트로 끝날 프로젝트라면 infra 관련한 부분에 힘을 덜 주어도 되겠지만, 24시간 상용 서비스를 만들어야 하는 저의 경우에는 지속적인 운영, 실시간 트러블 슈팅을 위해 도커와 Github Action을 적용한 CI / CD를 도입하도록 하였습니다.
오늘은 여기서 이 CI / CD란 무엇인지 짚고 넘어가도록하겠습니다.
CI (Continuous Integration)
CI는 영문 단어 자체를 직역해보자면, '지속적인 통합'이라는 의미를 갖고있습니다.
여기서 지속적인 통합은, 개발자 단에서 애플리케이션의 코드 수정이나 추가적인 기능이 구현되었을 경우 새로운 변경 사항들이 정기적으로 빌드 및 테스트 절차를 걸쳐 공유 레포지토리에 통합되는 것을 의미합니다.
이러한 CI는 주로 다수의 사람들 간 협업하는 환경에 사용됩니다.
예를들자면, Git과 같은 형상관리 툴을 통해 여러 개발자 간 협업을 해야하는 상황에서
지속적으로 서비스를 운영해나가야 하는 애플리케이션 특성 상, 기능 추가마다 공유 레포지토리 (main, dev branch)에 버전을 업데이트 합니다.
이 때, 공유 레포지토리에는 수많은 버전이 쌓이게되는데, 이 버전들이 쌓일 때 마다 테스트를하고 Merge를 하기엔 리소스 낭비가 심할것입니다.
이 때마다 빌드와 테스트를 자동화 해주는 역할을 하는것이 바로 이 'CI'라고 할 수 있습니다.
CI의 이점
- 조기에 더 효과적으로 오류 탐지 가능 -> 체크인 후 몇 분 이내에 오류 해결이 가능
- 상시 진행 상황을 확인하며 더 유익한 피드백 적용 가능
- 팀 협업 증진 -> 모든 팀원이 코드를 변경, 시스템을 통합하여 소프트웨어의 다른 영역과의 충돌을 신속히 해결 가능
- 더 효과적으로 시스템 통합 -> 소프트웨어 개발 라이프사이클의 말기에 뜻밖의 상황이 벌어질 가능성 최소화 (개발 단계에서의 주기적 통합으로 인함)
- 병합 및 테스트에서 동시 변경의 필요성 감소
- 시스템 테스트 과정에서의 오류 건수 감소
- 상시 업데이트 된 시스템을 대상으로 테스트 가능
- 애자일 환경에 특화 (작은 그룹의 작업 또는 스프린트로 구성을 하는 특성에 의함)
Open Source CI Tools
- Jenkins : 가장 범용적으로 사용되는 툴로, 소스 저장소에 commit하는 즉시 코드를 자동으로 빌드, 통합, 테스트 가능. Docker plugin을 Jenkins에서 사용 가능.
- Buildbot : 작업 스케줄링 시스템인 Buildbot은 작업을 큐에 지정하고 실행하며 결과를 보고.
- Go : Go의 차별화 요소는 파이프라인의 개념. 이 덕분에 복잡한 빌드 워크플로우 모델링을 손쉽게 해결 가능.
- Travis CI : 가장 오래되었고, 신뢰받는 호스팅 솔루션 중 하나로, 기업용 온프레미스 버전으로도 제공 됨.
- GitLab CI : Open source Rails 프로젝트의 핵심 요소인 GitLab CI는 무료 호스팅 서비스로, 세부적 git 저장소 관리 기능과 함계 액세스 제어, 이슈 트래킹, 코드 리뷰 등의 기능 제공.
성공적인 CI란?
- 개발자가 애플리케이션에 적용한 변경 사항들이 병합(Merge)된 후 이러한 변경 사항이 애플리케이션을 손상시키지 않도록 자동으로 애플리케이션을 빌드하고, 다양한 수준의 자동화 된 테스트 (단위테스트, 통합 테스트)를 실행하여 해당 변경 사항을 검증하는 것.
즉, 클래스와 기능에서부터 전체 애플리케이션을 구성하는 다양한 모듈에 이르기까지 모든 것을 테스트하는 것.
자동화된 테스트를 통해 새 코드와 기존 코드 간 충돌이 발견되는 경우 CI를 적용하면 버그를 빠르게, 더 자주 수정하기가 용이해 짐.
이후, DevOps 주기 관점에서, 지속적 통합(CI) 다음에는 지속적 딜리버리(CD) 및 지속적 배치가 이루어집니다.
CD (Continuous Delivery/Deployment)
CD는 직역하면 '지속적 제공', '지속적 배포'의 의미를 갖고있습니다.
CD는 개발의 프로덕션 레벨까지 자동으로 배포하는것을 의미하는데, CI와 다른점은, CI는 새로운 코드의 빌드와 테스트, Merge까지만을 담당했다면 (즉, 공유 레포지토리까지의 생명주기를 담당했다면) CD는 이를 넘어 프로덕션레벨, 즉 이 코드가 돌아가는 서버 환경에까지 릴리즈가 되는것을 의미합니다.
CD는 검증 완료된 코드 베이스 변경 사항 (업데이트, 버그 수정, 새로운 기능 등)을 사용자에게 최대한 빠르고 안전하게 제공하는 데 중점을 둡니다.
이를 위해 코드 변경 사항을 개발, 테스트, 프로덕션 등과 같은 다양한 환경에 배포하는 작업을 자동화 한다고 볼 수 있습니다.
효과적인 CD 프로세스를 마련하기 위해서는, CI가 개발 파이프라인에 이미 구축이 되어있어야 합니다.
프로덕션 이전의 파이프라인 단계에서는 수동으로 핸들링 할 일이 없으므로, CD는 잘 설계된 테스트 자동화에 크게 의존합니다.
따라서, CD에는 선행 테스트에 많은 투자가 필요함을 인지하여야 합니다.
우리가 개발작업을 할 때, 테스트코드를 중요하게 짜야 하는 이유가 바로 이 부분에서 나타납니다.
팀원간 각자가 테스트코드를 작성하여 이 테스트코드가 공유 repo단으로 배포가 된 상태에서, 이후 통합을 할 때, 통합 된 코드가 제대로 동작을 하는지 판가름 하기위해 테스트코드 파이프라인을 구축하여 원래 동작하여야 할 기능들이 병합(Merge)이후에 정상적으로 작동을 하는지를 판단할 수가 있습니다.
만약 병합 파이프라인에서 테스트코드가 실패하게된다면 통합이 실패하였다는 의미가 된 것이므로, 어딘가 문제가 생겼음을 알 수 있겠지요.
만약 테스트코드를 작성하지않고, 그대로 CI를 진행하였다면 병합된 코드에 문제가 생긴지도 모르는 상태로 프로덕션 환경에까지 올라가게 될 위험성이 생기게되어버립니다.
또한, 이러한 테스트코드 작성을 통해 배포 단계에서 수동으로 일일이 테스트를 검증할 필요가 없게되므로 배포의 신뢰성 향상으로 인해 개발자의 생산성 또한 향상될 수가 있겠지요.
후기
김영한님을 비롯한 시니어 개발자분들이 항상 말씀하시는 말씀이 "테스트코드는 아주 중요하고, 테스트 코드를 작성하는 기간이 되게 지루하다고 느낄 수 있겠지만, 테스트코드를 작성 하는것이 개발 시간을 단축시킬 수 있는 방법이다!"라고 말씀 하신것이 CI/CD를 공부하면서 체감이 됩니다.
개발은 공부할 수록 유기적으로 얽혀있다는것이 나날이 체감이 되는것 같고, 이러한 관계들을 알아갈 때마다 재미가 더해져가는것같습니다.
이것으로 포스팅을 마칩니다.
긴 글 읽어주셔서 감사합니다.
출처
https://www.ibm.com/kr-ko/topics/continuous-integration
CI (Continuous Integration) 이란? | IBM
하루에 한 번 이상 개발자 작업을 기본 코드 분기와 통합하는 소프트웨어 개발 및 DevOps 사례인 CI(지속적 통합)에 대해 알아봅니다.
www.ibm.com
https://www.redhat.com/ko/topics/devops/what-is-ci-cd
CI/CD(CI CD, 지속적 통합/지속적 배포): 개념, 툴, 구축, 차이
CI/CD는 애플리케이션의 통합 및 테스트 단계부터 제공 및 배포까지 애플리케이션 라이프사이클 전체에서 지속적인 자동화와 지속적인 모니터링을 제공하는 것을 뜻합니다.
www.redhat.com