我是使用 AWS 的初学者。
我只想定期自动停止和启动几个 EC2 实例(不重启)。
有什么推荐的方法吗?
Amazon 最近(2018 年 2 月)发布了 EC2 instance scheduler 工具:
AWS Instance Scheduler 是一个简单的 AWS 提供的解决方案,它 使客户能够轻松配置自定义启动和停止时间表 用于他们的 Amazon Elastic Compute Cloud (Amazon EC2) 和 Amazon 关系数据库服务 (Amazon RDS) 实例。解决办法是 易于部署,有助于降低两者的运营成本 开发和生产环境。使用此服务的客户 在正常工作时间运行实例的解决方案最多可节省 与每天 24 小时运行这些实例相比,减少了 70%。
我在 15 分钟内在我的帐户中启动并运行了它;使用起来非常简单,而且几乎免费。
https://aws.amazon.com/answers/infrastructure-management/instance-scheduler/
AWS 有一个很好的文档,解释了如何使用 Lambda 和 Cloudwatch 事件来实现这一点。你可以参考它 - https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/
这个解决方案可以修改为动态获取EC2列表,或者对一组可以根据特定标签识别的实例进行操作。
是的,您可以使用 AWS Lambda 做到这一点。您可以在 Cloudwatch 中选择触发器,该触发器在 UTC 的 Cron 表达式上运行。
这里有相关链接https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/
另一种选择是使用
awscli
,可从 pip
、apt-get
、yum
或 brew
获得,然后使用您从 IAM 获得的凭据运行 aws configure
并执行以下 bash 脚本,以停止EC2 已被标记为Name: Appname
和Value: Appname Prod
。您可以使用 awscli
标记您的实例或从 AWS 控制台手动标记它。 aws ec2 stop-instances
将停止实例,jq
用于过滤 json 查询并使用来自 aws ec2 describe-instances
. 的标签获取正确的实例 ID
验证
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/
(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/
Lambda 脚本停止实例:
import json
import boto3
# Enter the region your instances are in. Include only the region without specifying Availability Zone; e.g., 'us-east-1'
region = 'us-east-1'
def lambda_handler(event, context):
ec2 = boto3.client('ec2', region_name=region)
filter = [{'Name': 'tag:Name', 'Values': ['****-env']}] //give instance name here in place of ****-env
instances = ec2.describe_instances(Filters=filter)
#ec2.stop_instances(InstanceIds=instances)
stop_instance = instances.get('Reservations')[0].get('Instances')[0].get('InstanceId')
stop_instances = []
stop_instances.append(stop_instance)
ec2.stop_instances(InstanceIds=stop_instances)
启动实例的Lambda脚本:
import json
import boto3
# Enter the region your instances are in. Include only the region without specifying Availability Zone; e.g., 'us-east-1'
region = 'us-east-1'
def lambda_handler(event, context):
ec2 = boto3.client('ec2', region_name=region)
filter = [{'Name': 'tag:Name', 'Values': ['****-env']}]
instances = ec2.describe_instances(Filters=filter)
#ec2.stop_instances(InstanceIds=instances)
start_instance = instances.get('Reservations')[0].get('Instances')[0].get('InstanceId')
start_instances = []
start_instances.append(start_instance)
ec2.start_instances(InstanceIds=start_instances)
ASG 调度程序是管理 EC2 实例的最佳和最简单的选项,如果您正在使用 ASG。如果不使用 ASG,那么您可以使用 AWS 实例调度程序 CF 解决方案或带有 cloudwatch Cron 事件的 lambda。
您现在可以使用 EventScheduler 并且现在已经全部涵盖了
首先创建一个 iAM 策略并在其中添加以下 json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ec2Stop",
"Effect": "Allow",
"Action": "ec2:StopInstances",
"Resource": "*"
}
]
}
现在创建 iAM 角色,选择自定义信任策略并在信任策略中添加以下 json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ec2Stop",
"Effect": "Allow",
"Action": "ec2:StopInstances",
"Resource": "*"
}
]
}
现在去亚马逊事件桥,创建一个调度器并指定调度器细节,你可以使用cron进行循环。然后在选择目标中选择所有 Apis 并搜索 ec2。然后搜索 stopInstances API。选择它并添加您的实例 ID。最后将角色附加到它并繁荣它全部完成以自动停止实例
同样以下是启动实例的策略其余流程保持不变
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2Start",
"Effect": "Allow",
"Action": "ec2:StartInstances",
"Resource": "*"
}
]
}