1

我们有几个(> 5)windows framework 4.8 .Net MVC Web 应用程序工作负载托管在由 ALB 暴露在外部的多可用区 ECS 集群(EC2 类型:Windows )中。所有这些应用程序在相当长的一段时间内都运行良好。现在需要有选择地为这些应用程序引入自动缩放(在 5 个中,3 个需要扩展/缩小)。我们正在考虑同时利用以下两个功能来实现这一目标。

  1. ECS 服务自动伸缩以扩展每个容器实例(任务级别)。

  2. ECS 集群 Auto ScalingEC2 实例级别使用 ECS 容量提供程序。它为步骤 1 中的任务启动的容器提供了空间。

我的问题是,这是可以实现的吗?或者这是Windows 容器的正确方法?. 为什么我强调 Windows 容器是因为 AWS ECS 与 Linux 容器相比缺乏很多特性,例如我们不能设置容器内存软限制(内存预留)但应该在配置任务本身时提到硬限制(内存),我认为是一大局限。

如果这无法实现,有哪些选择?我们现在无法迁移到 EKS,而且显然 Windows 不支持 Fargate。

4

2 回答 2

2

是的,这是可以实现的。我们有一个 ECS 集群,使用 Windows docker 容器运行六个服务。正如您所提到的,有两种类型的自动缩放:在任务级别和在容器实例级别。任务级自动缩放比容器实例自动缩放更容易。

容器实例

对于容器实例自动伸缩组,您需要以下资源:

  1. ECS 集群(您已经拥有)。
  2. 使用Windows ECS Optimized AMI之一的容器实例的启动配置。
  3. 使用您的启动配置创建新实例的自动扩展组。
  4. 您的扩展策略,可以是预留目标策略、计划策略或容量提供程序的组合。

在启动配置中,您需要将新实例注册到您的 ECS 集群。我们为此使用 UserData,并配置一些附加选项(例如,处理您提到的 Windows 中的硬/软内存限制):

<powershell>
[Environment]::SetEnvironmentVariable(ECS_RESERVED_MEMORY, 256, Machine) 
[Environment]::SetEnvironmentVariable(ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE, $TRUE, Machine) 
[Environment]::SetEnvironmentVariable(ECS_ENABLE_CPU_UNBOUNDED_WINDOWS_WORKAROUND, $TRUE, Machine) 
Initialize-ECSAgent -Cluster <your-cluster> -EnableTaskIAMRole -LoggingDrivers '[json-file,awslogs]' 
</powershell>

在自动扩展策略方面,您有多种选择,因此您必须选择最适合您的用例的选项。我们现在使用 80% 的内存预留目标进行扩展,并在一天中的某些时间安排了一些扩展操作,以确保我们在一天中的几次预期峰值时有足够的容量。我们还没有开始使用容量提供程序,因为它们周围存在一些错误和问题,所以我给他们更多的时间来“成熟”(我认为他们现在已经解决了很多问题......你可以阅读更多关于这个从这个评论开始)。

这几乎是扩展容器实例所需的全部内容。您可以开始向集群添加任务,并且您的自动扩展组应该开始添加更多容器实例。

请注意,如果没有容量容器,可能会出现组无法扩展的情况,即使在任何实例中都没有足够的内存或 CPU 来添加新任务。这将取决于您的任务的内存和 CPU 配置以及您的预留目标(例如,您有一个任务需要整个集群当前可用内存容量的 20%,您的集群有 85% 的内存使用率,但您的扩展策略在达到 90% 的内存使用率之前不会扩展)。这是容量提供者旨在解决的问题。在我们的用例和任务配置中,我们从来没有遇到过组无法扩展的问题,但我们知道我们正在过度配置集群以避免这种情况。

另一个问题是在扩展容器实例时:您需要将实例设置为以某种方式耗尽,以便您的任务有时间优雅地结束,这不是 AWS 自动处理的。您可以在此处跟踪一个未解决的问题。我们使用 lambda 函数和基于此评论中的Github 存储库的自动缩放生命周期挂钩解决了这个问题。

任务

扩展任务更容易:

  1. 您需要将您的任务与负载均衡器相关联,以便任务在 ELB 中/从 ELB 中自动注册/注销。
  2. 您可以为您的任务创建扩展策略(例如,您可以使用 ALBRequestCountPerTarget 根据每个目标的请求数量来增加,或者也可以安排自动扩展操作)。

在任务定义中,您必须将主机端口设置为 0,以便 ELB 自动分配它(在此处阅读 hostPort 的文档)。

这里的主要问题是确保您的应用程序设计为作为集群工作(例如,使用外部会话管理器而不是内存中的会话管理器)。

这是该过程的要点。每个步骤都有很多文档需要阅读,但这应该可以回答您提出的问题,为您指明正确的方向并帮助您避免我们在此过程中发现的一些问题。

于 2020-07-31T05:12:29.557 回答
1

为了禁用 Windows 容器的硬内存限制,在启动模板 UserData 上将“ECS_ENABLE_MEMORY_UNBOUNDED_WINDOWS_WORKAROUND”环境变量设置为 true。

  1. AWS Launch 模板用户数据
<powershell>
[Environment]::SetEnvironmentVariable("ECS_RESERVED_MEMORY",256, "Machine") 
[Environment]::SetEnvironmentVariable("ECS_ENABLE_MEMORY_UNBOUNDED_WINDOWS_WORKAROUND", $true, "Machine") 
[Environment]::SetEnvironmentVariable("ECS_ENABLE_CPU_UNBOUNDED_WINDOWS_WORKAROUND", $true, "Machine") 
Initialize-ECSAgent -Cluster <clustername>-EnableTaskIAMRole -LoggingDrivers '["json-file","awslogs"]' 
</powershell>
  1. 在任务定义中跳过内存硬限制并提供将被代理忽略的软限制(保留)。

代理版本应>=1.32.1(越大越好)

于 2020-11-04T09:30:25.823 回答