AWS 에서 Blue-Green 무중단 배포 구현
먼저 EC2 인스턴스 한 대(Elastic IP) 구성입니다. Elastic IP는 blue-green 스위치를 구현하는 가장 단순한 방법입니다. 방법은 이렇습니다. 새 EC2 인스턴스를 런칭하고, 설정하고, 새로운 버전을 배포하고, 테스트한 뒤, 운영서버에 적용할 준비가 되었다면 EIP를 새 인스턴스로 할당하기만 하면 됩니다. 그러면 사용자의 트래픽이 거의 즉시 새 인스턴스로 redirect됩니다.
다음은 ELB 뒤에 여러 EC2 인스턴스가 있는 경우입니다. LB로 배포하는 환경이라면 위에서 본 EIP를 이용한 테크닉은 동작하지 않습니다. EIP와 ELB는 associate할 수 없기 때문입니다. 이 경우 blue 환경은 EC2 인스턴스 pool 중 하나가 되고, LB는 request를 pool에서 healthy 상태인 인스턴스 중 하나에 임의로 보냅니다. blue-green 스위치가 같은 LB 뒤에서 동작하게 하려면, pool에 있는 모든 EC2 인스턴스를 새로운 버전으로 교체해야 합니다. 여기에는 두 가지 방법이 있습니다. 하나는 일련의 API 호출을 자동화하는 방법이고, 다른 하나는 AutoScaling groups를 사용하는 방법입니다.
API 호출을 자동화하는 방법부터 보겠습니다. ELB API의 자세한 내용은 http://docs.aws.amazon.com/ElasticLoadBalancing/latest/APIReference/Welcome.html에 있습니다. 이 API로 EC2 인스턴스를 등록하고 해제할 수 있습니다. API 호출로 “blue” 인스턴스를 제거하면서 동시에 “green” 인스턴스를 등록합니다. 이 작업은 병렬로 매우 빠르게 수행할 수 있습니다. 다만 스위치가 즉시 이루어지지는 않습니다. ELB에 인스턴스를 등록하는 시점과, 그 인스턴스로 request를 route하기 시작하는 시점 사이에 딜레이가 있기 때문입니다. ELB는 healthy 인스턴스로만 route하기 때문에, health check를 위한 약간의 시간이 필요합니다.
AutoScaling groups를 쓰는 방법도 있습니다. AutoScaling은 EC2 인스턴스를 늘리고 줄이는 일을 자동화해 줍니다. 인스턴스가 unhealthy 상태가 되거나 지정한 threshold를 넘어서면 AutoScaling이 인스턴스를 추가하거나 교체합니다. 이 특징을 활용한 blue/green 스위치 구현은 다음과 같습니다. 먼저 새로운 “green” 버전을 위한 launch configuration을 생성합니다. 그 launch configuration을 사용한 새 “green” AutoScaling group을 만들고, 서빙 중인 “blue” 인스턴스들과 같은 ELB에 associate합니다. 새 인스턴스가 healthy 상태가 되어 등록될 때까지 기다린 뒤, “blue” 그룹의 desired number of instances를 0으로 업데이트해서 예전 인스턴스들이 죽기를 기다립니다. 마지막으로 “blue” AutoScaling group과 launch configuration을 삭제합니다. 이 방법의 단점은 느리다는 것입니다. 새 인스턴스 생성을 기다리고, AutoScaling group이 healthy 상태를 확인하기를 기다리고, ELB가 healthy 상태를 확인하기를 기다리고, 예전 인스턴스들이 죽기를 기다려야 합니다. 그래서 저는 이 방법을 쓰지 않고 다음에 나오는 DNS redirection을 사용합니다. 읽고 보니 이걸 안 쓴다는 건가 싶긴 합니다.
DNS redirection using Route53도 있습니다. 보통은 EIP 주소나 긴 ELB 호스트네임 대신 도메인 주소를 가지고 있을 것입니다. AWS가 아닌 환경이라면 blue-green 스위치는 DNS의 CNAME 레코드를 변경하는 방식으로 수행했을 것이고, AWS에서는 같은 결과를 얻기 위해 Route53을 사용할 수 있습니다. Route53로 단순하게 새 ELB를 바라보도록 resource record set을 업데이트하면 됩니다.
Route53이 이런 일반적인 DNS 접근을 지원하지만, 좀 더 좋은 대안이 있습니다. Route53을 Weighted 라운드 로빈으로 사용하는 방법입니다. 이 방식은 regular resource record sets와 alias resource record sets 모두에서 동작합니다. 같은 도메인이나 서브도메인의 multiple answers에 associate되도록 설정하고, 각 엔트리별로 0에서 255 사이의 가중치를 부여합니다. DNS 쿼리가 처리될 때, Route53은 가중치를 기반으로 계산된 확률을 사용해 하나의 answer를 선택합니다. blue-green 스위치가 작동하기 위해서는, 현재의 “blue” 환경 엔트리의 가중치를 255로, 새로운 “green” 환경의 가중치를 0으로 두면 됩니다. 이후에 가중치만 바꿔 주면 트래픽이 blue에서 green으로 swap됩니다. 이 방법의 유일한 단점은 DNS 변경 전파에 약간의 시간이 걸린다는 것입니다. 그래서 사용자가 perceive할 시기를 정확히 컨트롤하기는 어렵습니다. 장점은 거의 zero-downtime이라는 점입니다.
마지막은 Elastic Beanstalk의 Environment swap입니다. http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.CNAMESwap.html에 설명된 대로 CNAMEs swap을 하면 됩니다.
http://www.thoughtworks.com/insights/blog/implementing-blue-green-deployments-aws