튜토리얼: 블루/그린 배포를 사용하는 서비스 만들기

튜토리얼: 블루/그린 배포를 사용하는 서비스 만들기

Amazon ECS는 Amazon ECS 콘솔의 Create Service 마법사에 블루/그린 배포를 통합했어요. 자세한 내용은 Creating an Amazon ECS rolling update deployment 를 참고해 주세요. 다음 튜토리얼은 AWS CLI로 블루/그린 배포 유형을 사용하는 Fargate 태스크가 포함된 Amazon ECS 서비스를 만드는 방법을 보여 줘요.

출처: 문서

본문

참고 블루/그린 배포 수행 지원이 CloudFormation에 추가되었어요. 자세한 내용은 AWS CloudFormation User Guide 의 Perform Amazon ECS blue/green deployments through CodeDeploy using CloudFormation 을 참고해 주세요.

전제 조건 이 튜토리얼에서는 다음 전제 조건을 완료했다고 가정해요.

  • 최신 버전의 AWS CLI 가 설치되고 구성되어 있어야 해요. AWS CLI 설치 또는 업그레이드에 대한 자세한 내용은 Installing the AWS Command Line Interface 를 참고해 주세요.
  • Set up to use Amazon ECS 의 단계가 완료되어 있어야 해요.
  • IAM 사용자가 AmazonECS_FullAccess IAM 정책 예제에 지정된 필요한 권한을 보유하고 있어야 해요.
  • 사용할 VPC 와 보안 그룹 이 만들어져 있어야 해요. 자세한 내용은 Create a virtual private cloud 를 참고해 주세요.
  • Amazon ECS CodeDeploy IAM 역할이 생성되어 있어야 해요. 자세한 내용은 Amazon ECS CodeDeploy IAM Role 을 참고해 주세요.

1단계: Application Load Balancer 만들기 블루/그린 배포 유형을 사용하는 Amazon ECS 서비스는 Application Load Balancer, Network Load Balancer, Service Connect를 사용하거나 헤드리스일 수 있어요. 관리형 트래픽 전환을 위해 로드 밸런서 또는 Service Connect가 필요해요. 이 튜토리얼은 Application Load Balancer를 사용해요.

Application Load Balancer를 만들려면

  1. create-load-balancer 명령을 사용해 Application Load Balancer를 만듭니다. 같은 가용 영역이 아닌 두 서브넷과 보안 그룹을 지정합니다.
    aws elbv2 create-load-balancer \
        --name bluegreen-alb \
        --subnets subnet-abcd1234 subnet-abcd5678 \
        --security-groups sg-abcd1234 \
        --region us-east-1
    
    출력에는 다음 형식의 로드 밸런서의 Amazon Resource Name(ARN)이 포함됩니다.
    arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642
    
  2. create-target-group 명령을 사용해 대상 그룹을 만듭니다. 이 대상 그룹은 서비스의 원래 태스크 세트로 트래픽을 라우팅합니다.
    aws elbv2 create-target-group \
        --name bluegreentarget1 \
        --protocol HTTP \
        --port 80 \
        --target-type ip \
        --vpc-id vpc-abcd1234 \
        --region us-east-1
    
    출력에는 다음 형식의 대상 그룹의 ARN이 포함됩니다.
    arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4
    
  3. create-listener 명령을 사용해 요청을 대상 그룹으로 전달하는 기본 규칙이 있는 로드 밸런서 리스너를 만듭니다.
    aws elbv2 create-listener \
        --load-balancer-arn arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642 \
        --protocol HTTP \
        --port 80 \
        --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4 \
        --region us-east-1
    
    출력에는 다음 형식의 리스너의 ARN이 포함됩니다.
    arn:aws:elasticloadbalancing:region:aws_account_id:listener/app/bluegreen-alb/e5ba62739c16e642/665750bec1b03bd4
    

2단계: Amazon ECS 클러스터 만들기 create-cluster 명령을 사용해 사용할 tutorial-bluegreen-cluster 라는 클러스터를 만들어요.

aws ecs create-cluster \
    --cluster-name tutorial-bluegreen-cluster \
    --region us-east-1

출력에는 다음 형식의 클러스터 ARN이 포함돼요.

arn:aws:ecs:region:aws_account_id:cluster/tutorial-bluegreen-cluster

3단계: 태스크 정의 등록 register-task-definition 명령을 사용해 Fargate와 호환되는 태스크 정의를 등록해요. 이 태스크 정의는 awsvpc 네트워크 모드 사용을 요구해요. 다음은 이 튜토리얼에 사용되는 예제 태스크 정의예요.

  1. 먼저 다음 내용으로 fargate-task.json 이라는 파일을 만듭니다. 태스크 실행 역할의 ARN을 사용해야 합니다. 자세한 내용은 Amazon ECS task execution IAM role 을 참고해 주세요.
    {
        "family": "sample-fargate",
        "networkMode": "awsvpc",
        "containerDefinitions": [
            {
                "name": "sample-app",
                "image": "public.ecr.aws/docker/library/httpd:latest",
                "portMappings": [
                    {
                        "containerPort": 80,
                        "hostPort": 80,
                        "protocol": "tcp"
                    }
                ],
                "essential": true,
                "entryPoint": [
                    "sh",
        		"-c"
                ],
                "command": [
                    "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
                ]
            }
        ],
        "requiresCompatibilities": [
            "FARGATE"
        ],
        "cpu": "256",
        "memory": "512"
    }
    
  2. 그런 다음 만든 fargate-task.json 파일을 사용해 태스크 정의를 등록합니다.
    aws ecs register-task-definition \
        --cli-input-json file://fargate-task.json \
        --region us-east-1
    

4단계: Amazon ECS 서비스 만들기 create-service 명령을 사용해 서비스를 만들어요.

  1. 먼저 다음 내용으로 service-bluegreen.json 이라는 파일을 만듭니다.
    {
        "cluster": "tutorial-bluegreen-cluster",
        "serviceName": "service-bluegreen",
        "taskDefinition": "tutorial-task-def",
        "loadBalancers": [
            {
                "targetGroupArn": "arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4",
                "containerName": "sample-app",
                "containerPort": 80
            }
        ],
        "launchType": "FARGATE",
        "schedulingStrategy": "REPLICA",
        "deploymentController": {
            "type": "CODE_DEPLOY"
        },
        "platformVersion": "LATEST",
        "networkConfiguration": {
           "awsvpcConfiguration": {
              "assignPublicIp": "ENABLED",
              "securityGroups": [ "sg-abcd1234" ],
              "subnets": [ "subnet-abcd1234", "subnet-abcd5678" ]
           }
        },
        "desiredCount": 1
    }
    
  2. 그런 다음 만든 service-bluegreen.json 파일을 사용해 서비스를 만듭니다.
    aws ecs create-service \
        --cli-input-json file://service-bluegreen.json \
        --region us-east-1
    
    출력에는 다음 형식의 서비스 ARN이 포함됩니다.
    arn:aws:ecs:region:aws_account_id:service/tutorial-bluegreen-cluster/service-bluegreen
    

5단계: AWS CodeDeploy 리소스 만들기 다음 단계를 사용해 CodeDeploy 애플리케이션, CodeDeploy 배포 그룹용 Application Load Balancer 대상 그룹, CodeDeploy 배포 그룹을 만들어요.

CodeDeploy 리소스를 만들려면

  1. create-application 명령을 사용해 CodeDeploy 애플리케이션을 만듭니다. ECS 컴퓨팅 플랫폼을 지정합니다.
    aws deploy create-application \
        --application-name tutorial-bluegreen-app \
        --compute-platform ECS \
        --region us-east-1
    
    출력에는 다음 형식의 애플리케이션 ID가 포함됩니다.
    {
        "applicationId": "b8e9c1ef-3048-424e-9174-885d7dc9dc11"
    }
    
  2. create-target-group 명령을 사용해 CodeDeploy 배포 그룹을 만들 때 사용할 두 번째 Application Load Balancer 대상 그룹을 만듭니다.
    aws elbv2 create-target-group \
        --name bluegreentarget2 \
        --protocol HTTP \
        --port 80 \
        --target-type ip \
        --vpc-id "vpc-0b6dd82c67d8012a1" \
        --region us-east-1
    
    출력에는 다음 형식의 대상 그룹 ARN이 포함됩니다.
    arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget2/708d384187a3cfdc
    
  3. create-deployment-group 명령을 사용해 CodeDeploy 배포 그룹을 만듭니다. 먼저 다음 내용으로 tutorial-deployment-group.json 이라는 파일을 만듭니다. 이 예제는 만든 리소스를 사용합니다. serviceRoleArn 에 내 Amazon ECS CodeDeploy IAM 역할의 ARN을 지정합니다. 자세한 내용은 Amazon ECS CodeDeploy IAM Role 을 참고해 주세요.
    {
       "applicationName": "tutorial-bluegreen-app",
       "autoRollbackConfiguration": {
          "enabled": true,
          "events": [ "DEPLOYMENT_FAILURE" ]
       },
       "blueGreenDeploymentConfiguration": {
          "deploymentReadyOption": {
             "actionOnTimeout": "CONTINUE_DEPLOYMENT",
             "waitTimeInMinutes": 0
          },
          "terminateBlueInstancesOnDeploymentSuccess": {
             "action": "TERMINATE",
             "terminationWaitTimeInMinutes": 5
          }
       },
       "deploymentGroupName": "tutorial-bluegreen-dg",
       "deploymentStyle": {
          "deploymentOption": "WITH_TRAFFIC_CONTROL",
          "deploymentType": "BLUE_GREEN"
       },
       "loadBalancerInfo": {
          "targetGroupPairInfoList": [
            {
              "targetGroups": [
                 {
                     "name": "bluegreentarget1"
                 },
                 {
                     "name": "bluegreentarget2"
                 }
              ],
              "prodTrafficRoute": {
                  "listenerArns": [
                      "arn:aws:elasticloadbalancing:region:aws_account_id:listener/app/bluegreen-alb/e5ba62739c16e642/665750bec1b03bd4"
                  ]
              }
            }
          ]
       },
       "serviceRoleArn": "arn:aws:iam::aws_account_id:role/ecsCodeDeployRole",
       "ecsServices": [
           {
               "serviceName": "service-bluegreen",
               "clusterName": "tutorial-bluegreen-cluster"
           }
       ]
    }
    
  4. 그런 다음 CodeDeploy 배포 그룹을 만듭니다.
    aws deploy create-deployment-group \
        --cli-input-json file://tutorial-deployment-group.json \
        --region us-east-1
    
    출력에는 다음 형식의 배포 그룹 ID가 포함됩니다.
    {
        "deploymentGroupId": "6fd9bdc6-dc51-4af5-ba5a-0a4a72431c88"
    }
    

6단계: CodeDeploy 배포 만들기 및 모니터링 다음 단계를 사용해 애플리케이션 사양 파일(AppSpec 파일)과 CodeDeploy 배포를 만들고 업로드해요.

CodeDeploy 배포를 만들고 모니터링하려면 AppSpec 파일을 만들고 업로드합니다.

  1. CodeDeploy 배포 그룹의 내용으로 appspec.yaml 이라는 파일을 만듭니다. 이 예제는 튜토리얼 앞부분에서 만든 리소스를 사용합니다.
    version: 0.0
    Resources:
      - TargetService:
          Type: AWS::ECS::Service
          Properties:
            TaskDefinition: "arn:aws:ecs:region:aws_account_id:task-definition/first-run-task-definition:7"
            LoadBalancerInfo:
              ContainerName: "sample-app"
              ContainerPort: 80
            PlatformVersion: "LATEST"
    
  2. s3 mb 명령을 사용해 AppSpec 파일용 Amazon S3 버킷을 만듭니다.
    aws s3 mb s3://tutorial-bluegreen-bucket
    
  3. s3 cp 명령을 사용해 AppSpec 파일을 Amazon S3 버킷에 업로드합니다.
    aws s3 cp ./appspec.yaml s3://tutorial-bluegreen-bucket/appspec.yaml
    

다음 단계를 사용해 CodeDeploy 배포를 만듭니다. 4. CodeDeploy 배포의 내용으로 create-deployment.json 이라는 파일을 만듭니다. 이 예제는 튜토리얼 앞부분에서 만든 리소스를 사용합니다.

{
    "applicationName": "tutorial-bluegreen-app",
    "deploymentGroupName": "tutorial-bluegreen-dg",
    "revision": {
        "revisionType": "S3",
        "s3Location": {
            "bucket": "tutorial-bluegreen-bucket",
            "key": "appspec.yaml",
            "bundleType": "YAML"
        }
    }
}
  1. create-deployment 명령을 사용해 배포를 만듭니다.
    aws deploy create-deployment \
        --cli-input-json file://create-deployment.json \
        --region us-east-1
    
    출력에는 다음 형식의 배포 ID가 포함됩니다.
    {
        "deploymentId": "d-RPCR1U3TW"
    }
    
  2. get-deployment-target 명령을 사용해 이전 출력의 deploymentId 를 지정해 배포의 세부 정보를 가져옵니다.
    aws deploy get-deployment-target \
        --deployment-id "d-IMJU3A8TW" \
        --target-id tutorial-bluegreen-cluster:service-bluegreen \
        --region us-east-1
    
  3. 다음 출력에서처럼 상태가 Succeeded 가 될 때까지 배포 세부 정보를 계속 검색합니다.
    {
        "deploymentTarget": {
            "deploymentTargetType": "ECSTarget",
            "ecsTarget": {
                "deploymentId": "d-RPCR1U3TW",
                "targetId": "tutorial-bluegreen-cluster:service-bluegreen",
                "targetArn": "arn:aws:ecs:region:aws_account_id:service/tutorial-bluegreen-cluster/service-bluegreen",
                "lastUpdatedAt": 1543431490.226,
                "lifecycleEvents": [
                    {
                        "lifecycleEventName": "BeforeInstall",
                        "startTime": 1543431361.022,
                        "endTime": 1543431361.433,
                        "status": "Succeeded"
                    },
                    {
                        "lifecycleEventName": "Install",
                        "startTime": 1543431361.678,
                        "endTime": 1543431485.275,
                        "status": "Succeeded"
                    },
                    {
                        "lifecycleEventName": "AfterInstall",
                        "startTime": 1543431485.52,
                        "endTime": 1543431486.033,
                        "status": "Succeeded"
                    },
                    {
                        "lifecycleEventName": "BeforeAllowTraffic",
                        "startTime": 1543431486.838,
                        "endTime": 1543431487.483,
                        "status": "Succeeded"
                    },
                    {
                        "lifecycleEventName": "AllowTraffic",
                        "startTime": 1543431487.748,
                        "endTime": 1543431488.488,
                        "status": "Succeeded"
                    },
                    {
                        "lifecycleEventName": "AfterAllowTraffic",
                        "startTime": 1543431489.152,
                        "endTime": 1543431489.885,
                        "status": "Succeeded"
                    }
                ],
                "status": "Succeeded",
                "taskSetsInfo": [
                    {
                        "identifer": "ecs-svc/9223370493425779968",
                        "desiredCount": 1,
                        "pendingCount": 0,
                        "runningCount": 1,
                        "status": "ACTIVE",
                        "trafficWeight": 0.0,
                        "targetGroup": {
                            "name": "bluegreentarget1"
                        }
                    },
                    {
                        "identifer": "ecs-svc/9223370493423413672",
                        "desiredCount": 1,
                        "pendingCount": 0,
                        "runningCount": 1,
                        "status": "PRIMARY",
                        "trafficWeight": 100.0,
                        "targetGroup": {
                            "name": "bluegreentarget2"
                        }
                    }
                ]
            }
        }
    }
    

7단계: 정리 이 튜토리얼을 완료했으면 이와 관련된 리소스를 정리해 사용하지 않는 리소스에 대한 요금이 발생하지 않도록 해 주세요.

튜토리얼 리소스 정리

  1. delete-deployment-group 명령을 사용해 CodeDeploy 배포 그룹을 삭제합니다.
    aws deploy delete-deployment-group \
        --application-name tutorial-bluegreen-app \
        --deployment-group-name tutorial-bluegreen-dg \
        --region us-east-1
    
  2. delete-application 명령을 사용해 CodeDeploy 애플리케이션을 삭제합니다.
    aws deploy delete-application \
        --application-name tutorial-bluegreen-app \
        --region us-east-1
    
  3. delete-service 명령을 사용해 Amazon ECS 서비스를 삭제합니다. --force 플래그를 사용하면 태스크 0개로 확장되지 않은 경우에도 서비스를 삭제할 수 있습니다.
    aws ecs delete-service \
        --service arn:aws:ecs:region:aws_account_id:service/tutorial-bluegreen-cluster/service-bluegreen \
        --force \
        --region us-east-1
    
  4. delete-cluster 명령을 사용해 Amazon ECS 클러스터를 삭제합니다.
    aws ecs delete-cluster \
        --cluster tutorial-bluegreen-cluster \
        --region us-east-1
    
  5. s3 rm 명령을 사용해 Amazon S3 버킷에서 AppSpec 파일을 삭제합니다.
    aws s3 rm s3://tutorial-bluegreen-bucket/appspec.yaml
    
  6. s3 rb 명령을 사용해 Amazon S3 버킷을 삭제합니다.
    aws s3 rb s3://tutorial-bluegreen-bucket
    
  7. delete-load-balancer 명령을 사용해 Application Load Balancer를 삭제합니다.
    aws elbv2 delete-load-balancer \
        --load-balancer-arn arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642 \
        --region us-east-1
    
  8. delete-target-group 명령을 사용해 두 Application Load Balancer 대상 그룹을 삭제합니다.
    aws elbv2 delete-target-group \
        --target-group-arn arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4 \
        --region us-east-1
    
    aws elbv2 delete-target-group \
        --target-group-arn arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget2/708d384187a3cfdc \
        --region us-east-1
    

더 알아보기 (Learn more)