在不活动的情况下以编程方式停止 AWS EC2

Posted

技术标签:

【中文标题】在不活动的情况下以编程方式停止 AWS EC2【英文标题】:Programmatically Stop AWS EC2 in case of inactivity 【发布时间】:2020-11-19 19:57:38 【问题描述】:

如果开发环境的 AWS Windows Server EC2 实例没有任何活动,例如在 2 小时不活动后,我们可以停止它吗?我无法确定是否有任何用户以虚拟方式连接到服务器。

我可以通过编程方式在固定时间轻松启动/停止 EC2,但为了降低服务器成本,我试图在 EC2 不使用时停止它。

我的意图(或用例)是:如果在指定时间内没有用户使用 EC2,它将自动停止。开发人员可以在需要时重新启动它。

【问题讨论】:

在 ec2 中运行什么样的应用程序?以及如何定义空闲状态?活动连接或其他一些假设指标? 见serverfault.com/questions/490886/… 接受 tpschmidt 的回答;这是完美的 【参考方案1】:

这不是一项简单的任务。

Amazon EC2 服务提供具有 RAM、CPU 和磁盘的虚拟计算机。它可以查看 CPU 上的活动量、网络流量和磁盘访问,但它无法查看操作系统

所以,问题变成了如何检测“不活动”。这实际上归结为操作系统并做出一些艰难的决定。例如,您的家庭计算机屏幕在定义的没有鼠标/键盘输入的时间后关闭,但操作系统仍在后台执行活动。如果系统正在运行诸如 Web 服务器之类的应用程序,并且没有 Web 请求,则很难知道这是因为没有请求而处于“不活动”状态,还是因为 Web 服务器正在运行而处于“活动状态”。

底线:没有开箱即用的功能可以做到这一点。您需要找到自己对“不活动”的定义,然后在操作系统中触发关机。

如果您希望按计划进行,这可能会有所帮助:Auto-Stop EC2 instances when they finish a task - DEV Community

【讨论】:

这是我在阅读您的问题时的看法。但是,如果您希望 AWS 而不是您的 EC2 来处理它,您可以将您的日志导出到 CloudWatch,分析它们并触发事件。 CloudWatch 只能提供 CPU 利用率、网络和磁盘访问。在我看来,仅凭这一点不足以决定“不活动”。但是,我同意可以分析过去的指标,查看活动期间和不活动期间的模式,然后可能做出决定。坦率地说,在实例本身上运行的程序更容易检测“活动”,因为它可以访问更丰富的数据。 还是同意,CPU/RAM 不是“不活动”。我的意思是 CloudWatch Logs。它可以用作日志集中工具来监控日志并触发 Lambda 处理的警报。以防万一有人真的需要在 EC2 之外处理此分析。 这在大多数情况下是一个简单的任务,但如果要概括它并不简单。大多数用例可以使用一段时间内的平均 CPU 或平均网络或平均 I/O 进行检测。【参考方案2】:

更新:不再需要 Lambda,请参阅 tpschmidt 的回答。

创建一个 Lambda 以关闭将由 Cloud Watch 警报触发的 EC2,例如,当 CPU 低于 20% 平均一小时。这在您编码时很好,因为您将使用超过 20% 的电量,而当您有一个多小时的休息时间时,您希望将其关闭。

请务必在您的 IDE 中设置自动保存。

Python Lambda 示例:

import boto3
region = 'eu-west-3'
instances = ['i-05be5c0c4039881ed']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
    #TODO getInstanceIDFromCloudWatch = event["instanceid"]
    ec2.stop_instances(InstanceIds=instances)
    print('stopped your instances: ' + str(instances))

参考:https://www.howtoforge.com/aws-lambda-function-to-start-and-stop-ec2-instance/

在 AWS 控制台中:

    转到 EC2,选择 EC2 实例并复制实例 ID

    转到 Cloud Watch 并选择指标

    在 AWS 命名空间下单击 EC2

    粘贴实例 ID 以找到它

    选择 EC2 > 每实例指标

    选择第一个指标 CPU 利用率

    选择名为 Graphed Metric 的第二个选项卡

    点击操作下的铃铛图标

    设置一个阈值,这也是最难的部分,保留默认统计:平均超过 1 小时

    设置 Condition Lower/Equal 并将值设置为 20%(您需要在超过 20% CPU 的情况下使用机器超过 1/5 小时,否则它会关闭)。

    接下来创建一个警报,设置一个通知,如果你喜欢或删除它

    警报创建后

    在 Cloud Watch 中选择事件 > 规则

    添加规则

    选择 EC2 作为服务名称和所有事件

    点击 Target 并选择您的 Lambda。

    当警报响起时,Lambda 将关闭实例 ID

ps 稍微偏离主题,但有一个名为osiris 的项目允许缩放到零.. 它不适用于 ASG 中的 EC2,它适用于 Kubernetes。Osiris 通过允许空闲工作负载自动缩放到零并允许缩放到零的工作负载自动重新调整,从而在 Kubernetes 集群中实现更高的资源效率- 由入站请求按需激活。

【讨论】:

不需要 lambda 函数;可以完全在 cloudwatch 中通过点击完成。请参阅下面@tpschmidt 的回答【参考方案3】:

最简单的解决方案可能是使用 CloudWatch 设置警报。

有一个read at the documentation,它基本上完美地描述了你的用例:

您可以创建一个警报,在出现以下情况时停止 Amazon EC2 实例 达到一定的门槛

条件可以是平均 CPU 利用率,例如CPU 利用率低于某个点(这很可能与没有登录用户/没有开发人员实际使用机器有关)。

【讨论】:

这对我来说似乎是最好的解决方案。上面的 lambda 函数只是执行“停止”操作,但在 cloud watch 中会处理这些操作。所以它是一个快速的无代码解决方案。结合接受答案的建议,在一小时内选择 cpu utilisaiton docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/… 最佳答案 - 无需任何代码即可轻松完成,甚至下拉列表中提供了实例 ID,并且只需要配置一个服务 cloudwatch。

以上是关于在不活动的情况下以编程方式停止 AWS EC2的主要内容,如果未能解决你的问题,请参考以下文章

在不继承 UINavigationController 的情况下以编程方式更改 ViewController 的方向

如何在不编码窗口状态的情况下以编程方式终止 NSApp?

是否可以在不替换的情况下以编程方式修改/更新 plist 文件?

如何在不“连接”它们的情况下以编程方式访问 NIB 中的 UI 元素?

如何在不使用命令的情况下以编程方式关闭/重启 linux 机器(运行时)

如何在没有 XML 的情况下以编程方式将片段添加到活动