【问题标题】:How can I use AWS CodePipeline to update a container service on ECS如何使用 AWS CodePipeline 更新 ECS 上的容器服务
【发布时间】:2018-05-16 18:12:45
【问题描述】:

我在 ECS 上有一个带有容器服务的集群。我已经设置 CodePipeline 在更新时构建一个新容器并将其推送到 ECR。如何触发对集群的更新以使用新更新的容器?

【问题讨论】:

    标签: amazon-web-services amazon-ec2 amazon-ecs


    【解决方案1】:

    由于您使用的是 CodePipeline,因此您可能会在构建新映像后触发 CloudFromation 堆栈。然后 CloudFormation 堆栈将创建一个新的任务定义并更新您的 ECS 服务。这是一个参考架构。

    您可以使用this 参考架构进行持续部署。 CloudFormation 模板附在上述 Github 存储库中。

    【讨论】:

      【解决方案2】:

      AWS CodePipeline 现在支持直接部署到 ECS。您可以使用新的 ECS 部署操作来更新您的 ECS 服务以使用您创建的新容器映像。您需要修改构建步骤以输出包含您构建的新图像的图像 URL 的配置文件。更多细节可以在这里找到https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-cd-pipeline.html

      【讨论】:

      • 请回答实际问题“如何触发对集群的更新以使用新更新的容器?”在答案本身中。
      • 使用 CodePipeline 时,直接部署到 ECS 和使用 CodeDeploy 部署到 ECS 有什么区别?
      【解决方案3】:

      我想我会用 bitbucket-pipelines 添加我的解决方案,我知道从技术上讲它并不能直接回答这个问题,但是 bitbucket 管道步骤中的命令实际上与 buildspec.yml 相同(尽管请查看 buildspec.yml 的文档)用于代码管道。

      我觉得我应该补充一点,aws 在 aws 控制面板中为 codepiplines 使用 GUI 做得很好,现在它真的很简单,可以为您处理部署和任务定义创建。

      希望将 JIRA 等工具及其部署功能与 JIRA 任务集成的人们需要使用 bitbucket 管道!

      options:
        docker: true
        size: 2x
      
      pipelines:
        tags:
          build-*:
            - step: 
                name: build app
                image: node:10.15.0
                script:
                  - npm i
                  - npm run build
                artifacts:
                  - node_modules/** 
                  - dist/**
      
      
      
           - step:
             name: push to aws staging
             # integrate with JIRA <3
             deployment: staging
             image: atlassian/pipelines-awscli:latest
             services:
               - docker
             script:
               # command line JSON processor plugin (important)
               - apk add jq          
      
               # standard docker login and build
               - eval $(aws ecr get-login --no-include-email)
               - docker build --build-arg notProduction=true -t app:staging .
               - docker tag app:staging ${secretUrl}.amazonaws.com/app:staging
               - docker push ${secretUrl}.amazonaws.com/app:staging
      
               # gets the latest task definition
               - export TASK_DEF=$(aws ecs describe-task-definition --task-definition "app-staging")
      
               # gets the specific containerDefinitions array and exports to a json format which is needed for the register-task-definition function
               - export CONTAINER_DEFS=$(echo $TASK_DEF | jq '.taskDefinition.containerDefinitions' | awk -v ORS= -v OFS= '{$1=$1}1')
      
               # creates a new task definition from the previous definition details
               - aws ecs register-task-definition --family "app-staging" --container-definitions $CONTAINER_DEFS
      
               # updates ecs
               - aws ecs update-service --cluster "toolkit" --service "app-staging" --task-definition "app-staging"
             artifacts:
               - node_modules/**
               - dist/**
      

      【讨论】:

        【解决方案4】:

        如果您可以将容器更新到新的 :latest 映像,那么在部署之前停止 ECS 集群的任务就可以了。

        在 AWS CodeBuild 阶段的buildspec.yml 中添加

        aws ecs list-tasks --cluster "ECS_CLUSTER_NAME" --output text | awk '{print $2}' | while read line ; do aws ecs stop-task --task "$line" --cluster "ECS_CLUSTER_NAME" ; done
        

        使用您的 ECS 集群的名称而不是 ECS_CLUSTER_NAME,到您的 docker push... 命令之后的 post_build commands 部分。

        容器将被停止。 ECS 将使用您新创建的 docker 映像完成所需的任务量。

        附:不要忘记检查 IAM,以便您的 CodeBuild 用户角色有权执行 ecs:* 命令。

        【讨论】:

          【解决方案5】:

          要以比停止任务更优雅的方式将容器更新为 :latest 映像的新副本,请执行以下操作:

          aws ecs list-services --cluster "ECS_CLUSTER_NAME" --output text | awk '{print $2}' | while read line ; do aws ecs update-service --service "$line" --force-new-deployment --cluster "ECS_CLUSTER_NAME" --region "ECS_CLUSTER_REGION" ; done
          

          此代码实质上列出了服务,获取每个服务的 serviceArn。然后循环强制执行新部署。

          这比停止任务更优雅,因为它开始一个新任务,然后旧任务被删除。因此,它总是让任务运行。

          这假设它将使所需的服务数量超过所需的任务限制。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-08-24
            • 1970-01-01
            • 2016-07-09
            • 2019-04-28
            • 2019-08-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多