由于使用了端口,我无法将新容器部署到ECS群集中

red*_*888 6 amazon-web-services amazon-ecs

我的服务使用的任务定义是提取图像的“最新”标记版本。

当我更新服务并“强制进行新部署”时,我会查看事件并看到以下内容:

service MYSERVICE was unable to place a task because no container instance met all of its requirements. The closest matching container-instance .... is already using a port required by your task
Run Code Online (Sandbox Code Playgroud)

然后,我去了我的集群并停止了所有任务。

然后返回到我的服务并通过强制新部署再次进行更新。这似乎有效

每次要部署新映像时,我都必须停止所有任务并更新服务吗?还是有一种“正确”的方式来做到这一点?

编辑:因此,如果我停止一项任务,服务将自动替换它。因此,我可以更新我的服务并“强制进行新部署”,然后一次停止一项任务,以获取某种滚动更新。除了我自己的脚本外,不确定是否有可以自动执行此功能的功能

只是为了跟进,如答案中所述,我只需要使用动态端口映射。

最初,当我第一次启动时,我没有负载均衡器,因此我直接命中EC2实例以访问正在运行的容器。当然,为了做到这一点,我不得不在EC2主机上公开一个静态端口。

我添加了一个负载平衡器,但保持该静态端口映射不了解动态端口映射的工作方式。我要做的就是更改任务定义以将主机端口设置为“ 0”。现在,主机上没有静态端口映射,NLB为我进行路由并按预期部署工作

MrD*_*Duk 11

虽然其他答案是正确的,但我认为它们不适用于您遇到的问题。我之所以这样说,是因为这也是我的团队面临的一个问题,并且与尝试在同一实例上启动多个容器并没有任何关系-如果我理解正确,那么您只是在尝试从中替换现有的容器更新的任务定义。如果要将同一容器的多个副本放在一个盒子中,请务必查看其他答案的建议(除了下面的详细信息),但是对于滚动部署,绝对不需要动态端口。

[[完整性的旁注:您的强制部署可能会抛出您发布的错误,因为EC2清理ECS停止的资源只需要一段时间。如果您尝试强制停止/启动任务,则会遇到同样的问题-尝试重新启动配置为分配超过50%的可用实例内存的容器时,我们也遇到了类似的错误。在完全清除EC2实例并将其报告给ECS之前,您将获得这些类型的资源错误。我已经看到这需要5分钟以上的时间。]]

那么到您的问题,不幸的是,目前还没有AWS出色的内置机制来执行任务的滚动重启。但是,您可以进行滚动部署

您可能已经知道,您的服务依赖于指定的任务定义。请注意,它依赖于任务定义编号,并不像EC2实例那样关心容器标签

以下设置是启用滚动部署的神奇之处。您可以在服务设置中找到这些配置选项。

魔法

为了能够进行滚动部署,您必须至少运行2个任务。

  • 任务数- 服务要运行的任务数(n)
  • 最低健康百分比- 部署新任务时的最低健康百分比n
  • 最大百分比- 部署新任务时可以添加的最大百分比n

因此,作为一个真实的示例,我们假设您具有以下配置:

Number of tasks: 3
Minimum healthy percent:  50
Maximum percent: 100
Run Code Online (Sandbox Code Playgroud)

如果更改服务所指向的任务定义,它将启动滚动部署。我们有3正在运行的任务,但可以保持>=50%健康。ECS将杀死您的一项任务,使正常运行的%降至66%,甚至高于50%。一旦出现新任务,服务将再次位于100%,ECS可以继续将部署滚动到下一个实例。

同样,如果您有一个配置,其中minimum % == 100maximum % == 150(假设您有能力),ECS将启动其他任务;一旦启动,您将拥有正常的百分比133%,并且可以安全地终止一项旧任务。该过程将一直持续到您的新任务完全部署为止。

  • 到目前为止,这个答案最适合我的情况,很高兴了解部署的工作原理。我不想使用负载均衡器并且只运行 1 个容器。所以我设置了`最小健康百分比== 0` (3认同)

Lau*_*ard 5

使用ECS(或任何其他协调器)时,建议您使用动态端口映射

基本上,ECS会为您的容器分配一个随机的未分配端口。然后,ECS提供了使用代理自检API或Docker客户端本身来检索该端口号的方法。但是,我不会尝试检索端口,而是依靠Application Load Balancer(ALB),它允许您使用单个端点来独立于其动态分配的端口访问任何目标容器。更新服务时,ALB将无缝过渡到容器的最新版本,而不会造成任何中断。

最后,在容器内部,本地端口将保持不变,因此您不必处理其他问题。

  • **既不鼓励动态端口映射,也不是最佳实践**。这仅取决于您的用例。 (3认同)

S.K*_*.K. 5

如果没有动态端口,每个容器只能部署一个服务实例,因为该实例正在使用的端口不能被任何其他实例使用。当您更新服务时,它将尝试重新启动其所有实例,如果在单个 EC2 容器上启动多个实例,则启动将失败。

最好在 ECS 集群中使用带有动态端口映射的 docker 容器。