如何自动停止和启动AWS EC2实例

时间:2018-03-07 09:11:05

标签: amazon-web-services amazon-ec2 instance

我是使用AWS的初学者。

我只想自动定期停止并启动几个EC2实例(不重启)。

有没有推荐的方法呢?

6 个答案:

答案 0 :(得分:5)

亚马逊最近(2018年2月)发布了EC2实例调度工具:

  

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/

答案 1 :(得分:2)

是的,您可以使用AWS Lambda执行此操作。您可以在Cloudwatch中选择在UTC上的Cron表达式上运行的触发器。

以下是相关链接https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/

另一种方法是使用awsclipipapt-getyum提供的brew,然后运行aws configure来自IAM的凭据并执行以下bash脚本,以停止已使用Name: AppnameValue: Appname Prod标记的EC2。您可以使用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/stop30 14 * * *是您可以在https://crontab.guru/

中查看的UTC cron表达式

答案 2 :(得分:2)

AWS有一个很好的文档,解释了如何使用Lambda和Cloudwatch事件实现这一目标。你可以参考它 - https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/

可以修改此解决方案以动态获取EC2列表,或对可以基于特定标记识别的一组实例进行操作。

答案 3 :(得分:0)

用于停止实例的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)

答案 4 :(得分:0)

如果使用ASG,

ASG调度程序是管理EC2实例的最佳和最简单的选择。如果未使用ASG,则可以将AWS实例计划程序CF解决方案或lambda与cloudwatch Cron事件一起使用。

答案 5 :(得分:0)

在GitHub上有一个名为clonesquad的项目,看起来很有趣,可以管理“宠物” EC2实例(当您必须管理宠物时...):https://github.com/jcjorel/clonesquad/ 它看起来像是由一组Lambda函数构建的自动缩放器... 尚未测试。