如何防止Auto Scaling终止EC2实例?

17

如果某个EC2实例正在执行某种处理任务,我希望通过Auto Scaling功能来阻止该实例被终止。

背景:
假设我有一个Auto Scaling组,当前有5个实例正在运行。 我对平均CPU使用率创建了一个警报... 假设其中4个实例处于空闲状态,而另一个实例正在进行一些繁重的处理任务... 平均CPU负载将触发警报,因此缩减规则将被执行。

我如何让Auto Scaling终止其中一个空闲的实例而不是那个正在执行处理任务的实例?

5个回答

10
我刚刚成功地使用相对较新的生命周期钩子功能处理了自动缩放组中长时间运行作业的问题。
在我的情况下,尝试选择一个空闲节点进行终止的问题在于选择空闲节点的进程将与提交工作到节点的进程竞争。在这种情况下,最好使用一种策略,其中任何节点都可以被终止,但是终止是平稳的,以便不会丢失任何工作。然后,您可以使用所有标准的自动缩放策略来管理缩小和扩展。
终止生命周期挂钩允许用户(或进程)在自动缩放组将其置于中间状态(标记为Terminating: Wait)之后对节点执行操作。然后,用户(或进程)负责通过AWS API调用完成生命周期操作,导致终止EC2实例的关闭。
我简要设置了这个方式:
  • 创建一个角色,允许自动缩放向SQS队列发送消息。
  • 为终止消息创建一个SQS队列。
  • 创建一个监视脚本,作为每个节点中的服务运行。我的脚本是一个简单的事件驱动状态机,按顺序从MONITORING(轮询SQS以获取节点的终止消息)转换到DRAINING(轮询工作队列,直到节点上没有正在执行的工作)到TERMINATED(进行完整的生命周期调用)。
  • 标准配置为事件驱动的AWS自动缩放;即创建CloudWatch警报和用于缩小和扩大规模的自动缩放策略。

这种方法的一个障碍是SDK(例如boto)尚不支持生命周期挂钩管理,也没有适用于钩子的Cloud Formation资源。

相关的AWS文档在这里:

http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AutoScalingGroupLifecycle.html


你是如何设置终止实例接收生命周期钩子的?你为每个实例设置不同的队列吗?如果是这样,怎么做?还是只是滥用 SQS 的可见性超时功能来将消息传递给所有实例? - Bryan Larsen
1
好问题 - 我正在滥用可见性超时!在监视脚本中,EC2实例获取10个SQS消息并处理与其EC2实例ID匹配或为测试消息的任何消息。所有其他消息都被收集,并重置其可见性超时。这是一个权宜之计,存在一种特殊情况,即多个EC2实例上的监视器完美同步,以至于其中一个始终隐藏另一个的消息。然而,在实践中,它对我们来说一直运行良好。 - nerff
很棒,听到有人在生产中使用它工作得很好。我将可见性超时设置得非常低,似乎消息总是最终到达正确的实例,但我还没有使用它足够长的时间来对此有信心。 - Bryan Larsen
@nerff,你愿意分享一下你为此创建的脚本吗? - einstiien

10

更新

正如Ryan Walls所指出的那样(+1),AWS与此同时提供了实例保护以控制在缩小规模时Auto Scaling是否可以终止特定实例(请参见介绍性博客文章为Auto Scaling提供实例保护):

 

您可以在自动缩放组或个别自动缩放实例上启用实例保护设置。自动缩放启动实例时,实例会继承自动缩放组的实例保护设置。[...]

值得注意的是,此实例保护仅适用于常规Auto Scaling缩小规模事件:

 

实例保护无法保护Auto Scaling实例免受通过Amazon EC2控制台、terminate-instances命令或TerminateInstances API进行手动终止的影响。如果Auto Scaling实例失败并且必须被替换,则实例保护不能保护其免受终止的影响。此外,实例保护无法保护Auto Scaling组中的Spot实例免受中断的影响。

通常情况下,该功能可通过AWS管理控制台(菜单操作->实例保护->设置缩放保护),AWS CLI(set-instance-protection命令)和API(SetInstanceProtection API操作)获得。

后两个选项允许自动化当前情景,也就是说,在运行“重型处理”作业之前需要启用实例保护,并在完成后禁用实例保护,以便该实例再次有资格进行终止。


初始答案

目前,Auto ScalingAmazon EC2 实例不支持此功能。虽然您可以为自动缩放组的实例配置终止策略,但可用的策略中并没有包括这个(相当高级的)概念:

Auto Scaling 为您提供以下终止策略选项可供选择。您可以在终止策略中指定一个或多个选项。

  • OldestInstance - 如果您想终止您自动缩放组中最老的实例,请指定此选项。[...]

  • NewestInstance - 如果您想终止最近启动的实例,请指定此选项。[...]

  • OldestLaunchConfiguration - 如果您想终止使用最旧的启动配置启动的实例,请指定此选项。[...]

  • ClosestToNextInstanceHour - 如果您希望终止最接近完成计费小时的实例,请指定此选项。[...]

  • Default - 如果您想要 Auto Scaling 使用默认终止策略来选择实例进行终止,请指定此选项。


1
正如Ryan在下面的答案中已经指出,自动缩放已经实现了这个功能:https://aws.amazon.com/blogs/aws/new-instance-protection-for-auto-scaling/ 在此发表评论,因为这是被接受的答案。 - Rohit Banga

6

2

aws-cli是您最好的朋友..

  1. 在您的自动扩展组上禁用缩放策略。

  2. 使用aws-cli创建cron作业或计划任务以执行以下操作:

    2a. 获取与自动扩展组关联的EC2实例 http://docs.aws.amazon.com/cli/latest/reference/autoscaling/describe-auto-scaling-instances.html

    2b. 接下来,监视EC2实例上的CloudWatch统计信息 http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/US_SingleMetricPerInstance.html http://docs.aws.amazon.com/cli/latest/reference/cloudwatch/get-metric-statistics.html

    2c. 从您的自动扩展组中终止空闲的EC2实例 http://docs.aws.amazon.com/cli/latest/reference/autoscaling/terminate-instance-in-auto-scaling-group.html


你不一定需要aws-cli来完成这个任务。aws-sdks也具备这种能力。查找您的自动扩展组中的所有实例,检查每个实例的统计信息,然后终止它们。尽管如此,这不会使用终止策略,因为您将终止低负载实例。 - eodgooch

0

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