중단 배포 방식과 다운타임
서버 한대로 서비스를 운영한다고 가정하면, 현재 서버에는 V1 버전이 실행되고 있는 상황입니다. 그리고 우리는 이번에 여러 기능을 추가한 V2 버전을 새로 개발했고, 이제 사용자들이 V2 버전을 사용할 수 있도록 배포해야 합니다.
배포를 하려면 어떤 과정을 거쳐야할까? 일단 새로 만든 V2 버전 빌드를 서버에 다운로드 합니다. V1 버전과 V2 버전은 서로 같은 포트를 사용하므로, V2 버전을 실행하기 전에 먼저 현재 실행중인 V1 버전의 프로세스를 종료해야 합니다. 이 시점부터 유저는 서비스를 사용할 수 없게되며, 유저가 새로운 V2 버전으로 접속할 수 있도록 바로 V2 빌드를 실행합니다.
로딩과정을 거치고 V2 버전이 정상적으로 실행되면 유저가 다시 정상적으로 서비스를 이용할 수 있게 됩니다.
앞서 이야기한 배포 방식을 중단 배포라고 하며, V1 버전이 종료되고 V2 버전이 실행되는 그 사이, 즉 유저가 서비스를 이용할 수 없는 시간을 다운타임(downtime)이라고 합니다.
무중단 배포 (Zero-downtime Deployment)
1. 롤링 배포 (Rolling Update Deployment)
여러 개의 가동중인 서버 (인스턴스)를 갖춘 환경에서 한 번에 정해진 수만큼의 서버에 새로운 변경 사항이 포함된 어플리케이션을 배포하는 방법입니다.
구 버전에서 새 버전으로 트래픽을 점진적으로 전환하며, 구 버전의 인스턴스도 점차 삭제됩니다. 그렇기 때문에 서버 수의 제약이 있을 경우에는 유용한 방법이 될 수 있지만 배포 중 인스턴스의 수가 감소 되기 때문에 서버 처리 용량을 미리 고려해야 합니다. 이 방식을 사용하고 있는 서비스는 Elastic Beanstalk와 CodeDeploy인데요. CodeDeploy는 공식문서에서 직접적으로 서술된 부분이 없기 때문에 알기 어렵지만 기본적으로 롤링 배포를 하도록 설정되어있습니다. 그래서 EC2, 온프레미스의 경우, 인플레이스 배포가 롤링 배포와 혼합된 방식을 따르고 있고, Lambda나 ECS의 경우는 롤링 배포가 기본적인 배포 방식이 된다고 이해하면 될 것 같네요.
덤으로 Elastic Beanstalk의 배포 방법을 보면, 롤링이 그냥 롤링과 추가 배치를 사용한 롤링으로 나뉘는데요. 둘 다 구 버전에서 새 버전으로 점진적으로 전환되는 것은 동일하지만, 추가 배치를 사용한 롤링의 경우는 새 버전의 인스턴스를 배포한 후 바로 시작하여 배포 프로세스 중에도 모든 용량이 유지되도록 합니다.
※ 단점
방식2와 같은 경우 배포 도중 서비스 중인 인스턴스의 수가 줄어들게 되어 각각의 서버가 부담하는 트래픽의 양이 늘어날 수 있다. 따라서 전체 트래픽의 양과 단일 서버가 처리할 수 있는 트래픽의 양을 잘 파악하여 배포를 진행해야한다.
또한 구버전과 신버전의 어플리케이션이 동시에 서비스되기 때문에 호환성 문제가 발생할 수 있다.
2. 블루/그린 배포 (Blue/Green Deployment)
새로운 변경사항이 포함된 어플리케이션을 위한 새로운 환경을 구축하고 교체하는 방법입니다.
흔히 블루/그린 배포를 "구 버전의 환경을 새 버전의 환경으로 똑같이 구축해서 한 번에 전환한다" 라고 생각하는데, 사실 이것은 Red/Black 배포의 정의입니다. 그래서 실제로는 "신 버전과 구 버전의 어플리케이션이 한 순간이라도 공존하였다" 라고 하는 것이 더 올바르다고 할 수 있습니다. 이 이유에 대한 추가 설명은 아래 카나리 배포 부분 설명에 적어 놓을게요.
아무튼 블루/그린 배포는 하나의 버전만 프로덕션 되기 때문에 버전 관리 문제를 방지할 수 있고, 운영 환경에 영향을 주지 않고 실제 서비스 환경으로 새 버전 테스트가 가능합니다.
또, 주로 인플레이스 배포와 비교될 때 언급되는 장점으로 새 버전으로 전환 후에 문제가 생겼을 시에 구 버전으로 되돌리기 위한 롤백도 인플레이스 배포보다 더 빠르다는 점이 있습니다.
단, 구 버전과 새 버전 두 환경 모두 갖출 필요가 있기 때문에 시스템 자원이 두 배로 필요해지며, 비용이 그만큼 비싸지기 때문에 비용을 고려한 구성을 필요로 한데요. 이런 단점은 AWS와 같은 클라우드 서비스에서는 종량 과금이라는 메리트가 있어 큰 부담 요소로 작용되지 않으니 그리 신경 쓸 부분은 아닙니다.
블루/그린 배포도 Elastic Beanstalk, CodeDeploy에서 이 방식을 사용할 수 있습니다.
※ 단점
실제 운영에 필요한 서버 리소스 대비 2배의 리소스를 확보해야한다. 클라우드 환경에서 운영한다면 필요없는 인스턴스를 제거하면 그만이지만, 온프레미스 방식으로 서비스를 운영했다면 비용 부담이 클것이다.
3. 카나리 배포 (Canary Deployment)
가동 중인 서버들의 일부에만 새로운 앱을 배포하여, 일부 트래픽을 새 버전의 환경으로 분산하는 방법입니다.
A/B 테스트가 가능하고, 오류율 및 성능 모니터링에 유용하게 사용할 수 있다는 장점이 있습니다. 트래픽을 분산시킬 라우팅은 임의적 또는 사용자 프로필 등을 기반으로 분류할 수 있습니다. 분산 후에 결과에 따라 새 버전이 운영 환경을 대체할 수도 있고, 다시 구 버전으로 되돌릴 수도 있습니다.
이 방법을 사용하는 가장 대표적인 서비스는 API Gateway 인데, 사실 API Gateway 외에 카나리 방식이 언급된 서비스가 하나 있습니다. 바로 CodeDeploy 인데요. 블루/그린 배포의 배포 설정 타입의 종류 중 하나로 분류되어 있습니다.
위의 블루/그린 배포 설명에서 "구 버전의 환경을 새 버전의 환경으로 똑같이 구축해서 한 번에 전환한다" 라는 게 올바른 정의가 아니라고 했는데, 블루/그린 배포의 트래픽 전환 방식은 All-at-Once (한 번에) 만 있는게 아니기 때문입니다. 아래의 공식 문서를 보시면 카나리 외에도 리니어라는 방식도 있으며 블루/그린 배포 방식을 사용할 때도 트래픽을 몇 번에 나누어 전환이 가능한 것을 확인할 수 있습니다.
※ 단점
롤링 배포와 마찬가지로 신/구 버전의 애플리케이션이 동시에 존재하므로 호환성 문제가 발생할 수 있다.
참고 자료
다양한 배포 기법과 AWS에서 구축하는 CI/CD 파이프라인
댓글