更新Amazon ECS中的服务容器

build议用什么方法更新Amazon ECS中运行的服务的容器?

AWS文档说:“如果您更新了应用程序的Docker镜像,则可以使用该镜像创build新的任务定义,并将其部署到您的服务中,一次完成一项任务。 这几乎是当前(2015年4月13日)文档中可用的所有内容。

我理解正确吗,更新Amazon ECS中的应用程序容器的唯一方法是创build一个新任务,然后停止旧任务并启动新任务?

我已经成功地在Core OS和Fleetctl上使用“latest”标签。 这样做的好处是无需为新的更新更改Docker镜像标签,因为重新加载服务将会看到新的更改并更新容器(使用相同的标签“latest”)。

您在Amazon ECS中使用更新的Docker镜像更新服务时使用了哪种方法?

不知道这是否被认为是被遗弃的问题 – 在解决我的问题时偶然发现了这个问题,现在我的解决scheme现在已经解决了。

要使用新容器更新服务,您需要:

  1. 将新容器上传到存储库;
  2. 触发任务定义更新;
  3. 触发容器更新;
  4. 重要的是:确保服务规则允许启动新版本的任务。

如果服务任务未更新到最新版本,请检查“事件”选项卡以查找错误。 例如,ECS可能无法启动服务的新版本:集群中只有一个ec2实例,应用程序端口已在主机上使用。 在这种情况下,将“最小健康/最大健康”限制设置为“0%,100%” – 这样,ECS将在部署新容器之前select杀死旧容器。 这也是在几分钟的时间内发生的 – 如果你没有看到即时反馈,请不要急于求成。

以下是用于更新预configuration群集和服务中的容器的示例部署脚本。 请注意,如果您只是指“使用家庭最新版本”,则无需指定版本。

awsRegion=us-east-1 containerName=.. containerRepository=.. taskDefinitionFile=... taskDefinitionName=... serviceName=... echo 'build docker image...' docker build -t $containerName . echo 'upload docker image...' docker tag $containerName:latest $containerRepository:$containerName docker push $containerRepository:$containerName echo 'update task definition...' aws ecs register-task-definition --cli-input-json file://$taskDefinitionFile --region $awsRegion > /dev/null echo 'update our service with that last task..' aws ecs update-service --service $serviceName --task-definition $taskDefinitionName --region $awsRegion > /dev/null 

要更新您的应用程序,请更新任务定义,然后更新服务。 请参阅http://docs.aws.amazon.com/AmazonECS/latest/developerguide/update-service.html

我使用了ecs-deploy脚本中的一些部分,并对其进行了改进(从每个容器描述中获取图像,并用$ TAG_PUREreplace它的标记部分): https ://gist.github.com/Forever-Young/e939d9cc41bc7a105cdcf8cd7ab9d714

 # based on ecs-deploy script TASK_DEFINITION_NAME=$(aws ecs describe-services --services $SERVICE --cluster $CLUSTER | jq -r .services[0].taskDefinition) TASK_DEFINITION=$(aws ecs describe-task-definition --task-def "$TASK_DEFINITION_NAME" | jq '.taskDefinition') NEW_CONTAINER_DEFINITIONS=$(echo "$TASK_DEFINITION" | jq --arg NEW_TAG $TAG_PURE 'def replace_tag: if . | test("[a-zA-Z0-9.]+/[a-zA-Z0-9]+:[a-zA-Z0-9]+") then sub("(?<s>[a-zA-Z0-9.]+/[a-zA-Z0-9]+:)[a-zA-Z0-9]+"; "\(.s)" + $NEW_TAG) else . end ; .containerDefinitions | [.[] | .+{image: .image | replace_tag}]') TASK_DEFINITION=$(echo "$TASK_DEFINITION" | jq ".+{containerDefinitions: $NEW_CONTAINER_DEFINITIONS}") # Default JQ filter for new task definition NEW_DEF_JQ_FILTER="family: .family, volumes: .volumes, containerDefinitions: .containerDefinitions" # Some options in task definition should only be included in new definition if present in # current definition. If found in current definition, append to JQ filter. CONDITIONAL_OPTIONS=(networkMode taskRoleArn) for i in "${CONDITIONAL_OPTIONS[@]}"; do re=".*${i}.*" if [[ "$TASK_DEFINITION" =~ $re ]]; then NEW_DEF_JQ_FILTER="${NEW_DEF_JQ_FILTER}, ${i}: .${i}" fi done # Build new DEF with jq filter NEW_DEF=$(echo $TASK_DEFINITION | jq "{${NEW_DEF_JQ_FILTER}}") NEW_TASKDEF=`aws ecs register-task-definition --cli-input-json "$NEW_DEF" | jq -r .taskDefinition.taskDefinitionArn` echo "New task definition registered, $NEW_TASKDEF" aws ecs update-service --cluster $CLUSTER --service $SERVICE --task-definition "$NEW_TASKDEF" > /dev/null echo "Service updated" 

上传新的Docker镜像后,即使它具有与任务所使用的相同的标记,也必须复制最新的任务,然后将该服务configuration为使用该新的任务。 可选地,可以简单地有2个重复任务,并configuration服务在每次更新Docker镜像时在它们之间进行交换。

基本上,为了让ECS创build一个新的Docker容器,服务的更新必须触发它,而使服务触发的唯一方法是以某种方式更新它 – 就像告诉它使用不同的任务编号。

请注意,现有的正在运行的容器可能无法自动停止,因为服务已更新 – 您可能需要查看“任务”列表并手动停止它们。

对我来说,这种方法与上面类似。 创build服务和任务后,开始一切工作,编辑Auto-Scaling组并确保minmaxdesired设置为1

该组可能是默认的组; 如果您不确定,则可以通过select群集中的ECS实例选项卡,然后从“ 操作”下拉列表中select“ 群集资源” ,然后单击打开的对话框底部附近的链接。

当这一切到位时, 任何时候你想部署一个更新的容器镜像到集群的任务区域并停止任务 。 你会得到一个警告,但是如果提供了自动缩放function,那么服务会在最近一次推送时再次启动它。

不需要创build服务或任务的新版本。

请注意,服务/任务可以从瞬间更新到一分钟左右。 如果你绝望的等待,你可以手动运行新的任务。 该服务不会拥有它,所以它不是很理想,但如果它死了,它仍然会启动一个新的。