매번 헷갈리는 CI/CD 배포 전략 정리해버리기
안녕하세요. CX사업본부 모바일 사업부의 정하은입니다?
4월부터 쉬지 않고 프로젝트 개발을 달려오고, 드디어 이번 한 주동안 휴식기간을 얻을 수 있게 되었는데요. 개인 공부 시간이 생긴 참에 미뤄두었던 블로그를 써보았습니다.
AWS 자격증 중 하나인 DVA나 DOP에서 반드시 등장하는 배포 파트. 블루/그린 배포, 카나리 배포, 롤링 배포 등 상황마다 다른 배포 전략을 선택할 필요가 있는데요. 하지만 막상 문제를 풀 때면 계속 헷갈리더라구요. (저만 그런가요..?) 저 같은 분들을 위해 이 글 하나로 시험에 나오는 배포 전략에 대해선 마스터 할 수 있도록 정리해보도록 할게요.
(AWS 서비스 기준으로 작성된 점 미리 양해 부탁드립니다!)
배포 전략이 뭔데?
예전에는 수 개월 혹은 수 년에 한 번씩 서비스를 릴리스 했었지만, 최근에는 서비스를 더 작게 만들고(마이크로 서비스) 더 자주 배포(Deployment) 하는 방식으로 변화하고 있습니다. 그만큼 변경 사항이 생겼을 때 더 빠르게 반영할 수 있지만 코드에 손을 대는 것이란 항상 위험이 따르죠. 그렇기 때문에 이에 대응하여 배포 전략을 구성해야합니다.
가장 대표적인 배포 전략은 아래 네 가지가 되는데요. 아마 실제로 검색해보시면 AWS의 서비스들 중 배포 기능을 가진 것들에서 이들 중 하나는 꼭 들어가 있는 것을 볼 수 있을거에요.
- 인플레이스 배포 (In-place Deployment)
- 롤링 배포 (Rolling Update Deployment)
- 블루/그린 배포 (Blue/Green Deployment)
- 카나리 배포 (Canary Deployment)
각 배포 전략마다 장점과 단점이 모두 존재하기 때문에 상황에 따라 전략을 선택해야하는데요. 그럼 바로 각 배포 전략에 대해 알아보도록 하겠습니다.
인플레이스 배포 (In-place Deployment)
인플레이스 배포는 사용중인 환경에 새로운 변경사항이 포함된 어플리케이션만 반영하는 방법입니다.
이 방식을 사용하는 대표적인 서비스가 CodeDeploy 인데요. 배포 그룹의 각 환경 (인스턴스) 에 있는 어플리케이션을 일시정지한 후, 최신 상태의 어플리케이션의 변경 사항이 설치되면 새 버전의 앱을 실행하는 형식으로 이루어집니다. 로드 밸런서를 사용하면 각 인스턴스가 배포중이더라도 등록을 해제할 수 있으며, 배포 완료 후에 이전 버전으로 복원도 가능합니다.
이것은 배포 방식 상 EC2, 온프레미스 환경에만 사용 가능한 배포 전략이 됩니다.
롤링 배포 (Rolling Update Deployment)
여러 개의 가동중인 서버 (인스턴스)를 갖춘 환경에서 한 번에 정해진 수만큼의 서버에 새로운 변경 사항이 포함된 어플리케이션을 배포하는 방법입니다.
구 버전에서 새 버전으로 트래픽을 점진적으로 전환하며, 구 버전의 인스턴스도 점차 삭제됩니다. 그렇기 때문에 서버 수의 제약이 있을 경우에는 유용한 방법이 될 수 있지만 배포 중 인스턴스의 수가 감소 되기 때문에 서버 처리 용량을 미리 고려해야 합니다. 이 방식을 사용하고 있는 서비스는 Elastic Beanstalk와 CodeDeploy인데요. CodeDeploy는 공식문서에서 직접적으로 서술된 부분이 없기 때문에 알기 어렵지만 기본적으로 롤링 배포를 하도록 설정되어있습니다. 그래서 EC2, 온프레미스의 경우, 인플레이스 배포가 롤링 배포와 혼합된 방식을 따르고 있고, Lambda나 ECS의 경우는 롤링 배포가 기본적인 배포 방식이 된다고 이해하면 될 것 같네요.
덤으로 Elastic Beanstalk의 배포 방법을 보면, 롤링이 그냥 롤링과 추가 배치를 사용한 롤링으로 나뉘는데요. 둘 다 구 버전에서 새 버전으로 점진적으로 전환되는 것은 동일하지만, 추가 배치를 사용한 롤링의 경우는 새 버전의 인스턴스를 배포한 후 바로 시작하여 배포 프로세스 중에도 모든 용량이 유지되도록 합니다.
블루/그린 배포 (Blue/Green Deployment)
새로운 변경사항이 포함된 어플리케이션을 위한 새로운 환경을 구축하고 교체하는 방법입니다.
흔히 블루/그린 배포를 "구 버전의 환경을 새 버전의 환경으로 똑같이 구축해서 한 번에 전환한다" 라고 생각하는데, 사실 이것은 Red/Black 배포의 정의입니다. 그래서 실제로는 "신 버전과 구 버전의 어플리케이션이 한 순간이라도 공존하였다" 라고 하는 것이 더 올바르다고 할 수 있습니다. (사실 Red/Black 배포에 대한 정의가 사람마다 다르다보니 모호한 개념이라는 건 안 비밀...) 이 이유에 대한 추가 설명은 아래 카나리 배포 부분 설명에 적어 놓을게요.
아무튼 블루/그린 배포는 하나의 버전만 프로덕션 되기 때문에 버전 관리 문제를 방지할 수 있고, 운영 환경에 영향을 주지 않고 실제 서비스 환경으로 새 버전 테스트가 가능합니다.
또, 주로 인플레이스 배포와 비교될 때 언급되는 장점으로 새 버전으로 전환 후에 문제가 생겼을 시에 구 버전으로 되돌리기 위한 롤백도 인플레이스 배포보다 더 빠르다는 점이 있습니다.
단, 구 버전과 새 버전 두 환경 모두 갖출 필요가 있기 때문에 시스템 자원이 두 배로 필요해지며, 비용이 그만큼 비싸지기 때문에 비용을 고려한 구성을 필요로 한데요. 이런 단점은 AWS와 같은 클라우드 서비스에서는 종량 과금이라는 메리트가 있어 큰 부담 요소로 작용되지 않으니 그리 신경 쓸 부분은 아닙니다.
블루/그린 배포도 Elastic Beanstalk, CodeDeploy에서 이 방식을 사용할 수 있습니다.
카나리 배포 (Canary Deployment)
가동 중인 서버들의 일부에만 새로운 앱을 배포하여, 일부 트래픽을 새 버전의 환경으로 분산하는 방법입니다.
A/B 테스트가 가능하고, 오류율 및 성능 모니터링에 유용하게 사용할 수 있다는 장점이 있는데요. 트래픽을 분산시킬 라우팅은 임의적 또는 사용자 프로필 등을 기반으로 분류할 수 있습니다. 분산 후에 결과에 따라 새 버전이 운영 환경을 대체할 수도 있고, 다시 구 버전으로 되돌릴 수도 있어요.
이 방법을 사용하는 가장 대표적인 서비스는 API Gateway 인데, 사실 API Gateway 외에 카나리 방식이 언급된 서비스가 하나 있습니다. 바로 CodeDeploy 인데요. 블루/그린 배포의 배포 설정 타입의 종류 중 하나로 분류되어 있습니다.
위의 블루/그린 배포 설명에서 "구 버전의 환경을 새 버전의 환경으로 똑같이 구축해서 한 번에 전환한다" 라는 게 올바른 정의가 아니라고 했는데, 블루/그린 배포의 트래픽 전환 방식은 All-at-Once (한 번에) 만 있는게 아니기 때문입니다. 아래의 공식 문서를 보시면 카나리 외에도 리니어라는 방식도 있으며 블루/그린 배포 방식을 사용할 때도 트래픽을 몇 번에 나누어 전환이 가능한 것을 확인할 수 있습니다.
마무리하며
배포 전략에 대해서 간략히 정리해보았는데 공식 문서나 타블로그 글들을 읽다보니 배포 전략에 대해서 수박 겉핡기 식으로만 인지하고 있었던 걸 알았습니다. (특히, 지금까지 알고 있던 블루/그린 배포의 정의가 레드/블랙 배포의 정의였다는 걸 알았을 때의 충격이란...? ) 평소에 일할 때는 기존 프로젝트의 방식을 따르기만 했었기 때문에 배포 전략에 대해서 제대로 알아본 적이 없었던 것이 부끄러울 정도였네요. 코딩 외의 개발 공부도 더 열심히 해야겠다는 생각이 들었습니다.
아무튼 지나가다 읽어보신 여러분께 도움이 되는 내용이 되기를 바라며 글 마무리하겠습니다?