1. 개요
본 게시글은 무중단 배포에 대한 내용을 담고 있으며 배포 전략에 대한 애니메이션은 [HUDI님의 게시글] 을 인용한것임을 밝힙니다.
맨 처음 배포를 해본것은 약 2년전이었다. 그때는 배포에 대해서 아는것도 없었기에 어떤건지도 잘 모르고, 여기저기를 찾아서 어찌저찌 했던 것 같다. 당시에는 내가 직접 수동 배포를 했었다.
대충 수동 배포 플로우를 정리해보면
1. 작성된 코드를 Github에 Push 한다.
2. AWS EC2에 SSH로 접속한다.
3. EC2에서 작성한 코드들을 Git clone | Git pull 한다.
4. 서버를 빌드하고 실행한다.
이렇게 된다. 당장 코드를 작성하고, 구현하는데에도 시간이 많이 쓰인다. 하지만 거기다 직접 빌드하고, 테스트도 해보고, 최종 배포까지 일련의 과정들을 수동으로 하게된다면 너무 귀찮기도 하고, 개발에 들이는 시간보다 배포에 쓰이는 시간이 더 많을 수 밖에 없었다. 심지어 혼자가 아닌 여러명이서 개발하는 프로젝트라면..?
즉, 수동 배포 는 한계가 명확하고 너무 귀찮은 작업이다. 배포까지의 일련의 과정이 자동화
된다면 얼마나 편할까?
그런 생각으로 나도 Git Actions
와 Docker
로 CI/CD
를 구축하였다. 이제 Github 에 코드를 push 만 하면 Git Actions
가 이를 trigger
하여 Docker
로 자동 배포를 진행해준다.
이때까지는 이걸로 모든게 해결된 줄 알았다.
이러한 배포 방식은 새로운 버전의 서버를 배포하는 과정에서 기존의 서버가 죽어버리는 다운 타임이 발생한다. 실제로 내가 개발중이던 서비스에서는 다운 타임이 대략 1분정도 발생하였는데, 이는 실제로 사용자들이 서비스를 1분동안 접근할 수 없게 되는것이다.
당연히 그건 적합한 방식이 아니란것은 누구나 인지할 것이다.
이처럼 사용자 관점에서 서비스를 지속해서 사용할 수 있도록 다운 타임 을 발생시키지 않도록 하는것이 무중단 배포 라고 한다.
그렇다면 이번 시간에 무중단 배포에 대해서 그리고 어떠한 무중단 배포 전략이 있는지 알아보자.
2. 무중단 배포가 뭘까?
1. Down Time
실제 서비스를 1대의 서버로 운영중이라고 가정해보자. 현재 서버에는 V1 버전이 8080 포트로 실행되고 있는데 이번에 새로운 기능을 추가한 V2를 개발하였고, 이를 배포하고자 한다.
새로운 버전인 V2를 배포하기 위해서는 V2의 빌드 파일들을 서버에 배포해야한다.
새로운 기능만 추가한 것이므로 포트 번호는 V1과 V2 모두 `8080`포트를 사용 중이다.
그러므로 V2를 배포하기 위해서는 실제 운영중인 V1 버전을 잠시 종료하고, V2 버전을 실행하여야 한다. V1이 종료된 시간 과 V2가 실행된 시간의 사이에 유저가 서비스를 이용할 수 없는 시간이 생기는데 이를 다운 타임 이라고 한다.
2. Zero Down Time (무중단 배포)
무중단 배포는 Zero-downtime Deployment로 말 그대로 서비스가 중단되지 않은 상태로, 새로운 버전을 사용자들에게 배포하는 것을 의미한다.
3. 무중단 배포 전략에는 어떤것이 있을까?
배포 전략에 대해서 정리하기에 앞서 애니메이션으로 배포 방식들을 직관적으로 잘 설명한 레퍼런스가 있어 인용하고자 한다. [Hudi님의 게시글] 애니메이션을 확인하면 직관적으로 이해하기 쉽다.
1. 롤링(Rolling) 배포
트래픽을 점진적으로 구버전에서 신버전으로 옮기는 방식으로 2가지의 방식이 있다.
방식 1
- 구 버전이 실행되고 있는 인스턴스를 로드밸런서에서 라우팅 되지 않도록 제거한다.
- 라우팅 되지 않는 인스턴스를 신버전으로 변경한다.
- 다시 로드밸런서에 연결하여 라우팅 되도록 하며, 이 과정을 반복한다.
방식 2
- 인스턴스 하나를 추가하고, 새로운 버전을 실행한다.
- 로드 밸런서에 추가된 인스턴스를 연결한다.
- 구버전 인스턴스 한개를 라우팅에서 제거한다.
❓ V2 1개, v1 2개인 서버가 발생하지 않을까?
맞는 말이다. 그렇기에 이것이 롤링 배포의 단점이라고 할 수 있다.
장점
- 롤백이 필요한 경우 모든 트래픽을 이전 버전으로 되돌릴 수 있다.
- 많은 서버 자원을 확보하지 않아도 무중단 배포가 가능하다. (최소 1개의 추가 노드만 필요)
단점
- 이전 버전과 새 버전이 공존하게 되어 어쩔 수 없이 위험이 수반되어야 한다.
- 배포 도중 서비스 중인 노드 및 인스턴스의 수가 줄어들어 각 서버거 부담하는 트래픽의 양이 늘어날 수 있다.
2. Blue/Green 배포
트래픽을 한번에 구버전에서 신버전으로 옮기는 방법 이다.
현재 운영 중인 서비스를 Blue, 새롭게 배포할 환경을 Green 이라고 한다.
Blue 와 Green 서버를 동시에 나란히 구성해둔 상태로 배포 시점에서 로드 밸런서가 트래픽을 Blue → Green 으로 일제히 변경시킨다. Green 서버가 성공적으로 배포되고, 문제가 없다고 판단하는 경우 Blue 서버를 제거할 수도 있다.
장점
- 롤링 배포와 다르게 한번에 모든 트래픽을 새로운 트래픽으로 변경하기 때문에 호환성 문제가 발생하지 않는다.
단점
- 똑같은 인프라가 복제된 환경이므로 실제 운영에 필요한 서버의 리소스 대비 2배의 리소스가 필요로 하다.
3. 카나리(Canary) 배포
전체적인 방식은 점진적으로 구버전에서 신버전으로 트래픽을 옮기는 것으로 롤링 배포와 비슷하지만 까나리(?) 배포의 핵심은 새로운 버전에 대한 오류를 빠르게 감지하는 것이다.
(마치 까나리 냄새로 콜라인지 까나리인지 조기에 빨리 감지하는 것)
초기에는 소수의 인원들에게만 새 버전의 서버를 제공하고, 나머지 사용자들은 기존의 구버전을 사용한다. 새 버전이 정상적으로 작동하는것이 확인되면 전체 트래픽을 새 버전으로 전환하는 방식이다.
장점
- 실제 사용자 테스트와 무중단 배포를 동시에 진행할 수 있다.
- 새로운 버전으로 인한 위험을 최소화 할 수 있다.
단점
- 롤링 배포와 마찬가지로 두 버전이 함께 존재하므로 호환성 문제가 발생할 수 있다.
Reference