November 22nd 2020
Contents
AWS 블루 / 그린 배포 절차
이번 글에서는 새 버전의 애플리케이션 개발 후 진행되는 배포 과정과 이와 관련된 몇 가지 개념을 살펴보겠습니다.
무중단 배포와 중단 배포는 말 그대로 배포 시 서비스를 중단할지 안 할지의 차이점을 가집니다. 무중단 배포는 서비스를 중단하지 않기 때문에 사용자가 서비스를 이용하는 데 아무런 지장이 없습니다. 중단 배포는 "서버 정기 점검"과 같이 사용자에게 알림을 주고 시스템을 정지한 후 배포를 진행합니다.
서비스에 지장이 없는 무중단 배포를 하는 것이 좋을 수 있지만, 중단 배포를 하는 이유는 무중단 배포를 하기에 큰 비용이 발생하는 상황이 있을 수 있기 때문입니다.
애플리케이션 코드나, 데이터베이스 스키마의 구버전과 신버전이 함께 서비스되면 안 되는 상황에 중단 배포를 하거나 별도의 처리를 해 줄 수 있습니다. 중단 배포는 보통 온라인 게임 서버에서 많이 하게 되는데, 구버전과 신버전이 같이 작동하면 게임 정책이 달라 서비스할 수 없을 수 있어서, 정기 점검을 걸고 중단 배포나 강제 업데이트를 하기도 합니다.
현재 위치 배포는 무중단 배포(In-place deployment)의 한 방법이며, 새롭게 서버를 증설하거나 줄이지 않고 배포를 진행하는 방식입니다. 다음은 현재 위치 배포를 단계별로 표현한 그림입니다.
현재 v.1..01 버전 네 대의 서버를 운영 중이고 v.1.02로 새롭게 배포하려 합니다.
네 대 중 두 대의 인스턴스를 로드 밸런서에제 해제합니다.
해제를 해서 요청을 받지 않는 두 대의 인스턴스에 새로운 버전 v1.02를 배포합니다.
v1.02 버전을 배포한 인스턴스를 다시 로드 밸런서에 등록합니다.
v.1.01 버전을 서비스 하고 있는 나머지 두 대의 서버를 로드 밸런서에세 제외합니다.
제외한 두 서버에 새로운 버전의 코드를 배포합니다.
배포 후 나머지 두 대도 로드 밸런서에 다시 연결합니다.
이런 방식으로 클라이언트에는 지장이 없게 서비스를 새로운 버전으로 배포할 수 있습니다.
현재 위치 배포는 새로운 인스턴스를 생성하지 않아서, 빠르고 간단하게 진행할 수 있습니다. 하지만, 배포 중 인스턴스 수가 줄기 때문에 요청량 처리에 무리가 올 수도 있습니다. 이러한 경우 시간이 조금 더 걸려도 여유 인스턴스를 추가 후 배포를 진행할 수도 있습니다.
추가로, 만약 배포한 버전에 문제가 있어 이전 버전으로 롤백하려면 다시 배포를 진행해야 하므로 대응 시간이 오래 걸린다는 단점이 있습니다.
블루/그린 배포도 무중단 배포 방식 중 하나입니다. 아래 그림처럼 두 대의 서버를 가지고 있는 그룹이 있고 새로운 버전의 코드를 배포하려 합니다.
블루/그린 배포는 두 개의 그룹으로 진행되는데, 이 그룹은 Load Balancer의 대상 그룹일 수도 있고 Auto Scaling Group일 수도 있습니다.
그린 그룹에 새로운 버전의 인스턴스를 블루 그룹과 같은 수로 생성합니다.
새로운 버전의 코드를 그린 그룹에 배포 후 로드밸런서에 등록하고 클라이언트의 요청을 블루 그룹과 나눠서 처리하도록 합니다.
이후 문제가 없으면 블루 그룹을 로드 밸런서에서 제외합니다.
블루/그린 배포는 최신 버전의 코드를 배포한 서버가 준비된 상태이기 때문에, 구버전과 신버전이 같이 서비스되는 시간을 짧게 가져갈 수 있습니다. 무중단 배포가 기본적으로 구버전과 신버전이 같이 서비스돼도 문제가 없어야 하지만, 예상치 못한 문제가 발생할 수 있어서 이러한 위험 부담을 줄일 수 있습니다.
배포 후 운영 환경에서 버그가 발생하면 빠르게 롤백을 할 수 있습니다. 현재 위치 배포에서는 롤백이 다시 구버전을 배포하는 것이었지만, 블루/그린에서는 연결된 로드 밸런서만 해제하면 됩니다. 실제로 배포 후 블루 그룹과 그린 그룹을 한동안 같이 운영하며 문제가 없다고 판단되면 블루 그룹의 인스턴스를 종료할 수 있습니다.
블루/그린의 특성상 배포 중 인스턴스 수가 줄지 않아 요청을 처리하는 데 부담이 없습니다. 하지만, 배포 단계에서 인스턴스의 수가 두 배로 늘어나는 단점도 있습니다.
참고로, 실섭 배포 전 파이널 스테이지 용으로 로드 밸런서를 하나 더 구성해 그린 그룹을 최종적으로 테스트해 보고 운영 서버에 적용할 수도 있습니다.
Auto Scaling Group을 사용해 여러 서버를 운영하는 경우 서버 단위 블루/그린 배포를 진행할 수 있습니다. 하지만, Auto Scaling Group 없이 1 ~ 2대의 소규모 서버를 운영한다면, nginx와 같은 웹 서버에서 블루/그린 배포를 진행할 수도 있습니다.
요청이 들어오면 클라이언트와 로드 밸러서를 거쳐 웹 서버에서 3001번 포트를 리스닝 하는 애플리케이션에 전달합니다.
새로운 버전을 배포하기 위해 3002번 포트에 애플리케이션을 추가합니다.
웹 서버 설정을 수정후 리로드해서 3001번 포트에서 3002번 포트로 요청이 전달되도록 합니다.
배포 후 문제가 없다면 3001번 포트를 리스닝하는 애플리케이션을 종료합니다.
이처럼 블루/그린 방식은 꼭 서버 단위가 아니어도 서버 내 웹 서버와 포트를 이용해 배포를 진행할 수 있습니다. 주의할 점은 nginx 설정 변경 후 restart 명령어를 사용하면 처리 중이거나 새로 들어오는 요청은 에러가 발생합니다. reload 명령어를 사용하면 nginx가 새로운 프로세스를 생성하고 기존 프로세스에는 새로운 요청을 전달하지 않습니다. 그리고 기존 처리 중이던 요청이 모두 종료되는 것을 기다리기 때문에 에러 없이 새로운 설정을 적용할 수 있습니다.
배포 관련 기본적인 개념에 대해 알아봤습니다. 위 개념을 실제 배포 시 어떻게 적용해야 할 지 알아보아요. 우리가 Git을 이용해 새로운 버전을 배포하려 한다면 어떤 과정으로 진행해야 할까요?
만약 서버가 한 두 대 정도만 있다면, 위 방법도 좋을거에요. 하지만 Auto Scaling Group을 이용해 24시간 수시로 서버가 새로 생기고 꺼지는 상황에서는 어떻게 최신 버전을 배포할 수 있을까요?
자동으로 추가되는 인스턴스에 사람이 직접 접속해 최신 코드를 내려받을 수는 없습니다. 그래서, 인스턴스가 자동으로 생성될 때 최신 버전의 코드를 저장해햐 하는데, 그러기 위해서 최신 버전의 AMI를 만들어야 합니다. 그리고, 이 AMI를 이요ㅕㅇ해 Auto Scaling Group에서 서버를 생성하게 해야 합니다.
대략적인 배포 과정을 살펴보면 아래와 같습니다. 초기 AMI 생성용 인스턴스로 서버를 구동합니다.
인스턴스에 접속해 최신 버전의 소스코드를 배포합니다.
배포 완료 후 해당 인스턴스를 종료하고, 새로운 AMI를 생성하고, 그린 그룹(비활성 그룹)의 시작 템플릿을 수정합니다.
그린 그룹의 새로운 인스턴스는 최신 버전의 코드가 적용된 인스턴스입니다. 그린 그룹을 로드 밸런서에 등록 후 요청을 처리힙니다. 문제가 없다면 블루 그룹을 로드 밸런서에서 제외합니다.
AWS에서 블루/그린 배포를 위해 블루 그룹을 먼저 생성하겠습니다. 기존 버전의 코드를 담고 있는 시작 템플릿을 선택해 Group을 생성해 줍니다.
저는 BlueGroup이라는 이름으로 AutoScaling 그룹을 생성하고, 서브넷은 ap-northeast-2a, 2c로 설정해 주었습니다.
Blue Group의 ASG이 생성되었으면, 서버 인스턴스 실행을 위해 로브 밸런서 대상 그룹에 등록 할 것입니다. 새로 생성한 ASG을 선택한 뒤, 연습용으로 생성한 로드 밸런서 대상 그룹에 등록했습니다.
로드 밸런서에 연결이 잘 됐는지 확인을 위해, 로드 밸런서 DNS 주소로 접속해 보아요.
접속이 잘 되었어요. :)
기존 버전의 블루 그룹 코드가 서비스 중이고, 이제 새로운 버전의 코드를 배포할 차례입니다. AMI 생성용 EC2 인스터스를 다시 사작 후 애플리케이션 폴러도 이동해 최신 버전의 코드를 내려받습니다.
저는 리눅스에 nginx 웹서버와 nodejs 애플리케이션으로 서비스하고 있기 때문에 node 앱 폴더로 이동해 최신 코드를 내려받았습니다.
# 프로젝트 폴더로 이동
cd sample-app/
# 새로운 버전 받기
git pull
# 시스템도 함께 종료
sudo shutdown -h now
AMI 생성용 인스턴스를 업데이트 및 정지합니다. 그리고 인스턴스에서 우클릭 해 새로운 이미지를 생성합니다.
최신 버전 코드를 담은 AMI를 새로운 생성했습니다. 이 AMI를 가지고 새로운 시작템플릿을 만들거에요. 시작 템플릿 메뉴로 이동해 템플릿을 새로 생성합니다.
템플릿 생성 시 시작 템플릿 콘텐츠에는 앞서 새로 생성한 Green Group의 AMI를 추가해 줍니다. AMI ID로 검색해 설정할 수 있습니다.
AMI 생성용 EC2에 접속해 새로운 버전의 코드를 내려받고, 이를 이용해 그린 그룹을(비활성 그룹) 위한 새로운 버전의 AMI와 시작 템플릿을 생성했습니다.
이제 새로운 시작 템플릿을 적용할 Auto Scaling Group(그린 그룹)을 생성할 차례입니다. 앞서 블루 그룹을 생성한 것과 같은 방식으로 그린 그릅을 생성해 주세요.
현재까지 진행 상황을 그림으로 보면 아래와 같습니다.
블루 그룹에는 기존 코드가 서비스 되고 있고, 그린 그룹에는 최신 버전의 코드가 준비되 있지만 아직 로드 밸런서에 등록은 안 된 상태입니다.
블루/그린으로 무중단 배포를 하기 위해 그린 그룹을 로드 밸런서에 등록하고, 문제가 없으면 블루 그룹을 대상 그룹에서 제외를 할 것입니다.
Auto Scaling Group 메뉴로 이동해 그린 그룹의 로드 밸런싱을 추가해 줍니다.
그리고 브라우저에서 접속해 보면 블루 그룹과 그린 그룹이 요청을 나눠서 처리하는 것을 확인할 수 있습니다.
그린 그룹을 확인 했으니, 블루 그릅을 로드 밸런서의 대상 그룹에서 제거해 줍니다. 그리고 로드 밸런서의 DNS 주소로 다시 접속해 보면 그린 그룹만 요청을 처리하는 것을 확인할 수 있습니다.
새롭게 배포된 버전에 문제거 없어 블루 그릅의 인스턴스를 종료하도록 할게요. 블루 그룹의 목표 용량과 최소를 0으로 변경해 인스턴스를 종료해 줍니다.
블루 그룹의 모든 인스턴스가 종료되면 블루/그린 배포 과정이 완료된 것입니다!
구러면 안녕~~!