View a markdown version of this page

教程:使用 Amazon ECR 源和 ECS-to-CodeDeploy 部署创建管道 - AWS CodePipeline

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

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

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

重要

作为创建管道的一部分,客户提供的 S3 工件存储桶将用于存放 CodePipeline 工件。(这与用于 S3 源操作的存储桶不同。) 如果 S3 项目存储桶与您的管道账户位于不同的账户中,请确保 S3 工件存储桶归安全且可靠的账户所有。 AWS 账户

注意

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

完成的管道会检测您的映像的更改,映像存储在 Amazon ECR 等镜像存储库中,用于 CodeDeploy 将流量路由和部署到 Amazon ECS 集群和负载均衡器。 CodeDeploy 使用侦听器将流量重新路由到 AppSpec 文件中指定的更新容器的端口。有关如何在 blue/green 部署中使用负载均衡器、生产侦听器、目标组和您的 Amazon ECS 应用程序的信息,请参阅教程:部署 Amazon ECS 服务

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

在源代码发生更改时或者新基本映像上传到 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 blue/green 部署操作的图像Detail.json 文件

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

先决条件

您必须已创建以下资源:

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

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

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

在本节中,您将使用 Docker 创建镜像,然后使用创建 Amazon ECR 存储库并将该映像推送到存储库。 AWS 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. 登录 AWS 管理控制台 并打开亚马逊 VPC 控制台,网址为https://console.aws.amazon.com/vpc/

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

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

    注意

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

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

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

创建 Amazon EC2 应用程序负载均衡器
  1. 登录 AWS 管理控制台 并打开亚马逊 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。