在AWS ECS服务中管理Docker容器的最佳实践

5

技术栈

Python(单体API) - Flask框架 PostgreSQL

我们已经按照以下方式部署了Docker容器:

  • Docker镜像存储在ECR中
  • Docker容器部署在ECS中
  • 共有25个Docker容器部署在3个R5大型EC2实例(2 vCPU,16 GB)中
  • 每个容器分配了1024/3072的最小和最大内存,因此每个EC2实例可容纳15个容器

我们现在面临停机问题,问题是OOM(内存不足),然后给定EC2实例中的容器开始移动到另一个EC2实例,当由于某种原因第三个EC2实例不可用时,就会发生这种情况,因此直到第二个实例正常运行,我们才会面临指定一组容器的停机时间。

所以想要检查我们使用的策略是否正确?

我们现在计划拥有少量容器的小型EC2实例,因此如果出现问题,则至少会关闭少量网站,而不是所有15个网站都将关闭,我们是否走在正确的方向上?

我们应该转移到Fargate吗?相对于使用ECS,成本会有什么影响?

如果有人能够帮助我找到这种问题的完美解决方案,那将是很棒的。

在不久的将来,我们将拥有数百个容器,可能会达到500个,因此我们必须决定最佳的部署、故障转移和高可用性策略。


3
Fargate通常比您自己的EC2集群更昂贵,您可以自行计算。这个问题的其余部分过于模糊,无法提供太多信息。 - deceze
感谢Deceze的快速回复,关于Fargate没问题。还需要什么信息才能得到正确的答案? - Manish Joisar
1
拥有较小的实例并略微超额配置您的自动缩放组可能是一个不错的主意(即,在撞墙之前扩展,而不是已经太迟了才扩展)。不过在我看来,您应该先检查一下内存限制-如果您假设每个容器实例实际上可以使用最大分配内存(即3GB),那么这些数字就不匹配了。 - Szymon Jednac
2个回答

8
如果您遇到OOM错误,这意味着您的EC2机器被过度配置了-您在其中运行了太多的容器。每个实例15个容器,每个容器最大3072,那么您需要在容量上使用46GB的内存,而机器的最大容量只有16GB。一旦足够多的容器使用了它们分配的内存,您的机器就会崩溃,带走所有其他任务。

因此,您现在可以做的第一件事是降低每台机器的任务数量或降低最大内存,以便任务总体上使用更少的内存。由于每台机器只有2个CPU,我建议您将其调整为每台机器总共运行两个任务,并在它们之间拆分内存,确保其他设置(最大连接、工作人员等)相应提高。

你还问过 Fargate。我们公司对容器同时使用 EC2 和 Fargate,我们有一个政策:如果没有特定的原因要在 EC2 上运行(例如需要 GPU),我们就放到 Fargate 上。虽然花费会多一些(Compute Savings Plans 降低了一些成本,但仍旧比较昂贵),但好处非常多。这意味着每个任务都是独立运行的,减少了一个任务影响其他任务的可能性。它也意味着更快的扩展期,因为我们不必等待 EC2 实例扩展并加入集群-如果你正在使用应用程序自动缩放来响应突然的流量涌入,这一点非常重要。
Fargate 最大的好处是减少了复杂性,这反过来意味着团队需要操心的事情会减少,开发人员节省时间和减轻压力的收益可能比额外支出更有价值。简单的事实是,我们永远不必担心诸如升级 ECS Agent、与 Patch Manager 集成以进行安全更新,以及我们不需要定期循环机器以用新版本替换它们,这意味着我们可以把时间花在基础设施的其他部分上。

正如我上面提到的,虽然有些情况下Fargate并不适用。对于我们来说,在EC2实例上运行并能够选择用于运行ML的GPU类型是最大的用例。为此,我们构建了自己的AWS Machine Image,它可以与AWS提供的各种GPU实例一起使用。这基本上是我没有使用Fargate的唯一地方,因为这些模型需要EC2实例GPU。


1

joisar,

我们也面临同样的问题。因此,我可以提供一些关于如何处理的信息。

阅读您的规格说明后,我可以得出一些数字。 正如您所提到的,您正在使用3个R5 Large类型的EC2(2个CPU,16个内存)。这意味着您有:

总CPU = 6 GB个单位和 总内存 = 48 GB内存

在您的配置中指定的最大内存=3072。 然后您已经提到了25个容器,这些容器部署在这3个实例上。[除非某些容器具有较少的内存,否则不确定如何实现]

首先,在单个EC2中,您不能拥有超过5个容器的这些规格。计算如下:

16 GB = 1024 * 16 = 16384。

16384/3072 = 5.3 [表示单个EC2最多只能容纳5个容器]

但请记住,您正在ECS的EC2中启动容器,EC2需要自己的空闲空间和内存来进行操作。但是,您没有为EC2分配太多的空闲内存,因为您将所有内存都分配给了您的容器。[我假设最坏的情况是5个容器都使用3072 MB内存。]这样你就没有内存了。您必须以这样一种方式决定最大内存数,以便EC2具有一些自由内存进行其自身的操作。
减少最大内存的优点包括:
  1. 为EC2提供更多的空间
  2. 您可以在ECS中为每个服务减小大小以获得2个任务定义。通过这种方式,您实现了高可用性。
尝试分析哪个容器使用更多的内存,为该容器分配更多的内存,为其他容器指定较少的内存。您必须平衡容器的内存数量。这也可能是许多人的痛点,这就是Fargate可以拯救我们的地方。
您还提到您计划更改EC2大小。选择内存优化实例。
是的,Fargate可能是最好的选择,但它的成本很高。
然后,对于高可扩展性(High Scalability),定义自动缩放策略。此外,策略应该这样设计:在夜间通常流量较少,因此可以减少集群中EC2机器的数量。通过这些措施,您将节省成本,并用所节省的成本在高峰期增加EC2机器的可用性。
最后,您需要提出自己的数字并监控它们,而且这不是一天可以完成的过程。这是一个不断发展的过程。

感谢Bhavuk的详细回复。 如果您看一下我的问题,当我说3072时,它是关于同一EC2实例中一个容器可以利用的最大内存,所以最小值为1024,这就是为什么一个EC2可以包含15个容器的原因。 - Manish Joisar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接