docker - 在一个容器中运行多个类似的进程是否有意义?

标签 docker kubernetes containers devops

提供问题背景的简短背景。

目前,我和我的团队正在将我们的微服务迁移到 k8s,以减少必须维护多个部署工具和管道的工作量。

我们计划迁移的微服务之一是 ETL worker,它在 SQS 上监听消息并执行多阶段处理。

它是使用 PHP Laravel 构建的,我们使用 supervisord 来控制在 aws ec2 上的每个工作实例上运行多少个进程。每个进程基本上执行一个 laravel 命令来轮询不同的队列以获取新消息。我们还定期调整进程数,以最大限度地利用每个实例的计算能力。

所以问题是:

迁移到 k8s 时,这种部署方式是否仍然可行?是否仍然需要“最大化”计算使用量?我们是否最好使用“容器方式”在每个容器中运行 1 个进程(不确定该工具叫什么。runit?)

我从多个来源(例如 https://devops.stackexchange.com/questions/447/why-it-is-recommended-to-run-only-one-process-in-a-container)了解到,容器只运行 1 个进程是理想的。还有恢复崩溃进程的情况,以及运行 supervisord 可能会如何干扰容器执行恢复的方式。但我不太确定它是否适用于我们的用例。

最佳答案

你绝对应该重组它,让每个容器运行一个进程,每个 pod 运行一个容器。您通常不需要 init 系统或像 supervisord 或 runit 这样的进程管理器(有一个论点是有一个像 tini 这样的专用 init 可以做特殊的 pid-1 事情)。

您在这里提到了两个问题,重启失败的进程和集群中的进程放置。对于这两种情况,Kubernetes 会自动为您处理。

如果 Pod 中的主进程发生故障,Kubernetes 将重新启动它。您不需要为此做任何事情。如果它反复失败,它将开始延迟重启。此功能仅在主进程失败时才有效——如果您的容器的主进程是主管进程,您将永远不会重启 pod,并且您可能不会直接注意到进程是否根本无法启动。

通常,您将通过具有一定数量相同副本 Pod 的 Deployment 运行容器。 Kubernetes 本身负责决定哪个节点将运行每个 pod;您不需要手动指定它。 pods 越小,放置它们就越容易。由于您要控制 pod 的副本数量,因此您还希望将 Web 服务器与队列 worker 等问题分开,以便您可以独立扩展它们。

Kubernetes 具有一定的自动扩展能力,但通常的方向是根据工作负载调整集群的大小:在面向云的设置中,如果您添加一个新的 pod 请求的 CPU 多于集群当前可用的 CPU,它将提供一个新节点。 Horizo​​nalPodAutoscaler 是一种高级设置,但您可以对其进行配置,使工作线程数成为队列长度的函数。同样,如果它唯一扩展的是 worker pod,而不是打包在一起的不相关事物的集合,那么这种方法会更好。

关于docker - 在一个容器中运行多个类似的进程是否有意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60758848/

相关文章:

php - Docker - 在 docker 容器外使用 PHP 创建目录

docker - 如何使用 docker-compose.yml 和 ecs-cli 将 EBS 卷附加到我的容器

azure - 启用虚拟节点和未启用虚拟节点的 AKS 群集

azure - Microsoft Azure AKS 位置(命令行字符串)

c++ - 不可复制类型的整数可索引 RAII 容器

docker - Webserver 无法通过 docker-compose 连接到 Redis

docker - Github Action 到 maven 构建,然后是 Docker 构建推送

kubernetes - Kubernetes仪表板不显示Pod消耗的CPU和内存

c++ - std::end(myVector) 和 myVector.end() 之间的区别

kubernetes - 将应用程序配置文件添加到 kubernetes pod 的最佳实践