教程:使用 CodePipeline 进行 Amazon ECS 标准部署
本教程帮助您通过将 Amazon ECS 与 CodePipeline 结合使用,从而创建一个完整的端到端持续部署 (CD) 管道。
重要
作为在控制台中创建管道的一部分,CodePipeline 将使用 S3 构件存储桶来存放构件。(这与用于 S3 源操作的存储桶不同。) 如果 S3 构件存储桶所在的账户与您的管道账户不同,请确保 S3 构件存储桶归 Amazon Web Services 账户所有,并且安全可靠。
注意
本教程适用于 CodePipeline 的 Amazon ECS 标准部署操作。有关使用 CodePipeline 中 Amazon ECS 到 CodeDeploy 蓝绿部署操作的教程,请参阅教程:创建包含 Amazon ECR 源和 ECS 至 CodeDeploy 部署的管道。
注意
本教程适用于包含源操作的 CodePipeline 的 Amazon ECS 标准部署操作。有关在 CodePipeline 中使用 Amazon ECS 标准部署操作和 ECRBuildAndPublish 构建操作来推送映像的教程,请参阅教程:使用 CodePipeline 构建 Docker 映像并将其推送到 Amazon ECR(V2 类型)。
先决条件
您必须先部署一些资源,然后才能使用本教程创建您的 CD 管道。以下是您在开始操作之前需要的资源:
注意
所有这些资源均应在同一 Amazon 区域内创建。
-
一个包含您的 Dockerfile 和应用程序源的源控制存储库(本教程使用 CodeCommit)。有关更多信息,请参阅 Amazon CodeCommit 用户指南 中的创建 CodeCommit 存储库。
-
一个 Docker 映像存储库(本教程使用 Amazon ECR),其中包含您从 Dockerfile 和应用程序源构建的映像。有关更多信息,请参阅 Amazon Elastic Container Registry 用户指南 中的创建存储库和推送映像。
-
一个 Amazon ECS 任务定义,该定义会引用在您的映像存储库中托管的 Docker 映像。有关更多信息,请参阅 Amazon Elastic Container Service 开发者指南 中的创建任务定义。
重要
CodePipeline 的 Amazon ECS 标准部署操作会根据 Amazon ECS 服务使用的任务定义修订,创建自己的修订。如果您在不更新 Amazon ECS 服务的情况下为任务定义创建新的修订,则部署操作将忽略这些修订。
以下是本教程中使用的一个任务定义示例。您对
name和family使用的值将在下一步中用于构建规范文件。{ "ipcMode": null, "executionRoleArn": "role_ARN", "containerDefinitions": [ { "dnsSearchDomains": null, "environmentFiles": null, "logConfiguration": { "logDriver": "awslogs", "secretOptions": null, "options": { "awslogs-group": "/ecs/hello-world", "awslogs-region": "us-west-2", "awslogs-stream-prefix": "ecs" } }, "entryPoint": null, "portMappings": [ { "hostPort": 80, "protocol": "tcp", "containerPort": 80 } ], "command": null, "linuxParameters": null, "cpu": 0, "environment": [], "resourceRequirements": null, "ulimits": null, "dnsServers": null, "mountPoints": [], "workingDirectory": null, "secrets": null, "dockerSecurityOptions": null, "memory": null, "memoryReservation": 128, "volumesFrom": [], "stopTimeout": null, "image": "image_name", "startTimeout": null, "firelensConfiguration": null, "dependsOn": null, "disableNetworking": null, "interactive": null, "healthCheck": null, "essential": true, "links": null, "hostname": null, "extraHosts": null, "pseudoTerminal": null, "user": null, "readonlyRootFilesystem": null, "dockerLabels": null, "systemControls": null, "privileged": null, "name": "hello-world" } ], "placementConstraints": [], "memory": "2048", "taskRoleArn": null, "compatibilities": [ "EC2", "FARGATE" ], "taskDefinitionArn": "ARN", "family": "hello-world", "requiresAttributes": [], "pidMode": null, "requiresCompatibilities": [ "FARGATE" ], "networkMode": "awsvpc", "cpu": "1024", "revision": 1, "status": "ACTIVE", "inferenceAccelerators": null, "proxyConfiguration": null, "volumes": [] } -
一个 Amazon ECS 集群,该集群运行着一项使用前述任务定义的服务。有关更多信息,请参阅 Amazon Elastic Container Service 开发者指南 中的创建集群和创建服务。
在满足这些先决条件后,您可以继续完成本教程并创建您的 CD 管道。
步骤 1:将构建规范文件添加至您的源存储库
本教程将使用 CodeBuild 构建您的 Docker 映像并将该映像推送至 Amazon ECR。将 buildspec.yml 文件添加至您的源代码存储库以指示 CodeBuild 如何执行此操作。下面的示例构建规范将执行以下操作:
-
构建前阶段:
-
登录 Amazon ECR。
-
将存储库 URI 设置为您的 ECR 映像并添加包含源的 Git 提交 ID 的前七个字符的映像标签。
-
-
构建阶段:
-
构建 Docker 映像并使用 Git 提交 ID 将该映像标记为
latest。
-
-
构建后阶段:
-
使用两个标签将该映像推送至 ECR 存储库。
-
在根目录中编写一个称为
imagedefinitions.json文件,其中包含您的 Amazon ECS 服务的容器名称以及映像和标签。您的 CD 管道的部署阶段将使用此信息来创建您的服务的任务定义的新修订,然后它会将该服务更新为使用此新任务定义。ECS 作业辅助角色需要imagedefinitions.json文件。
-
粘贴此示例文本以创建您的 buildspec.yml 文件,然后替换映像和任务定义的值。此文本使用示例账户 ID 111122223333。
version: 0.2 phases: pre_build: commands: - echo Logging in to Amazon ECR... - aws --version - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-west-2.amazonaws.com - REPOSITORY_URI=012345678910.dkr.ecr.us-west-2.amazonaws.com/hello-world - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7) - IMAGE_TAG=${COMMIT_HASH:=latest} build: commands: - echo Build started on `date` - echo Building the Docker image... - docker build -t $REPOSITORY_URI:latest . - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG post_build: commands: - echo Build completed on `date` - echo Pushing the Docker images... - docker push $REPOSITORY_URI:latest - docker push $REPOSITORY_URI:$IMAGE_TAG - echo Writing image definitions file... - printf '[{"name":"hello-world","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json artifacts: files: imagedefinitions.json
构建规范为先决条件中提供的示例任务定义而编写,本教程中的 Amazon ECS 服务使用了该定义。REPOSITORY_URI 值对应于 image 存储库 (没有任何映像标签),此文件末尾附近的 值对应于该服务的任务定义中的容器名称。hello-world
将 buildspec.yml 文件添加至您的源存储库
-
打开文本编辑器,然后将上述构建规范复制并粘贴到新文件中。
-
将
REPOSITORY_URI值 () 替换为您的 Docker 映像的 Amazon ECR 存储库 URI(无任何映像标签)。将012345678910.dkr.ecr.us-west-2.amazonaws.com/hello-world替换为引用您的 Docker 映像的服务的任务定义中的容器名称。hello-world -
提交您的
buildspec.yml文件并将其推送至源存储库。-
添加文件。
git add . -
提交更改。
git commit -m "Adding build specification." -
推送提交。
git push
-
步骤 2:创建持续部署管道
使用 CodePipeline 向导创建您的管道阶段,并将源存储库连接到您的 ECS 服务。
创建管道
在 https://console.aws.amazon.com/codepipeline/ 打开 CodePipeline 控制台。
-
在 Welcome 页面上,选择 Create pipeline。
如果这是您第一次使用 CodePipeline,则会显示一个介绍页面,而不是欢迎页面。选择 Get Started Now (立即开始)。
-
在步骤 1:选择创建选项页面上的创建选项下,选择构建自定义管道选项。选择下一步。
-
在步骤 2:选择管道设置的管道名称中,输入管道的名称。在本教程中,管道名称为 hello-world。
-
在管道类型中,保留默认选择 V2。管道类型有不同的特点和价格。有关更多信息,请参阅 管道类型。选择下一步。
-
在步骤 3:添加源阶段页面上,对于源提供程序,请选择 Amazon CodeCommit。
-
对于存储库名称,请选择要用作管道源位置的 CodeCommit 存储库的名称。
-
对于 Branch name (分支名称),选择要使用的分支,然后选择 Next (下一步)。
-
-
在步骤 4:添加构建阶段页面上,对于构建提供程序,请选择 Amazon CodeBuild,然后选择创建项目。
-
对于 Project name,为您的构建项目选择唯一名称。在本教程中,项目名称为 hello-world。
-
对于环境映像,选择托管映像。
-
对于操作系统,选择 Amazon Linux 2。
-
对于运行时,选择标准。
-
对于映像,请选择
aws/codebuild/amazonlinux2-x86_64-standard:3.0。 -
对于 Image version (映像版本) 和 Environment type (环境类型),请使用默认值。
-
选择如果要构建 Docker 映像或希望您的构建获得提升的特权,请启用此标志。
-
取消选择 CloudWatch logs (CloudWatch 日志)。您可能需要展开高级。
-
选择前往 CodePipeline。
-
选择下一步。
注意
该向导会为您的构建项目创建一个名为 codebuild-
build-project-name-service-role 的 CodeBuild 服务角色。记下此角色名称,因为稍后您要向该角色添加 Amazon ECR 权限。
-
-
在步骤 5:添加部署阶段页面上,对于部署提供程序,请选择 Amazon ECS。
-
对于集群名称,请选择在其中运行您的服务的 Amazon ECS 集群。在本教程中,该集群为 default。
-
对于 Service name (服务名称),选择要更新的服务,然后选择 Next (下一步)。在本教程中,服务名称为 hello-world。
-
-
在 Step 6: Review 页面上,审查您的管道配置,然后选择 Create pipeline 以创建管道。
注意
既然管道已创建好,它将尝试经历不同的管道阶段。但是,由此向导创建的默认 CodeBuild 角色无权执行包含在
buildspec.yml文件中的所有命令,因此构建阶段失败。下一部分将为构建阶段添加权限。
第 3 步:向 CodeBuild 角色添加 Amazon ECR 权限
CodePipeline 向导为 CodeBuild 构建项目创建了一个名为 codebuild-build-project-name-service-role 的 IAM 角色。在本教程中,名称为 codebuild-hello-world-service-role。由于 buildspec.yml 文件会调用 Amazon ECR API 操作,因此该角色必须具有授权进行这些 Amazon ECR 调用的策略。以下过程帮助您将适当权限附加到该角色。
向 CodeBuild 角色添加 Amazon ECR 权限
通过 https://console.aws.amazon.com/iam/ 打开 IAM 控制台。
-
在左侧导航窗格中,选择 角色。
-
在搜索框中,键入 codebuild-,然后选择由 CodePipeline 向导创建的角色。在本教程中,角色名称为 codebuild-hello-world-service-role。
-
在 Summary (摘要) 页面上,选择 Attach policies (附加策略)。
-
选中 AmazonEC2ContainerRegistryPowerUser 策略左侧的框,然后选择 Attach policy。
步骤 4:测试您的管道
您的管道应具有运行端到端本机 Amazon 持续部署所需的一切。现在,通过将代码更改推送至您的源存储库来测试管道的功能。
测试您的管道
-
对您的已配置源存储库进行代码更改,然后提交并推送更改。
在 https://console.aws.amazon.com/codepipeline/ 打开 CodePipeline 控制台。
-
从列表中选择您的管道。
-
监视管道经历不同阶段的进度。您的管道应完成且您的 Amazon ECS 服务运行通过您的代码更改创建的 Docker 映像。