블루/그린 배포를 사용하여 Amazon ECS 서비스 배포 - Amazon Elastic Container Service

블루/그린 배포를 사용하여 Amazon ECS 서비스 배포

AWS CLI를 사용하여 블루/그린 배포 유형을 사용하는 Fargate 태스크가 포함된 Amazon ECS 서비스를 생성하는 방법을 알아보세요.

참고

AWS CloudFormation에 블루/그린 배포 수행에 대한 지원이 추가되었습니다. 자세한 정보는 AWS CloudFormation 사용 설명서AWS CloudFormation을 사용하여 CodeDeploy를 통한 Amazon ECS 블루/그린 배포 수행을 참조하세요.

필수 조건

이 자습서에서는 다음 사전 조건이 충족되었다고 가정합니다.

1단계: Application Load Balancer 생성

블루/그린 배포 유형을 사용하는 Amazon ECS 서비스에서는 Application Load Balancer 또는 Network Load Balancer 중 하나를 사용해야 합니다. 이 자습서에서는 Application Load Balancer를 사용합니다.

Application Load Balancer를 생성하려면
  1. create-load-balancer 명령을 사용하여 Application Load Balancer를 생성합니다. 속해 있는 보안 그룹과 가용 영역이 다른 서브넷 2개를 지정합니다.

    aws elbv2 create-load-balancer \ --name bluegreen-alb \ --subnets subnet-abcd1234 subnet-abcd5678 \ --security-groups sg-abcd1234 \ --region us-east-1

    출력에는 다음 형식과 함께 로드 밸런서의 Amazon 리소스 이름(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 네트워크 모드를 사용해야 합니다. 다음은 이 자습서에서 사용된 태스크 정의 예제입니다.

먼저, 다음 내용으로 이름이 fargate-task.json인 파일을 생성합니다. 작업 실행 역할에 ARN을 사용해야 합니다. 자세한 정보는 Amazon ECS 태스크 실행 IAM 역할 섹션을 참조하세요.

{ "family": "tutorial-task-def", "networkMode": "awsvpc", "containerDefinitions": [ { "name": "sample-app", "image": "httpd:2.4", "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: #00FFFF;} </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", "executionRoleArn": "arn:aws:iam::aws_account_id:role/ecsTaskExecutionRole" }

그런 다음, 생성한 fargate-task.json 파일을 사용하여 태스크 정의를 등록합니다.

aws ecs register-task-definition \ --cli-input-json file://fargate-task.json \ --region us-east-1

4단계: Amazon ECS 서비스 생성

create-service 명령을 사용하여 서비스를 생성합니다.

먼저, 다음 내용으로 이름이 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 }

그런 다음, 생성한 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/service-bluegreen

다음 명령을 사용하여 로드 밸런서의 DNS 이름을 가져옵니다.

aws elbv2 describe-load-balancers --name bluegreen-alb --query 'LoadBalancers[*].DNSName'

웹 브라우저에 DNS 이름을 입력하면 파랑 배경에 sample 앱이 표시되는 웹 페이지가 보입니다.

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 배포 그룹을 생성할 때 사용할 2차 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 역할 섹션을 참조하세요.

    { "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" } ] }

    그런 다음, 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 배포 생성 및 모니터링

CodeDeploy 배포를 생성하기 전에 fargate-task.json의 작업 정의 command를 다음과 같이 업데이트하여 샘플 앱 배경색을 녹색으로 변경합니다.

{ ... "containerDefinitions": [ { ... "command": [ "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #097969;} </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\"" ] } ], ... }

다음 명령을 실행하여 업데이트한 작업 정의를 등록합니다.

aws ecs register-task-definition \ --cli-input-json file://fargate-task.json \ --region us-east-1

이제 다음 단계를 사용하여 애플리케이션 사양 파일(AppSpec 파일)과 CodeDeploy 배포를 생성하고 업로드합니다.

CodeDeploy 배포를 생성하고 모니터링하려면
  1. 다음 단계를 사용하여 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/tutorial-task-def:2" 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
  2. 다음 단계를 사용하여 CodeDeploy 배포를 생성합니다.

    1. 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" } } }
    2. create-deployment 명령을 사용하여 배포를 생성합니다.

      aws deploy create-deployment \ --cli-input-json file://create-deployment.json \ --region us-east-1

      출력에는 다음 형식의 배포 ID가 포함됩니다.

      {
          "deploymentId": "d-RPCR1U3TW"
      }
  3. get-deployment-target 명령을 사용하여 배포의 세부 정보를 가져와 이전 출력의 deploymentId를 지정합니다.

    aws deploy get-deployment-target \ --deployment-id "d-IMJU3A8TW" \ --target-id tutorial-bluegreen-cluster:service-bluegreen \ --region us-east-1

    초기 배포 상태는 InProgress입니다. 트래픽은 taskSetLabelBLUE, 상태가 PRIMARY, trafficWeight100.0인 원래 작업 세트로 전달됩니다. 대체 작업 세트는 taskSetLabelGREEN, 상태가 ACTIVE, trafficWeight0.0입니다. DNS 이름을 입력한 웹 브라우저에는 여전히 파란색 배경의 샘플 앱이 표시됩니다.

    {
    "deploymentTarget": {
    "deploymentTargetType": "ECSTarget",
    "ecsTarget": {
        "deploymentId": "d-RPCR1U3TW",
        "targetId": "tutorial-bluegreen-cluster:service-bluegreen",
        "targetArn": "arn:aws:ecs:region:aws_account_id:service/service-bluegreen",
        "lastUpdatedAt": "2023-08-10T12:07:24.797000-05:00",
        "lifecycleEvents": [
            {
                "lifecycleEventName": "BeforeInstall",
                "startTime": "2023-08-10T12:06:22.493000-05:00",
                "endTime": "2023-08-10T12:06:22.790000-05:00",
                "status": "Succeeded"
            },
            {
                "lifecycleEventName": "Install",
                "startTime": "2023-08-10T12:06:22.936000-05:00",
                "status": "InProgress"
            },
            {
                "lifecycleEventName": "AfterInstall",
                "status": "Pending"
            },
            {
                "lifecycleEventName": "BeforeAllowTraffic",
                "status": "Pending"
            },
            {
                "lifecycleEventName": "AllowTraffic",
                "status": "Pending"
            },
            {
                "lifecycleEventName": "AfterAllowTraffic",
                "status": "Pending"
            }
        ],
        "status": "InProgress",
        "taskSetsInfo": [
            {
                "identifer": "ecs-svc/9223370493423413672",
                "desiredCount": 1,
                "pendingCount": 0,
                "runningCount": 1,
                "status": "ACTIVE",
                "trafficWeight": 0.0,
                "targetGroup": {
                    "name": "bluegreentarget2"
                },
                "taskSetLabel": "Green"
            },
            {
                "identifer": "ecs-svc/9223370493425779968",
                "desiredCount": 1,
                "pendingCount": 0,
                "runningCount": 1,
                "status": "PRIMARY",
                "trafficWeight": 100.0,
                "targetGroup": {
                    "name": "bluegreentarget1"
                },
                "taskSetLabel": "Blue"
            }
        ]
    }
    }
    }

    다음 출력처럼 배포 상태가 Succeeded가 될 때까지 명령을 사용하여 배포 세부 정보를 계속 가져옵니다. 이제 트래픽이 대체 작업 세트로 리디렉션되며, 대체 작업 세트는 현재 PRIMARY 상태이고 trafficWeight100.0입니다. 로드 밸런서 DNS 이름을 입력한 웹 브라우저를 새로 고치면 녹색 배경의 샘플 앱이 표시됩니다.

    {
    "deploymentTarget": {
    "deploymentTargetType": "ECSTarget",
    "ecsTarget": {
        "deploymentId": "d-RPCR1U3TW",
        "targetId": "tutorial-bluegreen-cluster:service-bluegreen",
        "targetArn": "arn:aws:ecs:region:aws_account_id:service/service-bluegreen",
        "lastUpdatedAt": "2023-08-10T12:07:24.797000-05:00",
        "lifecycleEvents": [
            {
                "lifecycleEventName": "BeforeInstall",
                "startTime": "2023-08-10T12:06:22.493000-05:00",
                "endTime": "2023-08-10T12:06:22.790000-05:00",
                "status": "Succeeded"
            },
            {
                "lifecycleEventName": "Install",
                "startTime": "2023-08-10T12:06:22.936000-05:00",
                "endTime": "2023-08-10T12:08:25.939000-05:00",
                "status": "Succeeded"
            },
            {
                "lifecycleEventName": "AfterInstall",
                "startTime": "2023-08-10T12:08:26.089000-05:00",
                "endTime":  "2023-08-10T12:08:26.403000-05:00",
                "status": "Succeeded"
            },
            {
                "lifecycleEventName": "BeforeAllowTraffic",
                "startTime": "2023-08-10T12:08:26.926000-05:00",
                "endTime":  "2023-08-10T12:08:27.256000-05:00",
                "status": "Succeeded"
            },
            {
                "lifecycleEventName": "AllowTraffic",
                "startTime": "2023-08-10T12:08:27.416000-05:00",
                "endTime": "2023-08-10T12:08:28.195000-05:00",
                "status": "Succeeded"
            },
            {
                "lifecycleEventName": "AfterAllowTraffic",
                "startTime": "2023-08-10T12:08:28.715000-05:00",
                "endTime":  "2023-08-10T12:08:28.994000-05:00",
                "status": "Succeeded"
            }
        ],
        "status": "Succeeded",
        "taskSetsInfo": [
            {
                "identifer": "ecs-svc/9223370493425779968",
                "desiredCount": 1,
                "pendingCount": 0,
                "runningCount": 1,
                "status": "ACTIVE",
                "trafficWeight": 0.0,
                "targetGroup": {
                    "name": "bluegreentarget1"
                },
                "taskSetLabel": "Blue"
            },
            {
                "identifer": "ecs-svc/9223370493423413672",
                "desiredCount": 1,
                "pendingCount": 0,
                "runningCount": 1,
                "status": "PRIMARY",
                "trafficWeight": 100.0,
                "targetGroup": {
                    "name": "bluegreentarget2"
                },
                "taskSetLabel": "Green"
            }
        ]
    }
    }
    }

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 플래그를 사용하면 작업이 없는 상태로 축소되지 않은 서비스도 삭제할 수 있습니다.

    aws ecs delete-service \ --service arn:aws:ecs:region:aws_account_id:service/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