我在ECS上有一个容器服务集群。我已经设置了CodePipeline,在更新时构建新的容器并将其推送到ECR。如何触发对我的集群的更新以使用新更新的容器?
我在ECS上有一个容器服务集群。我已经设置了CodePipeline,在更新时构建新的容器并将其推送到ECR。如何触发对我的集群的更新以使用新更新的容器?
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/**
如果您同意将容器更新为新的: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 Cluster名称而不是ECS_CLUSTER_NAME的位置,将post_build
commands
部分添加到docker push...
命令之后。
容器将停止。ECS将使用您新创建的Docker镜像满足所需的任务数量。
P.S. 不要忘记检查IAM,确保CodeBuild用户角色具有执行ecs:*命令的权限。
由于您正在使用CodePipeline,因此可以在构建新镜像后触发CloudFromation堆栈。然后,CloudFormation堆栈将创建一个新的任务定义并更新您的ECS服务。这是一个参考架构。
您可以使用this参考架构进行持续部署。CloudFormation模板附在上述Github存储库中。
如果要以比停止任务更优雅的方式将容器更新为最新的 :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。然后循环强制进行新部署。
这比停止任务更优雅,因为它启动一个新任务,然后旧任务在之后被删除。因此,它总是保留一个正在运行的任务。
这假设将采取所需数量的服务超过所需任务限制。