自动终止的AWS EC2实例?

100

亚马逊网络服务的EC2实例是否有自我终止的方法? 亚马逊是否有任何功能允许一个实例在运行超过一小时后终止自己("Hara-Kiri")? 我可以更改正在运行实例上的脚本以进行自我终止,但这可能会失败,而我不想编辑镜像,因此我希望亚马逊来终止该实例。


2
只是为了澄清,如果实例持续时间超过X个小时,我需要一个紧急停机开关。我的用例是,我使用亚马逊的EC2快速旋转实例,在Ubuntu上运行一些进程(大约需要5分钟),然后关闭自身。这由Windows桌面应用程序控制。大多数情况下它都像魅力一样工作,但有时用户关闭他们的笔记本电脑并度假一周,你猜怎么着,我必须支付168小时的AWS费用,而我不需要这么长时间。 如果有人想要更多细节,我可以告诉你所有的事情。 史蒂夫 - Steve3p0
5个回答

121

要使实例自行终止,请按以下两个步骤操作:

  1. 使用 --instance-initiated-shutdown-behavior terminate 或 AWS 控制台/ API 调用上的等效选项启动实例。
  2. 以 root 用户身份运行 shutdown -h now。在 Ubuntu 上,您可以使用以下命令将其设置为 55 分钟后发生:

  3. echo "sudo halt" | at now + 55 minutes
    
    我之前写了一篇文章,介绍了实现"一个小时后自动终止"的其他选项:

    Amazon EC2 上临时实例的自动终止
    http://alestic.com/2010/09/ec2-instance-termination

    这篇文章最初是在 instance-initiated-shutdown-behavior 可用之前编写的,但你可以在评论中找到更新和其他有用的信息。

Eric,谢谢您,但我不知道在AWS控制台上如何执行第一步骤。我在“请求实例向导”中看到了“关闭行为”设置,但唯一的选项是“终止”和“停止”。这并没有真正安排实例在一个小时内停止。我将检查我正在使用启动实例的AWS .NET API,看看是否可以执行此类操作。 - Steve3p0
7
当您想要终止实例时,将“关机行为”设置为“终止”,然后执行“halt”或“shutdown -h now”。 使用“at”提前进行计划。 (1)和(2)是单个过程中必需的步骤,而不是替代方法。 - Eric Hammond
2
有没有特别的原因使用“shutdown -h now”而不是“shutdown -P now”? - Dustin Boswell
3
@EricHammond 我问这个问题的原因是我的实例在关闭时大约有5%的概率失败(它们会陷入一种卡住的状态,正在运行但无法停止并且无法通过SSH访问)。只是想知道这可能是原因。 - Dustin Boswell
3
@DustinBoswell 可能是你正在使用的命令是“halt”或“shutdown -h”,这与“poweroff”不同,具体取决于系统设置。请尝试使用“sudo poweroff”(或“sudo shutdown -P now”,但我更喜欢“poweroff”因为它更详细),替代原有命令。 - AntonioMO

26

你可以做到这件事

ec2-terminate-instances $(curl -s http://169.254.169.254/latest/meta-data/instance-id)

EC2将获取其当前实例ID并终止自身。


4
我喜欢这种方法......但它需要在实例上设置凭据才能运行terminate-instances。这并非总是如此,否则您将会收到“Client.UnauthorizedOperation”错误提示。 - RaveTheTadpole
6
你可以设置一个实例配置文件,这样就不需要设置凭证了。 - galva
@RaveTheTadpole 如果你想让一个实例终止自身,它需要获得终止自身的权限。这是一个隐含的条件。 - polvoazul

14

希望这会奏效

instanceId=$(curl http://169.254.169.254/latest/meta-data/instance-id/)
region=$(curl http://169.254.169.254/latest/dynamic/instance-identity/document | grep region | awk '{print $3}' | sed  's/"//g'|sed 's/,//g')

/usr/bin/aws ec2 terminate-instances --instance-ids $instanceId --region $region

希望这可以帮到您!!!


谢谢!我稍微修改了一下,不知道你是否使用jq,但无论如何我想分享一下。region=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region) - D.Fitz

8
这是我的用于“自我终止”的脚本。
$ EC2_INSTANCE_ID="`wget -q -O - http://instance-data/latest/meta-data/instance-id || die \"wget instance-id has failed: $?\"`"
$ echo "ec2-terminate-instances $EC2_INSTANCE_ID" | at now + 55 min || die 'cannot obtain instance-id'

如果您想将其指定为自停止,则只能执行一次。在您的EC2控制台中,转到实例设置,将关闭行为更改为停止
配置/etc/cloud/cloud.cfg,您可以参考如何使用cloud-init运行引导脚本
按照Eric Hammond的答案,将命令放入文件并将其定位在scripts-per-boot路径中即可。
$ echo '#!/bin/sh' > per-boot.sh
$ echo 'echo "halt" | at now + 55 min' >> per-boot.sh
$ echo 'echo per-boot: `date` >> /tmp/per-boot.txt' >> per-boot.sh
$ chmod +x per-boot.sh
$ sudo chown -R root per-boot.sh
$ sudo mv -viu per-boot.sh /var/lib/cloud/scripts/per-boot

重新启动您的实例,检查脚本是否已执行:

$ cat /tmp/per-boot.txt 
per-boot: Mon Jul 4 15:35:42 UTC 2016

如果是这样的话,以防您忘记停止实例,它会确保在运行了55分钟或者您在脚本中设置的任何时间后,实例将自行终止为停止状态。
Broadcast message from root@ip-10-0-0-32
        (unknown) at 16:30 ...

The system is going down for halt NOW!

PS:对于想要使用 自停止 功能的用户,需要注意并非所有的 EC2 类型在重启后都能自动恢复。我建议使用 EC2-VPC/EBS开/关时间表


0
我有一个类似的需求,需要在Web应用程序中启动EC2实例。我无法信任Web应用程序来停止/终止实例,因此我创建了一个脚本在单独的进程中运行,称为“feeder”。Feeder负责停止/终止实例。Web应用程序必须定期请求feeder“feed”实例。如果实例“饥饿”(在超时期内未被喂养),feeder将停止/终止它。可以在不同的机器上同时运行两个feeder以防止一个feeder进程出现问题。换句话说,实例在压力开关上运行。当释放压力时,实例将停止/终止。这也允许我在多个用户之间共享实例。
对于最初的问题,feeder可以在EC2实例本身中运行,消除了预先知道任务运行时间的需要,但它会给应用程序提供定期喂养的负担。如果笔记本电脑关闭,实例将关闭。
feeder位于https://github.com/alessandrocomodi/fpga-webserver,并具有宽松的开源许可证。

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