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

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

技术栈

Python (Monolith 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 相比,成本影响是什么?

如果有人能帮我找到解决此类问题的完美解决方案,那就太好了。

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

解决方法

如果您收到 OOM 错误,则意味着您的 EC2 机器被过度配置 - 您在这些机器上运行了太多容器。每个实例有 15 个容器,每个容器最多有 3072 个容器,这意味着在 16GB 的机器上可能有 46GB 的内存使用量。一旦有足够多的容器使用它们分配的内存,您的机器就会倒下,并带走所有其他任务。

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

您还询问了 Fargate。我的公司将 EC2 和 Fargate 用于我们的容器,我们有一项政策,如果没有特定原因在 EC2 上运行东西(例如需要 GPU),我们会将其放在 Fargate 上。虽然它多一点钱(与 Compute Savings Plans 相比没有那么多,但仍然更多),但好处非常好。这意味着每个任务都是单独运行的,从而减少了一个任务取代一堆其他任务的机会。这也意味着更快的扩展周期,因为我们不必等待 EC2 实例扩展并加入集群 - 如果您使用应用程序自动扩展来响应突然涌入的流量,这一点非常重要。>

Fargate 的最大好处是降低了复杂性,这反过来意味着我们的团队不必担心 - 为开发人员节省的时间和压力可能比花费的额外资金更有价值。简单的事实是我们永远不必担心升级 ECS 代理、与补丁管理器集成以进行安全更新,而且我们不需要定期循环机器以用新版本替换它们,这意味着我们可以将时间花在其他部分上取而代之的是我们的基础设施。

正如我上面提到的,虽然在某些情况下 Fargate 不合适。对我们来说,在 EC2 实例上运行的最大用例是能够选择我们用于运行 ML 的 GPU 类型。对于此 we built our own AWS Machine Image,它适用于 AWS 提供的各种 GPU 实例。这基本上是我唯一不使用 Fargate 的地方,因为这些模型需要 EC2 实例 GPU。

,

乔伊萨

我们也遇到过同样的事情。所以在这里我可以提供一些关于我如何看待它的信息。

阅读您的规格后,我可以得出一些数字。 正如您所提到的,您使用的是 3 个 R5 大类型的 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 可能是最好的,但成本很高。

然后对于高可扩展性,定义自动扩展策略。 此外,策略的方式应该是在 Nights 中我们通常拥有较少的流量,以便您可以减少集群中 EC2 机器的数量。有了这些,您将节省成本并节省成本;您可以在高峰时段使用它来提高 EC2 机器的可用性。

最后,你必须想出你的数字并监控它们,是的,这不是一天的过程。这是一个不断发展的过程。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-