애플리케이션을 인스턴스에 서버에 배포하는 전략은 여러 가지 방법이 존재합니다.
기존 서비스의 다운타임을 최소화하면서 새 버전을 배포해야 하기 때문에 상황에 따라 올바른 배포 전략을 사용해야 하는데요.
그 중 블루그린 배포와 카나리 배포 전략은 클라우드 환경이 대중화되면서 쉽게 사용할 수 있게 되었습니다.
클라우드 환경에서는 리소스를 쉽게 증설할 수 있고, 그에 따라 새로운 버전을 빠르고 간편하게 배포할 수 있기 때문인데요.
특히 클라우드 공급자가 제공하는 Load Balancer 서비스를 이용하면 트래픽 라우팅을 손쉽게 구성할 수 있어 다양한 배포 방법을 이용할 수 있게 되었습니다.
이번 포스팅에서는 대표적인 클라우드 공급자 중 하나인 Google Cloud Platform에서 Load Balancer 서비스를 이용한 카나리, 블루그린 배포 방법에 대하여 알아보겠습니다.
1. 배포 전략의 종류
현재 주로 사용되는 배포 전략은 3가지가 존재합니다. 롤링 배포, 카나리 배포, 블루/그린 배포가 그것인데요.
각 배포 전략 마다 장/단점이 존재하고 사용할 수 있는 상황이 다르기 때문에 배포하고자 하는 환경과 목적을 잘 파악한 뒤 알맞은 전략을 선택해야 합니다.
먼저 각 배포 전략의 특징을 알아보겠습니다.
1-1. 롤링 배포(Rolling Deployment)
롤링 배포는 다운타임을 최소화하기 위해 사용할 수 있는 가장 전통적인 배포 방식입니다.
롤링 배포는 기존 서비스의 유지를 위해, 전체 서버에 새 버전을 배포하는 대신 일부 서버에만 새 버전을 점진적으로 배포합니다.
새 버전에 이상이 없다면 롤링 배포는 최종적으로 모든 서버에 배포를 완료할때까지 진행됩니다.
이러한 배포 방식은 단계적으로 버전을 배포하기 때문에 이슈를 발견했을시 롤백을 수행할 충분한 시간을 벌 수 있습니다.
때문에 롤링 배포는 배포에 대한 제어가 편리한 전략이라는 장점이 존재합니다.
하지만 롤링 배포는 처리량을 위한 여분의 서버가 필요하기 때문에 더 많은 리소스가 필요하고, 배포 및 롤백에 시간이 오래 걸린다는 단점 또한 존재합니다.
1-2. 카나리 배포(Canary Deployment)
카나리 배포는 서버 앞단에 트래픽을 분배할 수 있는 로드 밸런서와 함께 사용할 수 있는 배포 전략입니다.
카나리 배포는 특정 서버에 새 버전을 배포하고 소수의 인원에게만 새 버전이 배포된 서버로 트래픽을 유입시키는 방식을 사용합니다.
새 버전에 이상 없음이 확인되면 최종적으로 모든 서버에 새 버전을 배포함으로써 배포를 마치게 됩니다.
카나리 배포의 어원은 석탄 광산에서 유독 가스의 위험을 미리 알려주는 카나리아 새에서 유래합니다.
새 버전으로 유입된 소수의 인원이 카나리아 새의 역할을 해 미리 위험을 감지하고 이슈에 대응할 시간을 벌어주게 됩니다.
카나리 배포의 장점은 소수의 서버에만 새 버전을 배포하기 때문에 리소스 사용량을 최적화할 수 있다는 점, 위험을 관리하기 쉬운 배포 전략이라는 점이 존재합니다.
하지만 소수 유저에게만 새 버전이 적용되기 때문에 유저 간 혼동이 올 수 있다는 점, 일부 유저에 대해서 테스트를 진행하기 때문에 완벽한 테스팅은 불가능하다는 단점 또한 존재합니다.
1-3. 블루/그린 배포(Blue/Green Deployment)
블루/그린 배포는 버전이 다른 두 환경을 준비한 뒤, 기존 버전에서 새 버전의 서버들로 한 번에 트래픽을 유입시켜 새 버전을 라이브 버전으로 만드는 배포 전략입니다.
여기서 기존의 버전을 블루, 새 버전을 그린이라고 칭하여 블루/그린 배포라는 이름이 붙었습니다.
블루/그린 배포는 트래픽 라우팅을 한 번만 변경하면 되는 비교적 간단한 배포 전략이며, 롤백 또한 간단하다는 장점이 존재합니다.
하지만 동일한 두 환경을 준비해야 하기 때문에 리소스 사용량이 2배로 들어가며, 따라서 비용 또한 2배로 소요된다는 단점이 존재합니다.
2. Google Cloud에서 배포 전략 사용하기
클라우드 환경에서 또한 위의 다양한 배포 전략을 사용할 수 있습니다.
특히 클라우드 환경은 리소스의 Scalability가 높고, 복잡한 트래픽 라우팅을 쉽게 구현할 수 있기 때문에 카나리 배포, 블루/그린 배포 전략을 사용하는데 이점이 존재합니다.
이번 장에서는 Google Cloud 환경에서 카나리, 블루/그린 배포 전략을 구현하는 방법에 대하여 알아보겠습니다.
2-0. 사전 준비
Cloud Load Balancer를 사용하기 전에 Load Balancer의 구성 요소에 대해 알아보겠습니다.
위 그림이 HTTP(S) Load Balancer의 구성 요소들을 나타낸 다이어그램입니다.
HTTP(S) Load Balancer는 아래와 같은 순서로 트래픽이 전달됩니다.
Forwarding Rule -> Target Proxy -> URL Map -> Backend Service -> Instance Group
각 요소들의 역할은 다음과 같습니다.
1. Forwarding Rule : Cloud Load Balancer의 엔드포인트를 제공합니다.
2. Target Proxy : Forwarding Rule에서 받은 트래픽을 프록시로 전달합니다.
3. URL Map : Target Proxy에서 받은 트래픽을 라우팅 룰에 따라 Backend Service로 전달합니다.
4. Backend Service : 라우팅 룰에 의해 전달받은 트래픽을 인스턴스 백엔드에 전달합니다.
5. Instance Group : Backend Service에 매핑된 트래픽을 인스턴스에 전달합니다.
이 중 URL Map이 배포 전략을 수행하기 위한 라우팅 룰을 수정할 수 있는 구성 요소입니다.
배포 전략을 구현하는 라우팅 룰은 Advanced Routing Rule을 통해서 사용할 수 있는데요.
Cloud Load Balancer의 Advanced Routing Rule은 위와 같은 구조로 이루어져 있습니다.
1. Host Rule : 라우팅 룰을 적용할 호스트를 지정합니다.
2. Path Matcher : 라우팅 룰과 룰을 적용받을 Backend Service를 매핑합니다.
3. Route Rule : 라우팅 룰을 정의합니다. 우선순위, 규칙, 행위로 이루어져 있습니다.
4. Backend Service : 라우팅 룰을 적용받을 Backend를 정의합니다.
위 Advanced Routing Rule을 이용하여 다양한 배포 전략을 구현할 수 있습니다.
2-1. 환경 구성
먼저 Google Cloud Platform 환경에서 배포 전략을 사용하기 위한 환경을 구성해보겠습니다.
기존 버전을 유지할 서버와 새 버전을 배포할 서버를 생성합니다. 여기서 서버는 GCP의 VM 그룹 서비스인 MIG(Managed Instance Group)을 사용합니다.
각 MIG에는 적용된 버전을 쉽게 확인할 수 있도록 트래픽을 받은 백엔드의 정보를 표시하는 웹 서버를 구성했습니다.
그리고 위의 두 MIG를 백엔드로 하는 Load Balancer를 생성합니다.
여기서 Load Balancer는 GCP의 7L LB 서비스인 Cloud HTTP(S) Load Balancer를 사용합니다.
Load Balancer는 2개의 백엔드 서비스를 가지며 각 백엔드 서비스는 위에서 생성한 MIG를 백엔드로 가지도록 구성합니다.
여기서 백엔드 서비스를 2개로 나누는 이유는, Cloud Load Balancer가 백엔드 서비스 단위로 트래픽을 라우팅하기 때문입니다.
2-2. 블루/그린 배포 전략 사용하기
블루/그린 및 카나리 배포 전략의 핵심은 트래픽을 분배하는 Load Balancer가 각 서버 그룹에게 특정한 가중치로 트래픽을 분배해야 한다는 것입니다.
그리고 Google Cloud의 Cloud Load Balancer는 Advanced Routing Rule 을 통해 이 기능을 지원하고 있습니다.
Cloud Load Balancer의 Advanced Routing Rule을 구성해 블루/그린 배포 전략을 사용하는 방법에 대해서 알아보겠습니다.
먼저 생성한 Cloud HTTP(S) Load Balancer의 수정 페이지로 진입한 뒤, Routing rules -> Advanced host and path rule -> ADD HOST AND PATH RULE 순으로 진입합니다.
그럼 위와 같이 Advanced Routing Rule을 입력할 수 있는 창이 나타나게 됩니다.
Advanced Routing Rule은 크게 두 개 값의 입력을 요구합니다.
1. Hosts : 라우팅 룰을 적용할 호스트명을 입력합니다.
2. Path matcher : 라우팅 룰을 입력하는 공간입니다. yaml 포맷을 사용해 규칙을 정의할 수 있습니다. 경로에 따라 적용될 룰을 지정하는 Match, 룰을 정의하는 Action, 룰을 적용할 백엔드를 지정하는 Service로 나누어집니다.
Path matcher 옆의 CODE GUIDANCE를 클릭하면 적용하고자 하는 기능에 따라 입력할 수 있는 라우팅 룰의 예시를 확인할 수 있습니다.
블루/그린 배포 전략을 사용하는 라우팅 룰은 아래와 같이 정의할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
|
defaultService: BACKEND_SERVICE_1_URL
name: path-matcher-1
routeRules:
- matchRules:
- prefixMatch: /
priority: 50
routeAction:
weightedBackendServices:
- backendService: BACKEND_SERVICE_1_URL
- backendService: BACKEND_SERVICE_2_URL
weight: 100 |
cs |
입력해야 할 값을 하나씩 살펴보도록 하겠습니다.
1. defaultService : 어떤 라우팅 룰에도 적용받지 않는 트래픽이 향하게 될 defult 백엔드 서비스입니다. 백엔드 서비스는 모두 projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_NAME 포맷으로 입력합니다.
2. name : 본 라우팅 룰의 이름을 정의합니다.
3. routeRules.matchRules.prefixMatch : 규칙을 적용할 경로를 정의합니다.
4. routeRules.priority : 해당 규칙의 우선순위를 정의합니다. 우선순위는 유니크해야 하며 낮은 값이 높은 값보다 우선합니다.
5. routeRules.routeAction.weightedBackendServices.backendService : 가중치에 따라 트래픽 라우팅을 적용할 백엔드 서비스를 정의합니다.
6. routeRules.routeAction.weightedBackendServices.weight : 위 백엔드 서비스에 적용할 트래픽 가중치를 정의합니다.
블루/그린 배포 전략을 사용하기 위해서는 새 버전의 백엔드 서비스 weight값을 100으로 설정해 새 버전으로 모든 트래픽이 라우팅되도록 합니다.
위 코드를 Path matcher에 입력하고, Hosts에 라우팅 룰을 적용할 호스트명을 입력하면 Advanced Routing Rule 구성이 마무리됩니다.
이후 DONE 버튼을 클릭해 구성을 저장합니다.
블루/그린 배포 전략이 정상적으로 적용되었는지 확인하기 위해 Windows 서버를 띄워 Load Balancer로 접속해보도록 하겠습니다.
Windows 인스턴스를 생성한 뒤 RDP 버튼을 클릭해 VM 인스턴스로 접속합니다.
비밀번호를 세팅한 뒤, 지정한 유저명과 비밀번호로 접속하면 위와 같이 Windows 서버로 접속할 수 있습니다. 여기서 브라우저를 이용해 Load Balancer의 백엔드 웹 서버로 접근하도록 하겠습니다.
배포 전
블루/그린 배포를 수행하기 전, 기존 버전의 인스턴스 그룹만 백엔드 서비스로 존재할 때의 결과를 확인해보겠습니다.
블루/그린 배포를 수행하기 전의 Load Balancer로부터 돌아온 Response입니다.
기본 Backend Service가 backend-service-1으로 설정되어 있기 때문에 backend-service-1에 맵핑된 mig-a 인스턴스 그룹으로 트래픽이 향하는 것을 확인할 수 있습니다.
브라우저를 새로고침해 다시 Request를 보내도 인스턴스 그룹 내에 속한 인스턴스로만 트래픽이 분산될 뿐, 기존 버전의 인스턴스 그룹을 향해 일관적으로 트래픽을 보내게 됩니다.
배포 후
이제 블루/그린 배포 전략을 수행하고 난 뒤의 트래픽 라우팅을 확인해보겠습니다.
위에서 설명했듯이 기존 설정에 백엔드 서비스 2를 추가하고, 이 백엔드 서비스에 가중치를 100으로 주는 방식으로 블루/그린 배포 전략을 구현했습니다.
블루/그린 배포를 수행하고 난 후, Load Balancer 엔드포인트로 접속하면 배포 전과 달리 mig-b 인스턴스 그룹로 트래픽이 향하는 것을 확인할 수 있습니다.
이는 새 버전인 mig-b가 맵핑된 backend-service-2로 100의 가중치를 주는 라우팅 룰을 적용했기 때문입니다.
또한 배포가 수행되면서 라우팅 룰만 변경되는 것이기 때문에, 서버의 다운타임은 거의 존재하지 않았습니다.
트래픽을 지속적으로 보내도 인스턴스 명만 바뀔 뿐 mig-b 인스턴스 그룹에서 Response가 오는 것을 확인할 수 있습니다.
이렇게 기존 버전에서 새 버전으로 한 번에 모든 라우팅을 향하게 구성함으로써 블루/그린 배포를 구현할 수 있습니다.
이 배포 전략은 기존의 인스턴스 그룹과 새 인스턴스 그룹을 유지한채로 새 인스턴스 그룹을 라이브 버전으로 만드는 것이기 때문에 다운타임이 존재하지 않고 한 번에 배포 과정이 수행됩니다.
롤백
배포 후 새 버전에 이상이 발견되면 롤백 과정이 진행되어야 합니다.
Advanced Routing Rule의 설정을 변경하는 것으로 Cloud Load Balancer를 통해 수행된 블루/그린 배포를 롤백할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
|
defaultService: BACKEND_SERVICE_1_URL
name: path-matcher-1
routeRules:
- matchRules:
- prefixMatch: /
priority: 50
routeAction:
weightedBackendServices:
- backendService: BACKEND_SERVICE_1_URL
weight: 100
- backendService: BACKEND_SERVICE_2_URL
|
cs |
위와 같이 새 버전인 backend-service-2에 부여되어 있던 가중치 100을 기존 버전인 backend-service-1에 부여합니다.
구성을 저장하고 난 뒤 다시 브라우저에서 Load Balancer로 요청을 보내 롤백이 수행되었는지 확인합니다.
Response를 확인하면 다시 기존 버전인 mig-a로 트래픽이 향하는 것을 확인할 수 있습니다.
이 과정 또한 트래픽 라우팅만 변경한 작업이기 때문에 진행 과정에서 다운타임이 발생하지 않습니다.
3. Terraform으로 배포 전략 구현하기
지금까지 웹 콘솔에서 Cloud Load Balancer를 사용해 다양한 배포 전략을 사용하는 방법에 대해 알아봤는데요.
이 작업을 웹 콘솔에서 마우스 클릭으로 수행하는 것보다는, 코드로 결과물을 작성하면 상태에 대한 관리 및 배포 프로세스가 더 빨라질 수 있습니다.
코드로 클라우드 리소스를 관리하는 것을 IaC(Infrastructure as Code)라고 하는데요.
현재 가장 널리 쓰이고 있는 IaC 도구는 Hashicorp사에서 제공하는 Terraform입니다.
이번 장에서는 Terraform을 이용해 코드로써 배포 전략을 구성하는 방법에 대해 알아보겠습니다.
3-1. Terraform 코드
Terraform으로 Cloud Load Balancer를 구성하기 위해서는 Forwarding Rule, Target Proxy, URL Map, Backend Service를 각각 정의해야 합니다.
이 중 배포 전략 구현에 직접 영향을 미치는 URL Map 리소스에 대한 코드만 살펴보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
resource "google_compute_url_map" "urlmap" {
name = "urlmap"
description = "a description"
default_service = google_compute_backend_service.testbackend1.id
host_rule {
hosts = ["*"]
path_matcher = "path-matcher-1"
}
path_matcher {
name = "path-matcher-1"
default_service = google_compute_backend_service.testbackend1.id
path_rule {
paths = ["/"]
route_action {
weighted_backend_services {
backend_service = google_compute_backend_service.testbackend1.id
weight = 100
backend_service = google_compute_backend_service.testbackend2.id
}
}
}
}
}
|
cs |
위와 같이 기존 yaml 포맷으로 이루어져 있던 라우팅 룰을 Terraform 언어인 HCL로 구성할 수 있습니다.
path_matcher.path_rule.route_action.weighted_backend_services.weight 어트리뷰트를 통해 각 Backend Service에 할당할 가중치를 설정할 수 있습니다.
해당 어트리뷰트를 생략하는 것으로 가중치를 0으로 설정할 수 있습니다.
위 코드의 경우 "testbackend1" Backend service에 가중치 100을, "testbackend2"에는 가중치 0을 설정합니다.
여기서 블루/그린 배포를 수행하고 싶다면 아래와 같이 가중치를 변경합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
resource "google_compute_url_map" "urlmap" {
name = "urlmap"
description = "a description"
default_service = google_compute_backend_service.testbackend1.id
host_rule {
hosts = ["*"]
path_matcher = "path-matcher-1"
}
path_matcher {
name = "path-matcher-1"
default_service = google_compute_backend_service.testbackend1.id
path_rule {
paths = ["/"]
route_action {
weighted_backend_services {
backend_service = google_compute_backend_service.testbackend1.id
backend_service = google_compute_backend_service.testbackend2.id
weight = 100
}
}
}
}
}
|
cs |
위와 같이 변경할 시 기존 "testbackend1"으로 전달되었던 트래픽을 "testbackend2"로 전달해 블루/그린 배포를 구현할 수 있습니다.
카나리 배포를 수행하고 싶다면 아래와 같이 변경합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
resource "google_compute_url_map" "urlmap" {
name = "urlmap"
description = "a description"
default_service = google_compute_backend_service.testbackend1.id
host_rule {
hosts = ["*"]
path_matcher = "path-matcher-1"
}
path_matcher {
name = "path-matcher-1"
default_service = google_compute_backend_service.testbackend1.id
path_rule {
paths = ["/"]
route_action {
weighted_backend_services {
backend_service = google_compute_backend_service.testbackend1.id
weight = 90
backend_service = google_compute_backend_service.testbackend2.id
weight = 10
}
}
}
}
}
|
cs |
위와 같이 변경할 시 기존 "testbackend1"으로 90% 트래픽을, "testbackend2"로 10% 트래픽을 분산해 카나리 배포를 구현할 수 있습니다.
4. 마무리
지금까지 Google Cloud의 Cloud Load Balancer를 통해 다양한 배포 전략을 구성하는 방법에 대하여 알아봤습니다.
배포 전략은 대표적으로 블루/그린, 카나리를 사용할 수 있으며 가중치 변경을 통해 각 배포 전략을 수행할 수 있었습니다.
또한 Terraform 코드를 통해서 배포 전략을 구현함으로써 효율적인 배포 프로세스가 이루어지도록 할 수도 있음을 알았습니다.
이 글을 보시는 분들이 Cloud Load Balancer를 통해서 배포 전략을 구현하는데 도움을 받으셨으면 합니다.