如何在 AWS ECS 中重启容器?

Posted

技术标签:

【中文标题】如何在 AWS ECS 中重启容器?【英文标题】:How to restart containers in AWS ECS? 【发布时间】:2017-09-04 00:02:21 【问题描述】:

我已经通过 consul 的键值存储向运行在 ECS 服务中的应用容器提供了应用配置。

应用程序仅在启动时从 consul 读取其配置一次。

当我需要更改配置时,我应该如何重新启动容器以刷新应用程序配置?

我希望通过 aws cli 以编程方式执行此操作。

【问题讨论】:

这里有很多答案:serverfault.com/questions/705644/… 流行的解决方案似乎是使用 aws cli aws ecs update-service --force-new-deployment ... 【参考方案1】:

您不会重新启动容器。但是,您可以停止单个任务,ECS 将在集群的某个位置重新生成您的任务的另一个实例。

【讨论】:

我考虑过。但是,这不会导致(轻微)停机吗?最好保持 ECS 开箱即用的蓝绿色部署。 这会导致短暂的停机,但重新启动也会如此。您可以增加服务的任务数以使其扩展,从负载均衡器中删除旧任务,然后停止旧任务。 投反对票。 1)这不是“你不”,而是“你不应该”。 2)这不是答案。您只是在说为什么这是一个坏主意(我完全同意),但您并没有说明如何实际执行此操作(执行该坏主意的解决方案),如果有人出于任何原因想要这样做的话。当开发人员做不常见/正常/标准的事情时,相同的“你不应该”而不是“你不应该”可以适用于大部分 *** 问题。这会扼杀创造力和真正的问题解决者。【参考方案2】:

更新:

正如@Aidin 提到的,您可以通过 AWS CLI 通过强制进行新部署来实现它:

aws ecs update-service \
--service <service name> \
--cluster <cluster name> \
--force-new-deployment \
[--profile guestapi-dev]

请注意,这不适用于具有 CodeDeploy 部署控制器的服务。

原答案:

我面临同样的挑战,我所做的是遵循this 指南(根据您的服务使用旧控制台或新控制台)。我不知道这是否可以通过 CLI 完成,但它实际上是“重新启动服务”,因为它会为您的服务重新生成新任务并杀死旧任务。

总结:

在旧控制台中:

    在 AWS 控制台中找到服务(ECS -> 集群 -> 服务)。 点击右上角的更新。 选中“强制新部署”框。 跳过其他配置,点击更新服务。

在新控制台中:

    在 AWS 控制台中找到服务(ECS -> 集群 -> 服务)。 点击右上角的编辑。 扩展部署选项 选中“强制新部署”框。 点击更新。

服务将重新部署。您应该能够看到现有任务正在运行、新任务配置以及最后旧任务消失。

【讨论】:

这是“创建新容器”而不是“重新启动现有容器”。虽然足够接近 - 可能对某些人有用,但不是每个人。谢谢。【参考方案3】:

这对我有用:

aws ecs list-tasks --cluster my-cluster-name | jq -r ".taskArns[]" | awk 'print "aws ecs stop-task --cluster my-cluster-name --task \""$0"\""' | sh

【讨论】:

这会重新启动整个任务,而不仅仅是一个容器。 投反对票。 1)没有解释。 2) 错误。错了,因为这个 sn-p 的作用是停止任务,所以如果任务属于服务,服务将重新生成运行任务的“新容器”。无论如何,这与重新启动容器无关。【参考方案4】:

转到 ECS 仪表板。只需从 aws 控制台停止 ECS 服务中正在运行的任务。它会产生一个新任务并终止旧任务。

【讨论】:

与另一个答案类似:它是“创建新容器”而不是“重新启动现有容器”。虽然足够接近 - 可能对某些人有用,但不是每个人。谢谢。 您好,用户明确询问了I am hoping to do this programmatically via the AWS CLI。另外,您能否including an explanation 了解这如何以及为什么可以解决问题。这确实有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释并说明适用的限制和假设。【参考方案5】:

总之,您不能简单地在同一个任务中停止和启动容器。你只是开始一个新的任务。 AWS 应该做一个滚动反弹,所以它不会给你停机时间,只要通过健康检查,新任务就会一直存在

【讨论】:

【参考方案6】:

关于这个问题的两个现有解决方案都不令人满意。我还没有完整的答案,但我可以 A) 告诉你我发现了什么,B) 告诉你处理这个问题的“正确”架构是什么。

我发现了什么

我的印象是通过 SSH 进入实例,然后只需 docker restart &lt;container-id&gt; 应该可以工作。

事实上,最初似乎是这样。但是,事实证明我错了,那只是一罐虫子在那儿等着我!这样做会导致容器从没有 IAM 角色/凭证开始,以便正确地与其他 AWS 服务通信。我的详细故事在ecs-agent 的this Github issue 上。我花了 10 多个小时才发现这是罪魁祸首。显然,只有 ecs-agent 启动容器,容器才会处于正常状态,而不是您启动/重新启动它们。

正确的方法是什么?

我相信 ECS/Tasks 背后的心态和理念是,他们希望完全控制您与容器运行环境之间的抽象层。您只需说“嘿,我想要 3 个这些 user-avatar-uploader-to-s3 容器运行”,它就会为您完成这项工作。但不欢迎你插手他们的业务!

但是,如果您希望容器是可配置的并将某些参数传递给它(例如原始问题中的 consul 键值对),您可以将它们定义为 环境变量在任务定义(针对每个容器)和服务/任务执行中。

因此,正确的方法是重做您的容器代码,以将这些参数(键值对)作为环境变量(或来自可配置的安全私有 S3 存储桶或 AWS SecretsManager)。然后将所需的值放入任务/任务执行中,瞧,它应该可以工作了。然后,您可以随时更改它们,ECS 会处理它。 (请注意,这将是一个容器/任务,使用新设置旋转,而不是更新旧设置。)

就是这样。

(我会在找到紧急心脏直视手术 docker 重启后立即更新此答案。)

【讨论】:

投反对票。 1) 没有回答“如何在 AWS ECS 中重启容器?”的问题。 2) 你为什么要手动 ssh 到实例重新启动它? 1) “你怎么用叉子吃汤”的答案是“你不知道。有更好的选择。叉子和汤不能那样工作。” 2)无论如何,如果你想吃汤,你需要靠近碗。 :) 祝你好运! 1) 根据你的汤示例,答案不是“你不知道”,而是“你不应该”。 2) 手动 ssh in 本质上是对 iac 的反模式。我什至认为在使用云服务时它是反模式。您也许可以在测试环境中执行此操作,但这不是一个可重复使用的解决方案。硬停下来。 3) MitchDempsey 给出了一个可以接受的答案,并对处理停机时间进行了跟进评论。您的回答不仅体现了一种不好的做法,而且您的实际解决方案只是重申了 OP 已经说过他们已经做过的事情。你在这里没有提供任何解决方案。你可以保持你的运气 我同意我并没有完全回答原始问题本身;见最后一行。我的回答包含我的最佳发现,包括阻止它的 Github 问题,以及我在那里的评论。我希望它能为任何想要了解它的人节省几个小时(直到ecs-agent 伙计们修复它。)从技术上讲,这篇文章可能是评论,但由于它很长并且有链接,我现在将它作为答案发布.一旦我终于在这里看到“重新启动正在运行的容器”的解决方案,我就会把我的拿下来。在那之前,感谢您在这里提供我的“如何开始”和“为什么”的详细信息,Ayala! :)

以上是关于如何在 AWS ECS 中重启容器?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWS ECS 中扩展任务/容器

如何链接在 AWS ECS 任务中运行的 2 个容器

AWS ECS 如何在私有桥接网络中启动容器

如何在 ECS(容器存储)上验证 AWS EBS(Beanstalk)? AccessDeniedException

如何使用 Fargate 在 AWS ECS 中正在运行的容器中运行命令

AWS ECS 使用 docker 和 nginx,如何将我的 nginx 配置放入容器中?