如何在 AWS ECS 中重启容器?
How to restart containers in AWS ECS?
我已经通过 consul 的键值存储向 ECS 服务中的应用程序容器 运行 提供了应用程序配置。
应用程序仅在启动时从 consul 读取其配置一次。
当我需要更改配置时,我应该如何重启容器以刷新应用程序配置?
我希望通过 aws cli 以编程方式执行此操作。
您没有重新启动容器。但是,您可以停止单个任务,ECS 将在集群的某个位置重新生成您的任务的另一个实例。
这对我有用:
aws ecs list-tasks --cluster my-cluster-name | jq -r ".taskArns[]" | awk '{print "aws ecs stop-task --cluster my-cluster-name --task \""[=10=]"\""}' | sh
None 关于这个问题的现有两个解决方案是令人满意的。我(还)没有完整的答案,但我可以 A) 告诉你我发现了什么,B) 告诉你什么是处理这个问题的“正确”架构。
我发现了什么
我的印象是通过 SSH 连接到实例然后 docker restart <container-id>
应该可以工作。
事实上,最初看起来确实如此。但是,事实证明我错了,等着我的只是一群虫!这样做会导致容器从没有 IAM role/credentials 开始正确地与其他 AWS 服务对话。我的故事在 ecs-agent
的 this Github issue 上有详细介绍。我花了 10 多个小时才发现那是罪魁祸首。显然,容器只有 如果 ecs-agent 启动 它们 而不是你 start/restart 它们
正确的方法是什么?
我相信 ECS/Tasks 背后的心态和哲学是他们想要完全控制您与容器的 运行 环境之间的抽象层。您只需说“嘿,我想要 3 个这些 user-avatar-uploader-to-s3 容器 运行”,它就会为您完成这项工作。但是不欢迎你干涉他们做生意的方式!
但是,如果您希望容器可配置并向其传递某些参数(例如原始问题中的 consul 键值对),您可以将它们定义为 环境变量 在任务定义(对于每个容器)和 Service/Task 执行中。
因此,正确的方法是重做您的容器代码以将这些参数(键值对)作为环境变量(或来自可配置的安全私有 S3 存储桶或 AWS SecretsManager)。然后将所需的值放在 task/task-execution 中,瞧,它应该可以工作了。然后您可以随时更改它们,ECS 会处理它。 (请注意,这将是一个 new container/task 旋转的新设置,而不是更新的旧设置。)
就是这样。
(我会在找到如何进行紧急心脏直视手术 docker 重新启动后立即更新此答案。)
更新:
如@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 -> 集群 -> 服务)。
- 点击右上角的编辑。
- 展开部署选项
- 选中“强制新部署”框。
- 单击“更新”。
服务将重新部署。您应该能够看到现有任务 运行、新任务配置以及最后旧任务消失。
转到 ECS 仪表板。只需从 aws 控制台停止来自 ECS 服务的 运行 任务。它会产生一个新任务并终止旧任务。
总而言之,您不能简单地在同一任务中停止和启动容器。您刚刚开始一项新任务。 AWS 应该会滚动反弹,所以它不会给您带来停机时间,只要通过健康检查,新任务就会一直存在
我已经通过 consul 的键值存储向 ECS 服务中的应用程序容器 运行 提供了应用程序配置。
应用程序仅在启动时从 consul 读取其配置一次。
当我需要更改配置时,我应该如何重启容器以刷新应用程序配置?
我希望通过 aws cli 以编程方式执行此操作。
您没有重新启动容器。但是,您可以停止单个任务,ECS 将在集群的某个位置重新生成您的任务的另一个实例。
这对我有用:
aws ecs list-tasks --cluster my-cluster-name | jq -r ".taskArns[]" | awk '{print "aws ecs stop-task --cluster my-cluster-name --task \""[=10=]"\""}' | sh
None 关于这个问题的现有两个解决方案是令人满意的。我(还)没有完整的答案,但我可以 A) 告诉你我发现了什么,B) 告诉你什么是处理这个问题的“正确”架构。
我发现了什么
我的印象是通过 SSH 连接到实例然后 docker restart <container-id>
应该可以工作。
事实上,最初看起来确实如此。但是,事实证明我错了,等着我的只是一群虫!这样做会导致容器从没有 IAM role/credentials 开始正确地与其他 AWS 服务对话。我的故事在 ecs-agent
的 this Github issue 上有详细介绍。我花了 10 多个小时才发现那是罪魁祸首。显然,容器只有 如果 ecs-agent 启动 它们 而不是你 start/restart 它们
正确的方法是什么?
我相信 ECS/Tasks 背后的心态和哲学是他们想要完全控制您与容器的 运行 环境之间的抽象层。您只需说“嘿,我想要 3 个这些 user-avatar-uploader-to-s3 容器 运行”,它就会为您完成这项工作。但是不欢迎你干涉他们做生意的方式!
但是,如果您希望容器可配置并向其传递某些参数(例如原始问题中的 consul 键值对),您可以将它们定义为 环境变量 在任务定义(对于每个容器)和 Service/Task 执行中。
因此,正确的方法是重做您的容器代码以将这些参数(键值对)作为环境变量(或来自可配置的安全私有 S3 存储桶或 AWS SecretsManager)。然后将所需的值放在 task/task-execution 中,瞧,它应该可以工作了。然后您可以随时更改它们,ECS 会处理它。 (请注意,这将是一个 new container/task 旋转的新设置,而不是更新的旧设置。)
就是这样。
(我会在找到如何进行紧急心脏直视手术 docker 重新启动后立即更新此答案。)
更新:
如@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 -> 集群 -> 服务)。
- 点击右上角的编辑。
- 展开部署选项
- 选中“强制新部署”框。
- 单击“更新”。
服务将重新部署。您应该能够看到现有任务 运行、新任务配置以及最后旧任务消失。
转到 ECS 仪表板。只需从 aws 控制台停止来自 ECS 服务的 运行 任务。它会产生一个新任务并终止旧任务。
总而言之,您不能简单地在同一任务中停止和启动容器。您刚刚开始一项新任务。 AWS 应该会滚动反弹,所以它不会给您带来停机时间,只要通过健康检查,新任务就会一直存在