我正在使用AWS Code Pipeline,Code Build创建一个新的Docker容器并将其推送到ECR。

我的应用程序是基于简单直接的单一容器的。减少当前运行中的Container并从ECS注册表中重新启动新Container(通过代码管道生成代码)的摩擦会更少。

我尝试使用CloudFormation和EC2用户数据,自定义一方面是脚本脚本,另一方是带有ECS且任务定义的CloudFormation(尚未成功)。我强烈认为必须有更明显,更简单的方法。

#1 楼

我将ECS容器实例(我在谈论Docker主机-我在这里不喜欢AWS术语)和部署保留为两个独立的部分。

使ECS堆栈启动并运行。您可以通过CloudFormation和自动扩展组来管理它,这很好。只需将集群视为要部署到的平台即可,而无需重新部署。

然后,对于CD,到目前为止,最简单的方法是更新服务定义以使用新任务定义并让ECS滚动为您更新容器。

每次启动任务时,ECS都会运行docker pull image:tag,即使它在本地具有该映像以确保它具有最新版本的。该图像:标签。因此,您所使用的图像标签确实无关紧要(无需在每个版本上都更改该标签)。

这意味着您可以反复构建myimage:latest以进行部署容易。

您需要的是一个任务定义,其中image = myimage:latest。创建具有该任务定义的服务,每次ECS启动任务(您的服务的实例)时,它将是您构建的最新“ myimage:latest”。

从那里开始您可以从CodeDeploy中仅解决一个难题,您可以调用某些东西(也许是lambda函数)来创建任务定义的新修订版并更新服务,ECS会自动为该修订版创建新任务并删除旧任务。

示例:

假设您已经创建了一个名为MyService的服务。您已将该服务配置为为任务定义MyTaskDefinition:1(修订版1)运行2个任务。在该任务定义中,您有一个容器定义,其图像设置为“ myimage:latest”。


昨天您构建了myimage:latest,其ID为(SHA)365d8f7bf565。 br />您的容器实例ABC正在运行名为MyTaskDefinition-1-containerName-someLongId的任务。当您检查该容器时,它正在运行图像“ sha256:365d8f7bf565 .....”。
您的其他容器实例DEF正在运行另一个任务。它具有类似的名称(只是ID不同),但是运行的是相同的图像。
您将更改推送到存储库中。
CodePipeline拾取更改,将图像生成并发布到ECR。
新的Docker映像也是myimage:latest,但其ID(SHA)为f7ec5e54ac96
现在,您需要在管道中添加一个步骤以使用Lambda函数和AWS NodeJS SDK来对您的对象进行一些调用群集:


创建一个新的任务定义(与之前完全相同)。那将是MyTaskDefinition:2
更新您的MyService以使用MyTaskDefinition:2(而不是1)


ECS将创建新任务。容器名称将为MyTaskDefinition-2-containerName-someLongId。当您检查这些容器时,您会看到它们将在运行“ sha256:f7ec5e54ac96 .......”。也许您将在容器实例ABC上有2个任务,也许它们会被喷出(取决于您服务的配置)
一段时间后,ECS将从ABC中删除旧任务MyTaskDefinition-1-containerName-someLongId DEF。

注意:实际上,您不需要创建新的任务定义。如果需要,可以取而代之的是检索服务的任务列表,然后手动将其逐一停止。在停止新任务之前,您应该等待ECS重新启动任务(即:停止第一个容器,等待ECS替换它,再停止第二个容器)。 ECS重新启动容器时,它将抓取最新构建的myimage:latest,如前所述。我只是认为创建新任务定义更容易且更不容易出错(无需等待和检查逻辑,如果您有新的任务定义,则ECS将为您处理滚动更新)。

评论


太棒了-我将您的答案称为Docker CI / CD缺少的手册。谢谢。

– Naveen Vijay
17 Mar 3 '17 at 5:17

#2 楼

对于描述的简单用例,我建议检查Docker的Elastic Beanstalk,这不是像ECS裸露使用这样的最小解决方案,但是您可以从自动管理和配置的服务中受益,例如ELB,EC2 AutoScale,运行状况监视等等。 >
高级摘要:


配置Elastic Beanstalk以使用特定标签myimage:tested
使用Code Pipeline / Build来构建,测试和升级“ tested”标签“
触发Elastic Beanstalk部署,这将拉动提升的映像myimage:已针对所有实例进行了测试,提供了不同的部署策略。

这种基于重复使用相同标签的方法,将会生成替代方法带有构建ID的标签,例如myimage:tested-42,这将需要每次使用新标签更新Elastic Beanstalk,但对已部署的修订版进行更精细的控制。

#3 楼

为了简单起见,我第二讲弹性豆茎;设置和部署非常容易。

如果您熟悉docker-compose,另一种方法是定义docker-compose.yml并直接使用ecs-cli部署在ECS上。