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

Posted

技术标签:

【中文标题】如何通过 Auto Scaling 防止 EC2 实例终止?【英文标题】:How can I prevent EC2 instance termination by Auto Scaling? 【发布时间】:2013-07-05 18:45:15 【问题描述】:

如果该实例正在进行某种处理,我想通过Auto Scaling 功能阻止 EC2 实例终止。

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

如何让 Auto Scaling 终止其中一个空闲实例,而不是正在处理中的实例?

【问题讨论】:

【参考方案1】:

更新

作为noted by Ryan Walls (+1),AWS 同时提供Instance Protection 控制 Auto Scaling 是否可以在缩减时终止特定实例(请参阅介绍性博客文章 Instance Protection for Auto Scaling 了解一下通过):

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

值得注意的是,此实例保护仅适用于事件中的常规 Auto Scaling 扩展:

实例保护不会保护 Auto Scaling 实例免受 通过 Amazon EC2 控制台手动终止, terminate-instances 命令或 TerminateInstances API。实例 protection 不保护 Auto Scaling 实例免于终止 如果它未能通过健康检查并且必须更换。另外,实例 protection 不保护 Auto Scaling 组中的 Spot 实例 从中断。

与往常一样,该功能可通过 AWS 管理控制台(菜单 Actions->Instance Protection->Set Scale In Protection)、AWS CLI(set-instance-protection 命令)和 API(SetInstanceProtection API 操作)。

后两个选项允许手头场景的自动化,即需要在运行“繁重的处理”作业之前启用实例保护,并在它们完成后禁用实例保护,以便实例有资格再次终止。


初步回答

此功能目前不适用于 Auto Scaling 的 Amazon EC2 实例 - 虽然您确实可以使用 Configure [an] Instance Termination Policy for Your Auto Scaling Group,但 available policies 不包含这样一个(相当高级的)概念:

Auto Scaling 为您提供以下终止策略选项 从中选择。您可以在您的 终止政策。

OldestInstance — 如果您希望终止 Auto Scaling 组中最旧的实例,请指定此项。 [...]

NewestInstance - 如果您希望终止最后启动的实例,请指定此项。 [...]

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

ClosestToNextInstanceHour - 如果您希望最接近完成计费时间的实例为 终止。 [...]

默认 - 如果您希望 Auto Scaling 使用默认终止策略来选择要终止的实例,请指定此项。

【讨论】:

正如 Ryan 在下面的回答中已经指出的那样,自动缩放已经实现了这个功能:aws.amazon.com/blogs/aws/… 在这里评论,因为这是公认的答案。【参考方案2】:

我刚刚使用相对较新的生命周期挂钩功能成功处理了 Auto Scaling 组中长时间运行的作业的问题。

在我的例子中,尝试选择一个空闲节点来终止的问题是,选择空闲节点的进程将与向节点提交工作的进程竞争。在这种情况下,最好使用可以终止任何节点的策略,但终止会优雅地发生,因此不会丢失任何工作。然后,您可以使用所有标准的 Auto Scaling 策略来管理横向扩展和横向扩展。

终止生命周期挂钩允许用户(或进程)在节点被 Auto Scaling 组置于中间状态(标记为 Terminating:Wait)后对其执行操作。然后,用户(或进程)负责通过 AWS API 调用完成生命周期操作,从而导致终止的 EC2 实例关闭。

简而言之,我的设置方式是:

创建一个允许 Auto Scaling 将消息发布到 SQS 队列的角色。 为终止消息创建一个 SQS 队列。 创建一个在每个节点中作为服务运行的监控脚本。我的脚本是一个简单的事件驱动状态机,它按顺序从 MONITORING(轮询 SQS 以获取节点的终止消息)到 DRAINING(轮询作业队列,直到节点上没有执行任何工作)再到 TERMINATED(完成-生命周期调用)。 事件驱动的 AWS 自动扩展的标准配置;也就是说,创建 CloudWatch 警报,以及用于扩展和扩展的自动扩展策略。

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

相关的 AWS 文档在这里:

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

【讨论】:

您是如何设置它以便终止实例接收生命周期挂钩的?您是否为每个实例设置不同的队列?如果是这样,怎么做?还是只是滥用 SQS 的可见性超时功能,让它将消息传递给所有实例? 好问题 - 我正在滥用可见性超时!在监控脚本中,EC2 实例抓取十个 SQS 消息并处理任何与其 EC2 实例 ID 匹配的消息或测试消息。收集所有其他人,并重置其可见性超时。这是一个杂乱无章的问题,并且有可能出现一个极端情况,即多个 EC2 实例上的监视器同步得非常完美,以至于一个总是对另一个隐藏消息。然而,在实践中,它对我们来说效果很好。 酷,很高兴听到它在生产中为某人工作。我将可见性超时设置得非常低,而且消息似乎总是最终到达正确的实例,但我使用它的时间还不够长,对此没有信心。 @nerff 你愿意分享你为此创建的脚本吗?【参考方案3】:

亚马逊终于以更简单的方式解决了这个问题。现在有“实例保护”,您可以在其中将您的实例标记为受保护,并且它不会在“缩减”期间终止。

见https://aws.amazon.com/blogs/aws/new-instance-protection-for-auto-scaling

【讨论】:

【参考方案4】:

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

    在您的自动扩缩组上禁用缩减策略。

    使用 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 也有这种能力。查找自动缩放组中的所有实例,检查每个实例的统计信息,然后终止。虽然,这不会使用终止策略,因为您将称为低负载实例。【参考方案5】:

您可以使用 Amazon CloudWatch 来实现: http://aws.typepad.com/aws/2013/01/amazon-cloudwatch-alarm-actions.html。来自文章:

您可以使用类似的策略来摆脱负责处理计算密集型批处理的实例。一旦 CPU 空闲并且工作完成,终止实例并节省一些钱!

在这种情况下,由于您将处理终止,因此您需要删除缩减政策。另请参阅另一个选项:https://***.com/a/19628453/432849。

【讨论】:

以上是关于如何通过 Auto Scaling 防止 EC2 实例终止?的主要内容,如果未能解决你的问题,请参考以下文章

AWS EC2 Auto Scaling 同步如何自动工作?

Amazon EC2 Auto Scaling 如何工作?

如何在 Amazon EC2 上配置基于内存的 Auto Scaling?

Ansible:将正在运行的 EC2 实例添加到 Auto-scaling 组

如何转换 Amazon EC2 实例以用于 Auto Scaling?

如何在 AWS EC2 上为 Rancher 和 Kubernetes 集群做 Auto Scaling?