2010-03-09 226 views
84

我可以使用Amazon API自动启动和终止我的Amazon实例吗?你能否描述如何做到这一点?理想情况下,我需要每天以指定的时间间隔启动实例并停止实例。自动关闭并启动Amazon EC2实例

+2

EC2实例关闭时会发生什么?它是否持续存在,或者您是否必须重新构建它? –

+0

使用Amazon API自动启动和终止实例可能会导致该事件丢失数据。我建议使用[* AWS CloudWatch警报*]停止和恢复操作(http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/UsingAlarmActions.html) – hyip

+0

亚马逊API istead,我会建议到[*使用AWS Lambda *计划EC2开始/停止](http://stackoverflow.com/a/38371889/4058484),在您的情况下,它的成本低于$ 0.0004美元/月。 – hyip

回答

99

为防万一有人在这个老问题上磕磕绊绊,现在您可以通过向自动缩放组添加时间表来实现同样的目的:在某些时间将自动缩放组中的实例数量增加到1,并减少它之后回到0。

而且因为这个答案是获得了很多的意见,我想链接到这个一个非常有用的指南:Running EC2 Instances on a Recurring Schedule with Auto Scaling

+3

这里最好的芒。 –

+5

我尝试了链接中描述的方法,它确实在本教程指定的时间开始/停止实例。但是,我注意到在AWS Web控制台中,当通过此方法启动实例时,它不会从一个键开始(这样您就可以ssh进入它),而且它似乎也没有与我一样的东西安装在我用作测试的微型实例上(我不是云计算专家,但我认为这意味着这个新启动的实例没有连接到EBS?)有没有办法自动启动和按时间表停止* same *实例? –

+0

@KiranK。这是否意味着新实例未附加到当前使用的EBS卷上?你用了什么? –

16

我建议你看看EC2 Getting Started Guide,它向你展示了如何使用EC2命令行工具来做你需要的。您可以轻松地将此脚本编写到cron作业(在Linux/UNIX上)或Windows上的预定作业,以在给定时间调用启动和停止命令。

如果您想从自己的代码执行此操作,则可以使用SOAP或REST API;详情请参阅Developer Guide

1

你可以看看Ylastic来做到这一点。另一种方法似乎是让一台机器运行,关闭/使用cron作业或计划任务启动其他实例。

显然,如果您只想要一个实例,这是一个昂贵的解决方案,因为一台机器必须始终运行,并且每台机器每月支付$ 80以运行cron作业不符合成本效益。

-8

你不能自动执行此操作,或者至少不能在脚本文件中没有编程和API操作。如果你想要一个可靠的解决方案来停止,重新启动和管理你的图像(大概是为了控制你的环境中的成本),那么你可能想看看LabSlice。免责声明:我为这家公司工作。

3

如果它不是关键任务 - 一个简单的事情就是安排批处理文件每天凌晨3点运行'SHUTDOWN'(windows)。那么至少你不会冒着无意中让一个不需要的实例无限期地运行的风险。

显然这只是故事的一半!

24

您可以尝试直接使用Amazon EC2 API工具。有 真的只有你需要的两个命令:ec2-start-instances和ec2-stop-instances。 确保环境变量,如EC2_HOME, AWS_CREDENTIAL_FILE,EC2_CERT,EC2_PRIVATE_KEY等都是正确 配置和所有AWS证书,证书和私钥文件 是在正确的位置 - 你可以找到AWS EC2 API 更多信息工具文档。

您可以先手动测试命令,然后当一切正常时, 在Windows上配置Unix crontab或Scheduled Tasks。您可以在Linux/etc/crontab文件中找到下面的 示例(不要忘记所有 上述的环境变量都需要在 “your-account”用户中出现。

/etc/crontab 
0 8  * * * your-account ec2-start-instances <your_instance_id> 
0 16 * * * your-account ec2-stop-instances <your_instance_id> 
# Your instance will be started at 8am and shutdown at 4pm. 

我的BitNami云项目,在这里我们打包 AWS工具(包括我提到的那些)在一个自由,易于使用的 安装程序,你可能想尝试开发者:BitNami CloudTools pack stack

+2

对于这仍然需要有另一个实例。因为关机不是问题,而是启动。克隆或任何东西在关闭后都不会在死机中运行。 –

+0

我遵循[这些步骤](http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/set-up-ec2-cli-linux.html#set-up-ec2-cli-tools-on- amazon-linux)在我的AMazon Linux实例上设置AWS CLI工具。 停止实例正常工作。但是,启动一个已经停止的实例会导致400错误,找不到实例Id。我如何启动已停止的实例? –

5

我所在的公司有客户经常询问有关这方面的工作,所以我们已经写了一个免费的EC2调度可在这里应用:

http://blog.simple-help.com/2012/03/free-ec2-scheduler/

它可以在Windows和Mac上运行,可以创建多个每日/每周/每月的日程安排,并允许您使用匹配筛选器轻松包含大量实例,或者包含将来添加的实例。

15

我用Python编写代码,使用Boto程式库,做到这一点。您可以调整它以供自己使用。确保将它作为cron作业的一部分运行,然后在cron作业运行期间,您可以根据需要启动或关闭尽可能多的实例。

#!/usr/bin/python 
# 
# Auto-start and stop EC2 instances 
# 
import boto, datetime, sys 
from time import gmtime, strftime, sleep 

# AWS credentials 
aws_key = "AKIAxxx" 
aws_secret = "abcd" 

# The instances that we want to auto-start/stop 
instances = [ 
    # You can have tuples in this format: 
    # [instance-id, name/description, startHour, stopHour, ipAddress] 
    ["i-12345678", "Description", "00", "12", "1.2.3.4"] 
] 

# -------------------------------------------- 

# If its the weekend, then quit 
# If you don't care about the weekend, remove these three 
# lines of code below. 
weekday = datetime.datetime.today().weekday() 
if (weekday == 5) or (weekday == 6): 
    sys.exit() 

# Connect to EC2 
conn = boto.connect_ec2(aws_key, aws_secret) 

# Get current hour 
hh = strftime("%H", gmtime()) 

# For each instance 
for (instance, description, start, stop, ip) in instances: 
    # If this is the hour of starting it... 
    if (hh == start): 
     # Start the instance 
     conn.start_instances(instance_ids=[instance]) 
     # Sleep for a few seconds to ensure starting 
     sleep(10) 
     # Associate the Elastic IP with instance 
     if ip: 
      conn.associate_address(instance, ip) 
    # If this is the hour of stopping it... 
    if (hh == stop): 
     # Stop the instance 
     conn.stop_instances(instance_ids=[instance]) 
+0

这对于Elastic Beanstalk环境也可能吗? –

0

我相信最初的问题有点混乱。这取决于面食需要什么: 1.启动/终止(实例存储) - Auto Scaling是正确的解决方案(Nakedible的答案) 2.启动/停止EBS启动实例 - Auto Scaling不会帮助,我使用远程调度脚本(即,ec2 CLI)。

1

AutoScaling仅限于终止实例。如果你想停止一个实例并保留服务器状态,那么外部脚本是最好的方法。

您可以通过在另一个全天候运行的实例上运行作业来完成此任务,也可以使用第三方服务,如Ylastic(上述)或Rocket Peak

例如在C#代码停止服务器是相当简单:

public void stopInstance(string instance_id, string AWSRegion) 
     { 
      RegionEndpoint myAWSRegion = RegionEndpoint.GetBySystemName(AWSRegion); 
      AmazonEC2 ec2 = AWSClientFactory.CreateAmazonEC2Client(AWSAccessKey, AWSSecretKey, myAWSRegion); 
      ec2.StopInstances(new StopInstancesRequest().WithInstanceId(instance_id)); 
     } 
1

IMHO添加日程到自动缩放团是最好的“云状”的方法如前所述。

但如果你不能终止您的实例,并使用新的,例如,如果你有相关的弹性IP地址等

您可以创建一个Ruby脚本启动和停止基于日期的情况下,时间范围。

#!/usr/bin/env ruby 

# based on https://github.com/phstc/amazon_start_stop 

require 'fog' 
require 'tzinfo' 

START_HOUR = 6 # Start 6AM 
STOP_HOUR = 0 # Stop 0AM (midnight) 

conn = Fog::Compute::AWS.new(aws_access_key_id:  ENV['AWS_ACCESS_KEY_ID'], 
          aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']) 

server = conn.servers.get('instance-id') 

tz = TZInfo::Timezone.get('America/Sao_Paulo') 

now = tz.now 

stopped_range = (now.hour >= STOP_HOUR && now.hour < START_HOUR) 
running_range = !stopped_range 

if stopped_range && server.state != 'stopped' 
    server.stop 
end 

if running_range && server.state != 'running' 
    server.start 

    # if you need an Elastic IP 
    # (everytime you stop an instance Amazon dissociates Elastic IPs) 
    # 
    # server.wait_for { state == 'running' } 
    # conn.associate_address server.id, 127.0.0.0 
end 

看一看amazon_start_stop创建免费使用Heroku Scheduler调度。

1

即使有方法可以使用自动缩放来实现这一点,但它可能并不适合所有场合,因为它会终止实例。Cron作业永远不会用于单个实例(尽管它可以完美地用于诸如在运行多个实例时停止单个实例和调度其他实例的情况)。您可以使用像StartInstancesRequestStopInstancesRequest这样的API调用来实现相同的功能,但您必须依靠第三个资源。有许多应用程序可以安排具有许多功能的AWS实例,但对于简单的解决方案,我会推荐免费的应用程序,如snapleaf.io

2

AWS Data Pipeline工作正常。 https://aws.amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instances/

如果您希望排除开始(例如周末)的日子,请添加一个ShellCommandPrecondition对象。

在AWS控制台/数据管道中,创建一个新管道。这是easyer编辑/导入定义(JSON)

{ 
"objects": [ 
{ 
    "failureAndRerunMode": "CASCADE", 
    "schedule": { 
    "ref": "DefaultSchedule" 
    }, 
    "resourceRole": "DataPipelineDefaultResourceRole", 
    "role": "DataPipelineDefaultRole", 
    "pipelineLogUri": "s3://MY_BUCKET/log/", 
    "scheduleType": "cron", 
    "name": "Default", 
    "id": "Default" 
}, 
{ 
    "name": "CliActivity", 
    "id": "CliActivity", 
    "runsOn": { 
    "ref": "Ec2Instance" 
    }, 
    "precondition": { 
    "ref": "PreconditionDow" 
    }, 
    "type": "ShellCommandActivity", 
    "command": "(sudo yum -y update aws-cli) && (#{myAWSCLICmd})" 
}, 
{ 
    "period": "1 days", 
    "startDateTime": "2015-10-27T13:00:00", 
    "name": "Every 1 day", 
    "id": "DefaultSchedule", 
    "type": "Schedule" 
}, 
{ 
    "scriptUri": "s3://MY_BUCKET/script/dow.sh", 
    "name": "DayOfWeekPrecondition", 
    "id": "PreconditionDow", 
    "type": "ShellCommandPrecondition" 
}, 
{ 
    "instanceType": "t1.micro", 
    "name": "Ec2Instance", 
    "id": "Ec2Instance", 
    "type": "Ec2Resource", 
    "terminateAfter": "50 Minutes" 
} 
], 
"parameters": [ 
{ 
    "watermark": "aws [options] <command> <subcommand> [parameters]", 
    "description": "AWS CLI command", 
    "id": "myAWSCLICmd", 
    "type": "String" 
} 
], 
"values": { 
"myAWSCLICmd": "aws ec2 start-instances --instance-ids i-12345678 --region eu-west-1" 
} 
} 

把bash脚本来才可下载和前提在S3存储桶执行

#!/bin/sh 
if [ "$(date +%u)" -lt 6 ] 
then exit 0 
else exit 1 
fi 

激活和上周末两天运行的管道, AWS控制台管道健康状态读取误导性的“错误”。 bash脚本返回一个错误(出口1),并且EC2未启动。在第1天至第5天,状态为“健康”。

要在关闭办公室时自动停止EC2,请每日使用AWS CLI命令,而不要使用前提条件。

相关问题