教程:使用 Amazon ECR 源和 ECS 目标部署创建管道 CodeDeploy - Amazon CodePipeline
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

教程:使用 Amazon ECR 源和 ECS 目标部署创建管道 CodeDeploy

在本教程中,您将配置一个管道, Amazon CodePipeline 该管道使用支持 Docker 映像的蓝/绿部署部署来部署容器应用程序。在蓝/绿部署中,您可以在运行旧版本应用程序的同时启动新版本应用程序,并在重新路由流量之前测试新版本。您还可以监控部署流程并且在存在问题的情况下迅速回滚。

注意

本教程适用于 Amazon ECS 的 CodeDeploy 蓝/绿部署操作。 CodePipeline有关使用中的 Amazon ECS 标准部署操作的教程 CodePipeline,请参阅教程:使用 Amazon ECS 标准部署 CodePipeline

已完成的管道会检测您的映像的更改,该图像存储在映像存储库(例如 Amazon ECR)中,并用于 CodeDeploy 将流量路由和部署到 Amazon ECS 集群和负载均衡器。 CodeDeploy 使用侦听器将流量重新路由到 AppSpec 文件中指定的已更新容器的端口。如需了解如何在蓝绿部署中使用负载均衡器、生产侦听器、目标组和 Amazon ECS 应用程序,请参阅教程:部署 Amazon ECS 服务

管道还配置为使用存储您的 Amazon ECS 任务定义的源位置,例如。 CodeCommit在本教程中,您将配置这些 Amazon 资源中的每一个,然后创建包含每种资源操作的阶段的管道。

在源代码发生更改时或者新基本映像上传到 Amazon ECR 时,您的持续交付管道将自动构建和部署容器映像。

此流程使用以下项目:

  • 一个 Docker 映像文件,该文件指定容器名称和 Amazon ECR 映像存储库的存储库 URI。

  • 一个 Amazon ECS 任务定义,该定义列出您的 Docker 映像名称、容器名称、Amazon ECS 服务名称和负载均衡器配置。

  • 一个 CodeDeploy AppSpec 文件,它指定 Amazon ECS 任务定义文件的名称、更新的应用程序容器的名称以及 CodeDeploy重新路由生产流量的容器端口。它还可以指定可选的网络配置以及您在部署生命周期事件挂钩期间可运行的 Lambda 函数。

注意

当您把更改提交到 Amazon ECR 映像存储库时,管道源操作会为该提交创建 imageDetail.json 文件。有关 imageDetail.json 文件的信息,请参阅适用于 Amazon ECS 蓝绿部署的 imageDetail.json 文件

在创建或编辑管道和更新或指定部署阶段更新或指定源项目时,请确保指向要使用的带最新名称和版本的源项目。在设置管道后,在对映像或任务定义进行更改时,您可能需要更新存储库中的源项目文件,然后在管道中编辑部署阶段。

先决条件

您必须已创建以下资源:

  • 存储 CodeCommit 库。您可以使用您在中创建的 Amazon CodeCommit 存储库教程:创建简单的管道(CodeCommit存储库)

  • 启动 Amazon EC2 Linux 实例并安装 Docker 以创建映像,如本教程中所示。如果您已有要使用的映像,则可以跳过此先决条件。

步骤 1:创建映像并推送至 Amazon ECR 存储库

在本节中,您将使用 Docker 创建映像,然后使用创建 Amazon ECR 存储库并将该映像推送到存储库。 Amazon CLI

注意

如果您已有要使用的映像,则可以跳过此步骤。

创建映像
  1. 登录到已安装 Docker 的 Linux 实例。

    下拉 nginx 的映像。此命令提供 nginx:latest 映像:

    docker pull nginx
  2. 运行 docker images。您将在列表中看到该映像。

    docker images
创建 Amazon ECR 存储库并推送映像
  1. 创建用于存储您的 映像的 Amazon ECR 存储库。记下输出中的 repositoryUri

    aws ecr create-repository --repository-name nginx

    输出:

    { "repository": { "registryId": "aws_account_id", "repositoryName": "nginx", "repositoryArn": "arn:aws:ecr:us-east-1:aws_account_id:repository/nginx", "createdAt": 1505337806.0, "repositoryUri": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/nginx" } }
  2. 使用上一步中的 repositoryUri 值标记映像。

    docker tag nginx:latest aws_account_id.dkr.ecr.us-east-1.amazonaws.com/nginx:latest
  3. 运行 aws ecr get-login-password 命令,如 us-west-2 区域和 111122223333 账户 ID 的此示例中所示。

    aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-west-2.amazonaws.com/nginx
  4. 使用上一步中的 repositoryUri 将映像推送至 Amazon ECR。

    docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/nginx:latest

第 2 步:创建任务定义和 AppSpec 源文件并推送到 CodeCommit 存储库

在此部分中,您将创建一个任务定义 JSON 文件并将该文件注册到 Amazon ECS。然后,您可以为创建 AppSpec 文件 CodeDeploy 并使用 Git 客户端将这些文件推送到您的 CodeCommit 存储库。

为您的映像创建任务定义
  1. 使用以下内容创建名为 taskdef.json 的文件。对于 image,输入您的映像名称,如 nginx。此值会在管道运行时进行更新。

    注意

    请确保在任务定义中指定的执行角色包含 AmazonECSTaskExecutionRolePolicy。有关更多信息,请参阅 Amazon ECS 开发者指南 中的 Amazon ECS 任务执行 IAM 角色

    { "executionRoleArn": "arn:aws:iam::account_ID:role/ecsTaskExecutionRole", "containerDefinitions": [ { "name": "sample-website", "image": "nginx", "essential": true, "portMappings": [ { "hostPort": 80, "protocol": "tcp", "containerPort": 80 } ] } ], "requiresCompatibilities": [ "FARGATE" ], "networkMode": "awsvpc", "cpu": "256", "memory": "512", "family": "ecs-demo" }
  2. 使用 taskdef.json 文件注册任务定义。

    aws ecs register-task-definition --cli-input-json file://taskdef.json
  3. 注册任务定义后,编辑您的文件以删除映像名称并将 <IMAGE1_NAME> 占位符文本包含在映像字段中。

    { "executionRoleArn": "arn:aws:iam::account_ID:role/ecsTaskExecutionRole", "containerDefinitions": [ { "name": "sample-website", "image": "<IMAGE1_NAME>", "essential": true, "portMappings": [ { "hostPort": 80, "protocol": "tcp", "containerPort": 80 } ] } ], "requiresCompatibilities": [ "FARGATE" ], "networkMode": "awsvpc", "cpu": "256", "memory": "512", "family": "ecs-demo" }
创建 AppSpec 文件
  • 该 AppSpec 文件用于 CodeDeploy 部署。该文件(包含可选字段)使用以下格式:

    version: 0.0 Resources: - TargetService: Type: AWS::ECS::Service Properties: TaskDefinition: "task-definition-ARN" LoadBalancerInfo: ContainerName: "container-name" ContainerPort: container-port-number # Optional properties PlatformVersion: "LATEST" NetworkConfiguration: AwsvpcConfiguration: Subnets: ["subnet-name-1", "subnet-name-2"] SecurityGroups: ["security-group"] AssignPublicIp: "ENABLED" Hooks: - BeforeInstall: "BeforeInstallHookFunctionName" - AfterInstall: "AfterInstallHookFunctionName" - AfterAllowTestTraffic: "AfterAllowTestTrafficHookFunctionName" - BeforeAllowTraffic: "BeforeAllowTrafficHookFunctionName" - AfterAllowTraffic: "AfterAllowTrafficHookFunctionName"

    有关该 AppSpec 文件的更多信息(包括示例),请参阅CodeDeploy AppSpec 文件引用

    使用以下内容创建名为 appspec.yaml 的文件。对于 TaskDefinition,请勿更改 <TASK_DEFINITION> 占位符文本。此值会在管道运行时进行更新。

    version: 0.0 Resources: - TargetService: Type: AWS::ECS::Service Properties: TaskDefinition: <TASK_DEFINITION> LoadBalancerInfo: ContainerName: "sample-website" ContainerPort: 80
将文件推送到您的 CodeCommit 存储库
  1. 将文件推送或上传到您的 CodeCommit 存储库。这些文件是由 “创建管道” 向导为中部署操作创建的源项目 CodePipeline。您的文件在本地目录中应如下所示:

    /tmp |my-demo-repo |-- appspec.yaml |-- taskdef.json
  2. 选择要用于上传文件的方法:

    1. 在本地计算机上从克隆的存储库使用 Git 命令行:

      1. 将目录更改为本地存储库:

        (For Linux, macOS, or Unix) cd /tmp/my-demo-repo (For Windows) cd c:\temp\my-demo-repo
      2. 运行以下命令以立即暂存您的所有文件:

        git add -A
      3. 运行以下命令以提交带有提交消息的文件:

        git commit -m "Added task definition files"
      4. 运行以下命令将本地存储库中的文件推送到存储 CodeCommit 库:

        git push
    2. 要使用 CodeCommit 控制台上传文件,请执行以下操作:

      1. 打开 CodeCommit 控制台,然后从 “存储库” 列表中选择您的存储库

      2. 选择添加文件,然后选择上传文件

      3. 选择选择文件,然后浏览以找到您的文件。通过输入您的用户名和电子邮件地址来提交更改。选择提交更改

      4. 对要上传的每个文件重复此步骤。

步骤 3:创建您的应用程序负载均衡器和目标组

在此部分中,您将创建一个 Amazon EC2 应用程序负载均衡器。在创建 Amazon ECS 服务时,您可以使用稍后将通过负载均衡器创建的子网名称和目标组值。您可以创建应用程序负载均衡器或网络负载均衡器。负载均衡器必须使用在不同的可用区中具有两个公有子网的 VPC。在这些步骤中,您将确认您的默认 VPC,创建负载均衡器,然后为负载均衡器创建两个目标组。有关更多信息,请参阅您的网络负载均衡器的目标组

验证您的默认 VPC 和公有子网
  1. 登录 Amazon Web Services Management Console 并打开亚马逊 VPC 控制台,网址为 https://console.aws.amazon.com/vpc/

  2. 验证要使用的默认 VPC。在导航窗格中,选择您的 VPC。请注意哪个 VPC 在默认 VPC 列中显示为。这是默认 VPC。它包含可供您选择的默认子网。

  3. 选择子网。选择两个在默认子网列中显示的子网。

    注意

    记下子网 ID。本教程后面将会用到这些 ID。

  4. 选择子网,然后选择描述选项卡。验证要使用的子网是否位于不同的可用区中。

  5. 选择子网,然后选择路由表选项卡。为了验证要使用的每个子网是否为公有子网,请确认网关行包含在路由表中。

创建 Amazon EC2 应用程序负载均衡器
  1. 登录 Amazon Web Services Management Console 并打开亚马逊 EC2 控制台,网址为 https://console.aws.amazon.com/ec2/

  2. 在导航窗格中,选择负载均衡器

  3. 选择 Create Load Balancer(创建负载均衡器)

  4. 选择 Application Load Balancer(应用程序负载均衡器),然后选择 Create(创建)

  5. Name(名称)中,输入负载均衡器的名称。

  6. Scheme(模式)中,选择 internet-facing(面向 internet)

  7. IP 地址类型中,选择 ipv4

  8. 为您的负载均衡器配置两个侦听器端口:

    1. 负载均衡器协议下,选择 HTTP。在负载均衡器端口下,输入 80

    2. 选择添加侦听器

    3. 在第二个侦听器的负载均衡器协议下,选择 HTTP。在 Load Balancer Port(负载均衡器端口)下,输入 8080

  9. 可用区下,在 VPC 中,选择默认 VPC。接下来,选择要使用的两个默认子网。

  10. 选择下一步:配置安全设置

  11. 选择下一步:配置安全组

  12. 选择选择现有安全组,然后记下安全组 ID。

  13. 选择下一步:配置路由

  14. 目标组中,选择新建目标组并配置您的第一个目标组:

    1. 名称中,输入目标组名称(例如,target-group-1)。

    2. Target type(目标类型)中,选择 IP

    3. Protocol(协议)中,选择 HTTP。在 Port(端口)中,输入 80

    4. 选择下一步:注册目标

  15. 选择 Next: Review(下一步:审核),然后选择 Create(创建)

为您的负载均衡器创建第二个目标组
  1. 在预配置您的负载均衡器后,打开 Amazon EC2 控制台。在导航窗格中,选择目标组

  2. 选择创建目标组

  3. Name(名称)中,输入目标组名称(例如,target-group-2)。

  4. Target type(目标类型)中,选择 IP

  5. Protocol(协议)中,选择 HTTP。在 Port(端口)中,输入 8080

  6. VPC 中,选择默认 VPC。

  7. 选择创建

    注意

    要使部署运行,您必须为您的负载均衡器创建了两个目标组。您只需记下第一个目标组的 ARN。在下一步中,此 ARN 将用于 create-service JSON 文件。

更新您的负载均衡器以包含第二个目标组
  1. 打开 Amazon EC2 控制台。在导航窗格中,选择负载均衡器

  2. 选择您的负载均衡器,然后选择侦听器选项卡。选择具有端口 8080 的侦听器,然后选择编辑

  3. 选择转发至旁的铅笔图标。选择您的第二个目标组,然后选择复选标记。选择更新以保存更新。

步骤 4:创建您的 Amazon ECS 集群和服务

在本节中,您将创建一个 Amazon ECS 集群和服务,用于在部署期间 CodeDeploy 路由流量(到 Amazon ECS 集群而不是 EC2 实例)。要创建 Amazon ECS 服务,您必须使用通过负载均衡器创建的子网名称、安全组和目标组值来创建服务。

注意

使用这些步骤创建 Amazon ECS 集群时,您将使用仅限联网的集群模板,该模板预配置 Amazon Fargate 容器。 Amazon Fargate 是一项为您管理容器实例基础设施的技术。您不需要为 Amazon ECS 集群选择或手动创建 Amazon EC2 实例。

要创建 Amazon ECS 集群
  1. 打开 Amazon ECS 经典控制台: https://console.aws.amazon.com/ecs/

  2. 在导航窗格中,选择集群

  3. 选择创建集群

  4. 选择使用 Amazon Fargate 的仅限联网集群模板,然后选择下一步

  5. 配置集群页面上,输入集群名称。您可以为资源添加可选标签。选择创建

创建 Amazon ECS 服务

使用在 Amazon CLI Amazon ECS 中创建您的服务。

  1. 创建一个 JSON 文件并将其命名为 create-service.json。将以下内容粘贴到 JSON 文件中。

    对于 taskDefinition 字段,当您在 Amazon ECS 中注册任务定义时,请提供一个系列。这类似于使用修订号指定的任务定义的多个版本的名称。在此示例中,对文件中的系列和修订号使用“ecs-demo:1”。使用您在步骤 3:创建您的应用程序负载均衡器和目标组 中随负载均衡器创建的子网名称、安全组和目标组值。

    注意

    您需要在此文件中包含您的目标组 ARN。打开 Amazon EC2 控制台,然后在导航窗格中的负载均衡下,选择目标组。选择您的第一个目标组。从描述选项卡复制您的 ARN。

    { "taskDefinition": "family:revision-number", "cluster": "my-cluster", "loadBalancers": [ { "targetGroupArn": "target-group-arn", "containerName": "sample-website", "containerPort": 80 } ], "desiredCount": 1, "launchType": "FARGATE", "schedulingStrategy": "REPLICA", "deploymentController": { "type": "CODE_DEPLOY" }, "networkConfiguration": { "awsvpcConfiguration": { "subnets": [ "subnet-1", "subnet-2" ], "securityGroups": [ "security-group" ], "assignPublicIp": "ENABLED" } } }
  2. 运行 create-service 命令,并指定 JSON 文件:

    重要

    务必在文件名前包含 file://。此命令中需要该项。

    此示例创建一个名为 my-service 的服务。

    注意

    此示例命令创建一个名为 my-service 服务。如果您已有一个具有该名称的服务,则命令会返回错误。

    aws ecs create-service --service-name my-service --cli-input-json file://create-service.json

    输出将返回您的服务的描述字段。

  3. 运行 describe-services 命令以验证是否已创建您的服务。

    aws ecs describe-services --cluster cluster-name --services service-name

步骤 5:创建您的 CodeDeploy应用程序和部署组(ECS 计算平台)

当您为 Amazon ECS 计算平台创建 CodeDeploy 应用程序和部署组时,将在部署期间使用该应用程序来引用正确的部署组、目标组、侦听器和流量重新路由行为。

创建 CodeDeploy 应用程序
  1. 打开 CodeDeploy 控制台并选择创建应用程序

  2. 应用程序名称中,输入要使用的名称。

  3. 计算平台中,选择 Amazon ECS

  4. 选择创建应用程序

创建 CodeDeploy 部署组
  1. 在应用程序页面的部署组选项卡上,选择创建部署组

  2. 部署组名称中,输入一个描述部署组的名称。

  3. 服务角色中,选择一个授予 CodeDeploy对 Amazon ECS 访问权限的服务角色。若要创建新的服务角色,请按照以下步骤操作:

    1. 通过以下网址打开 IAM 控制台:https://console.aws.amazon.com/iam/

    2. 在控制台控制面板中,选择角色

    3. 选择创建角色

    4. 选择受信任实体的类型下,选择 Amazon Web Service。在 “选择用例” 下,选择CodeDeploy。在 “选择您的用例” 下,选择 CodeDeploy -ECS。选择下一步:权限AWSCodeDeployRoleForECS 托管策略已附加到角色。

    5. 选择下一步:标签,然后选择下一步:审核

    6. 输入角色的名称(例如 CodeDeployECSRole),然后选择创建角色

  4. 环境配置中,选择 Amazon ECS 集群名称和服务名称。

  5. 负载均衡器中,选择将流量提供给 Amazon ECS 服务的负载均衡器的名称。

  6. 生产侦听器端口中,选择将生产流量路由至您的 Amazon ECS 服务的侦听器的端口和协议。在测试侦听器端口中,选择测试侦听器的端口和协议。

  7. 目标组 1 名称目标组 2 名称中,选择用于在部署期间路由流量的目标组。请确保它们是您为负载均衡器创建的目标组。

  8. 选择立即重新路由流量以确定成功部署后将流量重新路由到更新后的 Amazon ECS 任务的时长。

  9. 选择 Create deployment group(创建部署组)

步骤 6:创建管道

在此部分中,您将使用以下操作创建管道:

  • 一种 CodeCommit 操作,其中源对象是任务定义和 AppSpec 文件。

  • 一个带 Amazon ECR 源操作的源阶段,其中源构件是映像文件。

  • 具有 Amazon ECS 部署操作的部署阶段,其中部署与 CodeDeploy 应用程序和部署组一起运行。

使用向导创建两阶段管道
  1. 登录 Amazon Web Services Management Console 并打开 CodePipeline 控制台,网址为 http://console.aws.amazon.com/codesuite/codepipeline/home

  2. 欢迎页面、入门页面或管道页面上,选择创建管道

  3. 步骤 1:选择管道设置管道名称中,输入 MyImagePipeline

  4. 在本教程中,为管道类型选择 V1。也可以选择 V2;但请注意,不同管道类型具有不同的特性和价格。有关更多信息,请参阅 管道类型

  5. 服务角色中,选择新建服务角色 CodePipeline以允许在 IAM 中创建服务角色。

  6. 高级设置中的各项设置保留为默认值,然后选择下一步

  7. 步骤 2:添加源阶段源提供程序中,选择 Amazon CodeCommit。在存储库名称中,选择您在中创建的 CodeCommit存储库的名称步骤 1:创建 CodeCommit 存储库。在分支名称中,选择包含最新的代码更新的分支的名称。

    选择下一步

  8. 步骤 3:添加构建阶段中,选择跳过构建阶段,并通过再次选择跳过接受警告消息。选择下一步

  9. 步骤 4:添加部署阶段中:

    1. 部署提供商中,选择 Amazon ECS(蓝/绿)。在应用程序名称中,输入应用程序名称或从列表中选择应用程序名称,例如 codedeployapp。在部署组中,输入部署组名称或从列表中选择部署组名称,例如 codedeploydeplgroup

      注意

      名称“Deploy”是在 步骤 4:部署步骤中创建的阶段的默认名称,正如“Source”是管道第一阶段的名称一样。

    2. Amazon ECS 任务定义下,选择SourceArtifact。在字段中,输入 taskdef.json

    3. 在 “Amazon CodeDeploy AppSpec 文件” 下,选择SourceArtifact。在字段中,输入 appspec.yaml

      注意

      此时,请不要在动态更新任务定义映像下填写任何信息。

    4. 选择下一步

  10. 步骤 5:审核中,查看信息,然后选择创建管道

向管道添加 Amazon ECR 源操作

查看您的管道并向其添加 Amazon ECR 源操作。

  1. 选择您的管道。在左上方,选择编辑

  2. 在源阶段中,选择编辑阶段

  3. 选择 CodeCommit 源操作旁边的 + 添加动作,即可添加并行动作。

  4. 操作名称中,输入名称(例如 Image)。

  5. 操作提供程序中,选择 Amazon ECR

    向管道添加 Amazon ECR 源操作。
  6. 存储库名称中,选择 Amazon ECR 存储库的名称。

  7. 映像标签中,指定映像名称和版本(如果与最新版本不同)。

  8. 输出构件中,选择默认输出构件(例如 MyImage),其中包含您希望下一阶段使用的映像名称和存储库 URI 信息。

  9. 在操作屏幕上选择保存。在阶段屏幕上选择完成。在管道上选择保存。一条消息显示了要为 Amazon CloudWatch ECR 源操作创建的 Amazon Events 规则。

将您的源构件连接到部署操作
  1. 在部署阶段上选择编辑,然后选择图标以编辑 Amazon ECS(蓝色/绿色)操作。

  2. 滚动到窗格底部。在输入项目中,选择添加。从您的新 Amazon ECR 存储库(例如,MyImage)添加源构件。

  3. 在 “任务定义” 中 SourceArtifact,选择,然后输入验证taskdef.json

  4. Amazon CodeDeploy AppSpec 文件SourceArtifact,选择,然后输入验证appspec.yaml信息。

  5. 动态更新任务定义图像中,在带图像 URI 的 Input Ar tifact 中 MyImage,选择,然后输入taskdef.json文件中使用的占位符文本: IMAGE1_NAME。选择保存

  6. 在 Amazon CodePipeline 窗格中,选择 “保存管道更改”,然后选择 “保存更改”。查看已更新的管道。

    创建此示例管道后,控制台条目的操作配置按如下所示在管道结构中显示:

    "configuration": { "AppSpecTemplateArtifact": "SourceArtifact", "AppSpecTemplatePath": "appspec.yaml", "TaskDefinitionTemplateArtifact": "SourceArtifact", "TaskDefinitionTemplatePath": "taskdef.json", "ApplicationName": "codedeployapp", "DeploymentGroupName": "codedeploydeplgroup", "Image1ArtifactName": "MyImage", "Image1ContainerName": "IMAGE1_NAME" },
  7. 要提交所做的更改并开始管道构建,请选择发布更改,然后选择发布

  8. 选择要查看的部署操作 CodeDeploy 并查看流量转移的进度。

    注意

    您可能会看到一个部署步骤,显示可选的等待时间。默认情况下,在成功部署后 CodeDeploy 等待一小时才终止原始任务集。您可以利用此时间回滚或终止任务,但在任务集终止时,您的部署也会完成。

步骤 7:对您的管道进行更改并验证部署

对您的映像进行更改,然后将更改推送至您的 Amazon ECR 存储库。这将触发您的管道运行。验证是否已部署您的映像源更改。