본문 바로가기
CLOUD/AWS

AWS CodeDeploy BLUE/GREEN 배포 자세히 알아보기

by Rainbound-IT 2022. 5. 17.
반응형

목차

     

    Blue/Green 배포를 사용하는 방법에 대해 자세히 알아보기 전에 이것이 무엇인지 이해해 보겠습니다.

    블루/그린 배포는 다운타임 없이 또는 최소한의 위험으로 애플리케이션/소프트웨어의 새 버전을 배포하려는 배포 패턴입니다. 블루/그린 배포는 유사한 스택을 가져온 다음 이 새 스택에 새 버전의 애플리케이션을 배포하여 달성됩니다. 트래픽은 현재 스택(블루 스택이라고 함)에서 새 스택(그린 스택이라고 함)으로 이동됩니다.

    이제 이것이 무엇인지 다루었으므로 Blue/Green 배포를 선택해야 하는 이유는 무엇입니까?

    • 다운타임 없음: 트래픽을 블루 스택에서 그린 스택으로 이동하고 있습니다.
    • 손쉬운 롤백: Green 스택이 정상이 아니면 역 프로세스를 따라 트래픽을 Blue 스택으로 다시 이동할 수 있습니다.
    • 위험 감소: 프로덕션 라이브 트래픽을 마이그레이션하기 전에 기능 테스트를 실행하여 그린 스택을 검증할 수 있습니다.

    이 블로그에서는 ECS 컨테이너 작업에 AWS CodeDeploy 서비스를 사용하여 블루/그린 배포를 수행하는 방법에 대해 자세히 알아볼 것입니다.

    AWS가 2015년 4월에 ECS를 시작했을 때 Blue/Green 배포에 대한 기본 지원은 없었습니다. 엔지니어는 이 문제를 해결하기 위해 다음과 같은 다양한 옵션을 시도했습니다.

    • ELB 뒤에서 Auto-scaling 그룹을 교체합니다.
    • Auto-scaling 그룹 시작 구성 업데이트.
    • Route53을 사용한 DNS 라우팅 업데이트.

    2016년 8월 AWS는 ALB( Application Load Balancer )를 출시했지만 여전히 ECS Blue/Green 배포를 지원하지 않았습니다. 이 문제를 해결하기 위해 Capital One의 팀은 테스트 트래픽에 베타 ALB를 사용한 다음 Blue/Green 작업 간의 트래픽 컷오버에 대한 ALB 수신기 규칙을 교체하는 자체 개발한 Blue/Green 배포 솔루션을 구현했습니다.

    2018년 11월까지 Amazon ECS는 CodeDeploy 를 사용하여 블루/그린 배포에 대한 공식 지원을 추가 했습니다 .

     

     

     

     

    ECS 블루/그린 배포를 위한 전제 조건

    • ECS 배포 유형은 "청록색"이어야 합니다.
    • ECS 서비스는 Application Load Balancer 또는 Network Load Balancer를 사용해야 합니다. 우리는 이 블로그에서 ALBr을 사용할 것입니다.
    • ALB에는 prod 트래픽을 받을 수신기가 있어야 합니다.
    • 테스트 트래픽을 라우팅하는 데 사용되는 로드 밸런서에 선택적 테스트 리스너를 추가할 수 있습니다. 테스트 리스너를 지정하면 CodeDeploy는 배포 중에 테스트 트래픽을 교체/그린 작업 세트로 라우팅합니다.
    • 두 개의 ALB 대상 그룹을 생성해야 합니다. 하나는 Blue 작업용이고 다른 하나는 Green 작업용입니다.

     

    CodeDeploy 블루/그린 배포 흐름

    여기서 가정은 개발 팀 팀이 이미 배포 자동화를 사용하여 ALB 및 대상 그룹이 있는 ECS 서비스를 프로그래밍 방식으로 생성하거나 AWS 콘솔을 사용하여 설정을 수행해야 한다는 것입니다.

    아래 다이어그램은 Blue 작업만 실행되고 100% 프로덕션 트래픽을 사용하는 초기 배포를 보여줍니다.

     

    이제 CodeDeploy 기반 Blue/Green 배포를 살펴보겠습니다. 아래 다이어그램에서 Green 작업이 시작되고(새 버전의 코드임) 대상 그룹 2에 연결되었음을 알 수 있습니다. 이제 ALB 테스트 트래픽 수신기가 포트 8443에서 테스트 트래픽을 위해 준비되었으며 테스트 트래픽이 전송됩니다. Target Group 2를 사용하여 Green 작업에 연결합니다. 테스트 리스너를 통해 테스트 트래픽이 준비되면 후크(람다 함수)를 추가할 수 있습니다. 람다 함수는 ALB/테스트 수신기 포트 8443에서 일부 기능 테스트를 수행할 수 있으며 "성공" 또는 "실패"를 반환합니다.

     

    테스트 트래픽 람다 후크가 "성공"을 반환했다고 가정하면 프로덕션 트래픽은 대상 그룹 2로 라우팅되고 차례로 Green 작업(새 코드 버전)에서 제공됩니다. ALB prod 리스너 포트 443과 테스트 리스너 포트 8443은 이제 모두 대상 그룹 2를 가리킵니다. CodeDeploy는 CodeDeploy 콘솔이나 CLI/API 호출을 통해 롤백이 가능하도록 사전 구성된 기간 동안 Blue 작업을 유지합니다.

    사전 구성된 기간이 경과하면 CodeDeploy는 Blue 작업을 종료하고 이 시점 이후에는 롤백이 불가능합니다.

     

    다양한 CodeDeploy 리소스

    이제 구현 세부 정보를 자세히 살펴보겠습니다. ECS Blue/Green 배포를 지원하려면 아래 AWS CodeDeploy 아티팩트가 필요합니다.

    • CodeDeploy 애플리케이션
    • CodeDeploy 배포 그룹
    • CodeDeploy 배포

     

    따라서 AWS CodeDeploy 콘솔에서 위의 CodeDeploy 리소스를 생성하거나 Python/Boto3 와 같은 언어별 API 또는 CLI를 사용하여 프로그래밍 방식으로 리소스를 생성할 수 있습니다 . 어떻게 생겼는지 살펴보겠습니다.

    Python/Boto3를 사용하여 CodeDeploy 애플리케이션 생성:

        cd_client = boto3.client('codedeploy')
    response = cd_client.create_application(
       applicationName=application_name,
       computePlatform='ECS'
    )
      

    Python/Boto3를 사용하여 CodeDeploy 배포 그룹을 생성합니다.

        response = cd_client.create_deployment_group(
       applicationName='AppECS-sample-springboot-app-qa-bg',
       deploymentGroupName='DgpECS-sample-springboot-app-qa-bg',
       deploymentConfigName='CodeDeployDefault.ECSAllAtOnce',
       serviceRoleArn='arn:aws:iam::123456789123:role/ecs_service_role',
       triggerConfigurations=[
           {
               'triggerName': 'sample-springboot-app-qa-code-deploy-bg-trigger',
               'triggerTargetArn': 'arn:aws:sns:us-east-1:123456789123:my_sns_topic',
               'triggerEvents': [
                   "DeploymentStart",
                   "DeploymentSuccess",
                   "DeploymentFailure",
                   "DeploymentStop",
                   "DeploymentRollback",
                   "DeploymentReady"
               ]
           },
       ],
       autoRollbackConfiguration={
           'enabled': True,
           'events': [
               'DEPLOYMENT_FAILURE', 'DEPLOYMENT_STOP_ON_ALARM', 'DEPLOYMENT_STOP_ON_REQUEST',
           ]
       },
       deploymentStyle={
           'deploymentType': 'BLUE_GREEN',
           'deploymentOption': 'WITH_TRAFFIC_CONTROL'
       },
       blueGreenDeploymentConfiguration={
           'terminateBlueInstancesOnDeploymentSuccess': {
               'action': 'TERMINATE',
               'terminationWaitTimeInMinutes': 15
           },
           'deploymentReadyOption': {
               'actionOnTimeout': 'CONTINUE_DEPLOYMENT'
           }
       },
       loadBalancerInfo={
           'targetGroupPairInfoList': [
               {
                   'targetGroups': [
                       {
                           'name': 'sample-springboot-app-qa-tg1'
                       },
                       {
                           'name': 'sample-springboot-app-qa-tg2'
                       }
                   ],
                   'prodTrafficRoute': {
                       'listenerArns': 'arn:aws:elasticloadbalancing:us-east-1:123456789123:listener/app/sample-springboot-app-qa-alb/2b8b8ab60f9c7e43/97b643f12d4fa8a4'
                   },
                   'testTrafficRoute': {
                       'listenerArns': 'arn:aws:elasticloadbalancing:us-east-1:123456789123:listener/app/sample-springboot-app-qa-alb/2b8b8ed64f9c7e43/09261df9b5476d39'
                   }
               },
           ]
       },
       ecsServices=[
           {
               'serviceName': 'sample-springboot-app-qa',
               'clusterName': 'my-test-cluster'
           }
       ]
    )
      

    CodeDeploy 배포 생성:

        response = cd_client.create_deployment(
       applicationName='AppECS-sample-springboot-app-qa-bg',
       deploymentGroupName='DgpECS-sample-springboot-app-qa-bg',
       revision={
           'revisionType': 'AppSpecContent',
           'appSpecContent': {
               'content': "APPSPEC FILE CONTENT",
               'sha256': "xxxxxx"
           }
       },
       ignoreApplicationStopFailures=False,
       autoRollbackConfiguration={
           'enabled': True,
           'events': [
               'DEPLOYMENT_FAILURE',
               'DEPLOYMENT_STOP_ON_ALARM',
               'DEPLOYMENT_STOP_ON_REQUEST'
           ]
       }
    )
      

    CodeDeploy "배포"는 리소스 정보 및 실행 후크 정보를 제공하는 YAML 파일인 AppSpec 파일을 사용합니다. 아래 표시된 것처럼 리소스 섹션에는 작업 정의 및 컨테이너 정보가 포함되어 있습니다. Hooks 섹션을 사용하면 CodeDeploy Blue/Green 배포 수명 주기의 다양한 지점에서 트리거될 람다 함수를 추가할 수 있습니다(자세한 내용은 아래 섹션 참조).

        {
       "version": 0.0,
       "Resources": [
           {
               "TargetService": {
                   "Type": "AWS::ECS::Service",
                   "Properties": {
                       "TaskDefinition": "ECS-TASK-DEFINITION-ARN",
                       "LoadBalancerInfo": {
                           "ContainerName": "my-container",
                           "ContainerPort": 8080
                       }
                   }
               }
           }
       ],
       "Hooks": [
     {
      "AfterAllowTestTraffic": "arn:aws:lambda:us-east-1:1234567890:function:my-green-ready-hook"
     }
    ]
    }
      

    블루/그린 배포 실행: happy path(왜..)

    초기 설정:

    여기에는 Fargate 작업을 실행하는 Blue/Green 배포(CodeDeploy에서 제공)를 사용하는 ECS 서비스가 있습니다.

    ECS 서비스는 ECS 작업 정의 버전 132를 기반으로 실행 중이며 하나의 Fargate 작업을 실행하고 있습니다.

     

    이 ECS 서비스에 연결된 ALB 및 대상 그룹:

     

    포트 443의 수신기는 PROD 트래픽 수신기이고 포트 8443은 TEST 트래픽 수신기입니다. 이 시점에서 두 리스너는 "-tg2"로 끝나는 동일한 대상 그룹에 연결됩니다.

     

     

    Code Deploy를 사용하여 Blue/Green 배포를 지원하기 위해 이 ECS 서비스에 대해 생성된 2개의 대상 그룹. 이 시점에서 대상 그룹 "-tg2"만 대상/작업을 실행하고 위의 ALB 수신기에 연결됩니다.

    블루 그린 배포를 시작합시다

    먼저 ECS 서비스에 대한 Blue/Green 배포를 시작합니다. ECS 배포는 ECS API를 사용하거나 AWS ECS 콘솔 - ECS 서비스 업데이트 기능을 사용하여 프로그래밍 방식으로 시작한 다음 CodeDeploy 콘솔 또는 CodeDeploy API에서 새 배포 생성을 시작할 수 있습니다. 업데이트된 코드 버전은 ECS 서비스를 업데이트하는 데 사용할 새 ECS 작업 정의 파일에 언급됩니다.

    ECS 서비스의 배포 컨트롤러가 CodeDeploy이므로 CodeDeploy의 배포가 트리거되고 여기에서 새 ECS 작업이 시작됩니다.

    아래에서 새 ECS 작업이 시작되었고 실행 횟수는 2임을 볼 수 있습니다. Deployments(배포) 탭에서 PRIMARY 항목은 현재 Blue 작업에 대한 것이고 ACTIVE 항목은 새로운 다가오는 Green 작업에 대한 것입니다.

     

    이제 녹색 작업이 실행 중입니다. PROD 트래픽은 원래 스택의 Blue 작업에서 계속 제공됩니다. 이 단계에서 롤백은 여전히 ​​가능하지만 롤백은 Green 작업을 종료한다는 점을 명심하십시오.

     

     

    이제 ALB 수신기가 업데이트되었습니다. PROD 수신기(Port-443)는 여전히 대상 그룹 "-tg2"에 연결되어 있고 라이브 트래픽을 서비스하고 있습니다. TEST 리스너(Port-8443)는 이전에 ALB에 전혀 연결되지 않은 대상 그룹 "-tg1"에 연결됩니다. 따라서 ALB DNS:8443을 누르고 PROD 트래픽을 사용하지 않는 Green 스택을 테스트할 수 있습니다.

     

    이제 "-tg1"(TEST 트래픽 가져오기) 및 "-tg2"(PROD 트래픽 가져오기)가 TEST 및 PROD 수신기를 제공하는 ALB에 연결됩니다.

     

    PROD 트래픽이 파란색에서 녹색 작업으로 이동됨:

    트래픽 라우팅이 완료되고 새 Green 작업(또는 교체 작업)이 이제 PROD 트래픽을 처리합니다. 그러나 트래픽 라우팅은 어떻게 발생했습니까? 이에 대한 통제권이 있습니까?  — 좋은 질문이고 별도의 섹션에서 답변하겠습니다 :)

    블루 작업이 여전히 주변에 있고 유휴 상태에 있기 때문에 이 단계에서 롤백이 여전히 가능하며 다음 15분 동안 사용할 수 있습니다(이 기간은 이전 섹션에 표시된 것처럼 DeploymentGroup 속성 "terminationWaitTimeInMinutes"에서 구성 가능) . 롤백 작업? — 또 다른 섹션에서 설명할 좋은 질문입니다.

     

    ECS는 이제 업데이트된 작업 정의 버전 133(이전에는 132)을 사용하여 작업을 실행하고 있습니다. 원래 작업과 새 작업이 모두 여전히 실행 중이므로 롤백이 여전히 가능합니다. 이제 배포 탭에 트래픽의 100%가 새로운 친환경 작업인 교체 작업에서 제공되는 것으로 표시됩니다.

    이제 ALB 리스너 PROD(Port-443) 및 TEST(Port-8443) 모두 Green 태스크가 대상으로 있는 대상 그룹 "-tg1"을 가리키고 있습니다.

    빨리 감기 15분 - 블루/그린 배포 완료

    CodeDeploy "DeploymentGroup" 구성 "terminationWaitTimeInMinutes"에 따라 15분 후에 Blue 작업을 종료합니다. 이제 Blue 작업이 종료되어 롤백이 더 이상 가능하지 않습니다!

    Blue/original 작업이 사라지면 ECS 실행 작업 수가 1로 돌아갑니다. 작업 정의 버전은 "133"이며 이는 새 버전이 PROD 트래픽을 제공하고 있음을 의미합니다. 배포 탭에서 ACTIVE 항목이 이제 사라졌습니다.

    블루/그린 배포 실행: 롤백 흐름

    현재 안정적인 PROD 상태를 요약해 보겠습니다.

    • ECS 서비스는 작업 정의 버전 133을 사용하여 1개의 작업을 실행하고 있습니다.
    • ALB 수신기는 대상 그룹 "-tg1"을 가리키는 PROD(Port-443) 및 TEST(Port-8443) 모두를 수신합니다.
    • 대상 그룹 "-tg1"이 활성 상태이고 PROD 트래픽을 제공하고 "-tg2"가 ALB에 연결되어 있지 않습니다.

    지금 새 버전을 배포하고 롤백 흐름을 시연하기 위해 트래픽 재라우팅 이후를 롤백합니다.

    다시 말하지만 블루/그린 배포를 시작하겠습니다.

    새로운 Blue/Green 배포가 트래픽을 Green 스택으로 다시 라우팅하고 Original/Blue 작업을 종료하기 전에 15분 동안 대기하는 상태를 빠르게 진행하고 검토해 보겠습니다.

    Blue 작업을 종료하기 위해 대기 중인 CodeDeploy Blue/Green 배포와 새로운 Green/Replacement 작업에서 제공하는 PROD 트래픽이 있습니다.

     

    ECS 서비스는 이제 새로운 ECS 작업 정의 버전 134(이 배포는 133으로 시작)를 사용하여 새 작업을 실행하고 있으며 ECS 실행 작업 수는 2입니다. 하나는 ECS task def 버전 133이고 다른 하나는 새로운 ECS task def 버전 134입니다. ECS 배포는 새 PRIMARY 작업에서 제공하는 100% 트래픽을 표시해야 합니다.

     

    ALB 수신기 PROD(Port-443) 및 TEST(Port-8443)는 모두 대상 그룹 "-tg2"를 가리키고 있습니다. 이전에는 "-tg1"에 연결되었습니다.

     

    따라서 배포가 제대로 진행되지 않았고 지금 롤백해야 한다고 가정해 보겠습니다.

    "배포 중지 및 롤백" 버튼을 클릭하여 CodeDeploy 콘솔에서 롤백을 시작하겠습니다.

    배포 작동 방식은 CodeDeploy가 현재 배포를 중지하고 Original/Blue 작업 삭제 단계를 건너뛰는 것입니다. 그런 다음 새 배포를 만들어 이전 배포를 롤백하고 트래픽을 Replace/Green 작업에서 Original/Blue 작업으로 다시 라우팅합니다. 또한 교체/그린 작업을 종료합니다.

    ECS 및 ALB 설정이 포스트 롤백처럼 보이는 방식을 검토해 보겠습니다.

    ECS 서비스는 이제 원래 작업 def 버전 133을 사용하여 작업을 실행하고 실행 중인 작업 수는 다시 1로 돌아갑니다. ECS Deployments는 PRIMARY 작업을 통해 100% PROD 트래픽을 표시합니다.

     

    ALB 리스너 PROD 및 TEST 모두 대상 그룹 "-tg1"으로 돌아갑니다.

    이렇게 하면 성공적인 롤백이 완료됩니다!

     

    블루/그린 태스크 간의 트래픽 라우팅을 제어하는 ​​방법은 무엇입니까?

    CodeDeploy를 사용하면 Blue/Green 배포 파이프라인에 연결 후크를 실행할 수 있습니다. 후크는 구현하는 람다 함수일 뿐입니다.

    몇 가지 예시 시나리오는 다음과 같습니다.

    • PROD 트래픽을 라우팅하기 전에 Green 스택에서 기능 테스트를 실행합니다.
    • PROD 트래픽 마이그레이션 전에 S3에 파일 다운로드/업로드와 같은 일부 환경 설정.

    Amazon ECS 배포를 위한 수명 주기 이벤트 후크 목록(참조: 여기 )

    • BeforeInstall  — 대체 작업 세트가 생성되기 전에 작업을 실행하는 데 사용됩니다.
    • AfterInstall  — 대체 작업 세트가 생성되고 대상 그룹 중 하나가 연결된 후 작업을 실행하는 데 사용됩니다.
    • AfterAllowTestTraffic  — 테스트 리스너가 대체 작업 세트에 트래픽을 제공한 후 작업을 실행하는 데 사용됩니다. 이 시점에서 후크 함수의 결과는 롤백을 트리거할 수 있습니다.
    • BeforeAllowTraffic  — 두 번째 대상 그룹이 교체 작업 세트와 연결된 후 트래픽이 교체 작업 세트로 이동되기 전에 작업을 실행하는 데 사용됩니다. 이 수명 주기 이벤트에서 후크 기능의 결과는 롤백을 트리거할 수 있습니다.
    • AfterAllowTraffic  — 두 번째 대상 그룹이 대체 작업 세트에 트래픽을 제공한 후 작업을 실행하는 데 사용됩니다. 이 수명 주기 이벤트에서 후크 기능의 결과는 롤백을 트리거할 수 있습니다.

    수명 주기 후크를 추가하려면 어떻게 해야 합니까?

    수명 주기 후크 람다 함수는 생성하여 CodeDeploy 배포 개체에 연결하는 AppSpec 파일을 통해 추가할 수 있습니다. 예제는 위의 섹션을 참조하십시오.

    자동 롤백 구현에는 다음이 포함됩니다.

    • 수명 주기 이벤트 " AfterAllowTestTraffic" 에 대한 후크 추가 .
    • 람다 함수는 ALB DNS + TEST 수신기 포트(8443)를 사용하여 Green 작업에서 기능 테스트를 실행합니다.
    • 기능 테스트가 통과하면(즉, CodeDeploy 콘솔에 "성공"이 반환됨) Blue/Green 배포가 계속되고 트래픽이 Green 스택으로 이동합니다.
    • 테스트가 실패하면(즉, CodeDeploy 콘솔에 "실패"가 반환됨) Blue 스택으로 트래픽의 자동 롤백이 시작됩니다.

     

    요약

    AWS CodeDeploy를 사용한 ECS 서비스 배포는 매우 쉽고 강력한 Blue/Green 배포 지원을 제공하는 매우 강력한 조합입니다.

    추가 배포 수명 주기 후크는 요구 사항에 따라 트래픽 라우팅 정책을 제어할 수 있는 유연성을 제공합니다.

    이미 AWS 서비스를 광범위하게 사용하고 있고 ECS가 컨테이너 배포 플랫폼인 경우 자체 개발한 솔루션보다 이 아키텍처를 반드시 고려해야 합니다.

    기존 AWS 서비스를 사용하는 Canary 배포 패턴에 대해 배우고 싶다면 여기 를 살펴보십시오. 이 주제에 대한 훌륭한 게시물입니다!

     

    참고문헌

     

     

    위글은 아래링크 번역한것입니다.

    https://www.capitalone.com/tech/cloud/seamless-blue-green-deployment-using-aws-codedeploy/

     

    A Deep Dive Into Seamless Blue/Green Deployment Using AWS CodeDeploy | Capital One

    A deep dive on blue/green deployments using AWS CodeDeploy service for ECS container tasks.

    www.capitalone.com

     

    반응형

    댓글