我可以使用Amazon API自动启动和终止我的Amazon实例吗?您能描述一下如何做到吗?理想情况下,我每天需要启动实例并以指定的时间间隔停止实例。
我可以使用Amazon API自动启动和终止我的Amazon实例吗?您能描述一下如何做到吗?理想情况下,我每天需要启动实例并以指定的时间间隔停止实例。
Answers:
以防万一有人偶然发现了这个老问题,如今,您可以通过向自动伸缩组添加时间表来实现相同的目的:在特定时间将自动伸缩组中的实例数量增加到1,然后将其减少到0 。
而且,由于该答案引起了广泛的关注,因此我认为可以链接到有关此问题的非常有用的指南:使用Auto Scaling按定期计划运行EC2实例
您可以尝试直接使用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或“计划任务”。您可以在下面的Linux / etc / crontab文件中找到示例(不要忘记,“您的帐户”用户必须具备上述所有这些环境变量。
/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 Cloud项目的开发人员,我们在其中将AWS工具(包括我提到的工具)打包在一个免费的,易于使用的安装程序中,您可以尝试安装该程序: BitNami CloudTools程序包堆栈
我使用Boto库用Python编写了代码。您可以自行调整。确保将其作为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])
我所服务的公司有客户定期询问此问题,因此我们编写了一个免费的EC2调度应用程序,可在此处使用:
http://blog.simple-help.com/2012/03/free-ec2-scheduler/
它可在Windows和Mac上运行,可让您创建多个每日/每周/每月计划,并使用匹配的过滤器轻松地包含大量实例或包含将来添加的实例。
AWS Data Pipeline运行正常。https://aws.amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instances/
如果希望从开始就排除几天(例如,周末),请添加ShellCommandPrecondition对象。
在AWS Console /数据管道中,创建一个新管道。编辑/导入定义(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控制台管道运行状况会读取一个误导性的“ ERROR”。bash脚本返回错误(退出1),并且EC2未启动。在第1到5天,状态为“健康”。
要在办公时间关闭时自动停止EC2,请每天使用AWS CLI命令并没有先决条件。
AutoScaling仅限于终止实例。如果要停止实例并保留服务器状态,则最好使用外部脚本。
您可以通过在另一个运行24/7的实例上运行作业来执行此操作,也可以使用第三方服务,例如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));
}
恕我直言,将时间表添加到自动伸缩组是如上所述的最佳“类似于云”的方法。
但是,如果您无法终止实例并使用新实例,例如,如果您具有与etc相关联的弹性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免费创建一个调度程序。
即使有多种方法可以使用自动缩放来实现此目的,但由于终止实例,它可能并不适合所有情况。Cron作业永远不会在单个实例上运行(尽管它可以完美地用于在运行多个实例时停止单个实例并调度其他实例的情况)。您可以使用诸如StartInstancesRequest和StopInstancesRequest之类的API调用来实现相同目的,但是同样,您必须依靠第三种资源。有许多应用程序可以计划具有许多功能的AWS实例,但是对于一个简单的解决方案,我建议使用免费的应用程序,例如snapleaf.io
是的,您可以使用AWS Lambda做到这一点。您可以在Cloudwatch中选择触发器,该触发器在UTC的Cron表达式上运行。
这是一个相关链接https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/
另一种方法是使用awscli
它可以从pip
,apt-get
,yum
或brew
,然后运行aws configure
与您的凭据从IAM导出并执行以下bash脚本,以停止已标有EC2 Name: Appname
和Value: Appname Prod
。您可以使用awscli
标记实例或从AWS控制台手动标记实例。aws ec2 stop-instances
将停止实例,jq
并用于过滤json查询并使用中的标记获取正确的实例ID aws ec2 describe-instances
。
要验证是否aws configure
成功并返回json输出aws ec2 describe-instances
,请在输出中找到您正在运行的实例ID。这是示例输出
{
"Reservations": [
{
"Instances": [
{
"Monitoring": {
"State": "disabled"
},
"PublicDnsName": "ec2-xxx.ap-south-1.compute.amazonaws.com",
"State": {
"Code": xx,
"Name": "running"
},
"EbsOptimized": false,
"LaunchTime": "20xx-xx-xxTxx:16:xx.000Z",
"PublicIpAddress": "xx.127.24.xxx",
"PrivateIpAddress": "xxx.31.3.xxx",
"ProductCodes": [],
"VpcId": "vpc-aaxxxxx",
"StateTransitionReason": "",
"InstanceId": "i-xxxxxxxx",
"ImageId": "ami-xxxxxxx",
"PrivateDnsName": "ip-xxxx.ap-south-1.compute.internal",
"KeyName": "node",
"SecurityGroups": [
{
"GroupName": "xxxxxx",
"GroupId": "sg-xxxx"
}
],
"ClientToken": "",
"SubnetId": "subnet-xxxx",
"InstanceType": "t2.xxxxx",
"NetworkInterfaces": [
{
"Status": "in-use",
"MacAddress": "0x:xx:xx:xx:xx:xx",
"SourceDestCheck": true,
"VpcId": "vpc-xxxxxx",
"Description": "",
"NetworkInterfaceId": "eni-xxxx",
"PrivateIpAddresses": [
{
"PrivateDnsName": "ip-xx.ap-south-1.compute.internal",
"PrivateIpAddress": "xx.31.3.xxx",
"Primary": true,
"Association": {
"PublicIp": "xx.127.24.xxx",
"PublicDnsName": "ec2-xx.ap-south-1.compute.amazonaws.com",
"IpOwnerId": "xxxxx"
}
}
],
"PrivateDnsName": "ip-xxx-31-3-xxx.ap-south-1.compute.internal",
"Attachment": {
"Status": "attached",
"DeviceIndex": 0,
"DeleteOnTermination": true,
"AttachmentId": "xxx",
"AttachTime": "20xx-xx-30Txx:16:xx.000Z"
},
"Groups": [
{
"GroupName": "xxxx",
"GroupId": "sg-xxxxx"
}
],
"Ipv6Addresses": [],
"OwnerId": "xxxx",
"PrivateIpAddress": "xx.xx.xx.xxx",
"SubnetId": "subnet-xx",
"Association": {
"PublicIp": "xx.xx.xx.xxx",
"PublicDnsName": "ec2-xx.ap-south-1.compute.amazonaws.com",
"IpOwnerId": "xxxx"
}
}
],
"SourceDestCheck": true,
"Placement": {
"Tenancy": "default",
"GroupName": "",
"AvailabilityZone": "xx"
},
"Hypervisor": "xxx",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xxx",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": true,
"VolumeId": "vol-xxx",
"AttachTime": "20xxx-xx-xxTxx:16:xx.000Z"
}
}
],
"Architecture": "x86_64",
"RootDeviceType": "ebs",
"RootDeviceName": "/dev/xxx",
"VirtualizationType": "xxx",
"Tags": [
{
"Value": "xxxx centxx",
"Key": "Name"
}
],
"AmiLaunchIndex": 0
}
],
"ReservationId": "r-xxxx",
"Groups": [],
"OwnerId": "xxxxx"
}
]
}
下面的bash脚本是stop-ec2.sh
在/home/centos/cron-scripts/
其灵感来自这个职位的SO
(instance=$(aws ec2 describe-instances | jq '.Reservations[].Instances | select(.[].Tags[].Value | startswith("Appname Prod") ) | select(.[].Tags[].Key == "Appname") | {InstanceId: .[].InstanceId, PublicDnsName: .[].PublicDnsName, State: .[].State, LaunchTime: .[].LaunchTime, Tags: .[].Tags} | [.]' | jq -r .[].InstanceId) && aws ec2 stop-instances --instance-ids ${instance} )
使用运行文件,sh /home/centos/cron-scripts/stop-ec2.sh
并验证EC2实例是否已停止。要调试运行aws ec2 describe-instances | jq '.Reservations[].Instances | select(.[].Tags[].Value | startswith("Appname Prod") ) | select(.[].Tags[].Key == "Appname") | {InstanceId: .[].InstanceId, PublicDnsName: .[].PublicDnsName, State: .[].State, LaunchTime: .[].LaunchTime, Tags: .[].Tags} | [.]' | jq -r .[].InstanceId
并查看它是否返回已标记的正确实例ID。
然后可以在crontab -e
下面的行中添加
30 14 * * * sh /home/centos/cron-scripts/stop-ec2.sh >> /tmp/stop
这会将输出记录到/tmp/stop
。30 14 * * *
您可以检入的是UTC cron表达式https://crontab.guru/
。同样,替换为aws ec2 start-instances
可以启动实例。
您无法自动执行此操作,或者至少不能没有脚本文件中的某些编程和API操作。如果您想要一个可靠的解决方案来停止,重新启动和管理映像(大概是为了控制您环境中的成本),则可能需要考虑LabSlice。免责声明:我在这家公司工作。