优雅地停止 ecs 容器

Posted

技术标签:

【中文标题】优雅地停止 ecs 容器【英文标题】:Gracefully stopping ecs container 【发布时间】:2018-09-08 12:05:57 【问题描述】:

我有一些 docker 容器,它在 RabbitMQ 上侦听并处理收到的消息。我有一个代码管道,当有代码提交时,它会启动图像的重建和更新任务。

我的问题是在消息处理期间容器将被突然杀死有什么方法可以停止容器杀死直到进程完成并允许它停止,以便在我自动创建一个新的新容器可以使用当前容器使用旧代码处理消息。我的容器在里面运行 python 代码。

【问题讨论】:

【参考方案1】:

ECS by default sends a SIGTERM:

停止任务

停止正在运行的任务。

在任务上调用StopTask 时,相当于 docker stop 是 发给任务中运行的容器。这导致一个 SIGTERM 和默认的 30 秒超时,之后发送 SIGKILL 并且容器被强制停止。如果容器处理 SIGTERM 优雅并在收到后 30 秒内退出,否 SIGKILL 已发送。

注意

可以在 Amazon ECS 上配置默认的 30 秒超时 具有 ECS_CONTAINER_STOP_TIMEOUT 变量的容器代理。更多 信息,请参阅 Amazon ECS 容器代理配置 Amazon Elastic Container Service 开发人员指南。

了解这一点后,您可以在应用中添加一个简单的检查来捕捉 SIGTERM,并做出适当的反应。

【讨论】:

感谢您的回复,所以如果我能够捕获 SIGTERM 并更改默认超时,我可以等待进程完成,即使它需要更长的时间,例如最多 30 分钟? 值得注意的是,最大超时时间为 120 秒。 docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…【参考方案2】:

在 Docker 中实现优雅停止的两种方法:

使用 docker stop

当向容器发出docker stop 命令时,Docker 会向容器内的进程触发SIGTERM 信号,并在清理容器之前等待 10 秒。

你可以指定10s以外的超时时间:

docker stop --time 30 <CONTAINER>

您需要确保进程正确处理SIGTERM 信号。否则会被SIGKILL 信号粗暴地杀死。

使用 docker kill

默认情况下,docker kill 命令会向进程发送SIGKILL 信号。但是您可以指定要使用的另一个信号:

docker kill --signal SIGQUIT <CONTAINER>

还要确保进程正确处理指定的信号。比docker stop 更糟糕的是,docker kill 命令没有超时行为。

【讨论】:

该问题专门请求 Amazon ECS (aws.amazon.com/ecs) 的帮助,ECS 为您管理容器,不提供对原始 docker cli 命令的访问。

以上是关于优雅地停止 ecs 容器的主要内容,如果未能解决你的问题,请参考以下文章

使用 docker-compose up 运行时如何优雅地停止 Dockerized Python ROS2 节点?

Kubernetes 中如何保证优雅地停止 Pod

Kubernetes 中如何保证优雅地停止 Pod

从 Docker 的信号机制看容器的优雅停止

如何优雅地停止 uWebSockets 服务器?

在 Powershell 中优雅地停止