使用蓝/绿部署创建服务 - Amazon Elastic Container Service

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用蓝/绿部署创建服务

以下教程说明如何创建一个 Amazon ECS 服务,该服务包含一个将蓝/绿部署类型与 AWS CLI结合使用的 Fargate 任务。

注意

为 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。指定两个不属于同一可用区的子网以及一个安全组。

    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 网络模式。以下为用于本教程的示例任务定义。

首先,使用以下内容创建名为 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'

在 Web 浏览器中,输入 DNS 名称,您应该可以看到以蓝色背景显示示例应用程序的网页。

步骤 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命令创建第二个 Application Load Balancer 目标组,该目标组将在创建 CodeDeploy 部署组时使用。

    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。有关更多信息,请参阅 亚马逊 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. 使用 s 3 mb 命令为 AppSpec 文件创建 Amazon S3 存储桶。

      aws s3 mb s3://tutorial-bluegreen-bucket
    3. 使用 s 3 cp 命令将 AppSpec 文件上传到亚马逊 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 名称所在的 Web 浏览器仍会以蓝色背景显示示例应用程序。

    {
    "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 名称的 Web 浏览器,现在您应该会看到绿色背景的示例应用程序。

    {
    "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 标记,您可以删除服务,即使它尚未缩减至 0 个任务。

    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. 使用 s 3 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