it-swarm.com.de

Automatisches Herunterfahren und Starten der Amazon EC2-Instanz

Kann ich meine Amazon-Instanz mithilfe der Amazon-API automatisch starten und beenden? Kannst du bitte beschreiben, wie das geht? Im Idealfall muss ich die Instanz jeden Tag starten und in bestimmten Zeitabständen stoppen.

88
Pasta

Für den Fall, dass jemand auf diese alte Frage stößt, können Sie heutzutage dasselbe tun, indem Sie einen Zeitplan zu einer automatischen Skalierungsgruppe hinzufügen: Erhöhen Sie die Anzahl der Instanzen in einer automatischen Skalierungsgruppe zu bestimmten Zeiten auf 1 und verringern Sie sie anschließend wieder auf 0 .

Und da diese Antwort viele Ansichten bekommt, wollte ich auf einen hilfreichen Leitfaden zu diesem Thema verweisen: Ausführen von EC2-Instanzen nach einem wiederkehrenden Zeitplan mit Auto Scaling

100
Nakedible

Sie können die Amazon EC2 API-Tools direkt verwenden. Es gibt wirklich nur zwei Befehle, die Sie benötigen: ec2-start-instance und ec2-stop-instance . Stellen Sie sicher, dass Umgebungsvariablen wie EC2_HOME, AWS_CREDENTIAL_FILE, EC2_CERT, EC2_PRIVATE_KEY usw. ordnungsgemäß sind konfiguriert und alle AWS-Berechtigungsnachweise, Zertifikatsdateien und privaten Schlüsseldateien befinden sich am richtigen Ort. Weitere Informationen finden Sie in der Dokumentation zu AWS EC2 APItools.

Sie können den Befehl zuerst von Hand testen und dann, wenn alles einwandfrei funktioniert, Unix crontab oder Scheduled Tasks unter Windows konfigurieren. Das -Beispiel finden Sie unten für die Linux-Datei/etc/crontab (Vergessen Sie nicht, dass alle oben genannten Umgebungsvariablen für den Benutzer "" Ihres Kontos "vorhanden sein müssen.

/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.

Ich bin ein Entwickler des BitNami Cloud-Projekts, in dem wir die AWS-Tools (einschließlich der von mir genannten) in einem kostenlosen, einfach zu verwendenden -Installer packen, den Sie vielleicht ausprobieren möchten: BitNami CloudTools-PaketStapel

26
danoo

Ich empfehle Ihnen, einen Blick auf die EC2-Kurzanleitung zu werfen, in der Sie erfahren, wie Sie mit den EC2-Befehlszeilen-Tools das tun, was Sie benötigen. Sie können dies leicht in einen cron-Job (unter Linux/UNIX) oder einen geplanten Job unter Windows ein Script erstellen, um die Befehle start und stop zu einem bestimmten Zeitpunkt aufzurufen.

Wenn Sie dies aus Ihrem eigenen Code heraus tun möchten, können Sie die APIs SOAP oder REST verwenden. Weitere Informationen finden Sie im Developer Guide .

17
gareth_bowles

Ich habe dazu in Python Code geschrieben und dazu die Boto-Bibliothek verwendet. Sie können dies für Ihren eigenen Gebrauch anpassen. Stellen Sie sicher, dass Sie dies als Teil eines Cron-Jobs ausführen, und Sie können so viele Instanzen starten oder herunterfahren, wie Sie während des Cron-Jobs benötigen.

#!/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])
15
Suman

Das Unternehmen, für das ich arbeite, hatte Kunden regelmäßig danach gefragt. Daher haben wir eine Freeware-App für die Planung von EC2-Apps hier veröffentlicht:

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

Es funktioniert unter Windows und Mac. Sie können mehrere tägliche/wöchentliche/monatliche Zeitpläne erstellen und mithilfe von Übereinstimmungsfiltern eine große Anzahl von Instanzen problemlos oder in Zukunft hinzugefügte Instanzen hinzufügen.

5
AntonyM

Wenn es nicht geschäftskritisch ist - Vereinfachen Sie das Planen der Batchdatei, um 'SHUTDOWN' (Windows) täglich um 3 Uhr morgens auszuführen. Dann laufen Sie zumindest nicht Gefahr, eine ungewollte Instanz unbegrenzt laufen zu lassen.

Offensichtlich ist dies nur die halbe Geschichte!

3
AndyM

AWS Data Pipeline funktioniert einwandfrei. https://aws.Amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instances/

Wenn Sie Tage vom Starten ausschließen möchten (z. B. am Wochenende), fügen Sie ein ShellCommandPrecondition-Objekt hinzu.

Erstellen Sie in AWS Console/Data Pipeline eine neue Pipeline. Es ist einfacher, eine Definition zu bearbeiten/importieren (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"
}
}

Legen Sie das Bash-Skript zum Herunterladen bereit und führen Sie es als Vorbedingung in Ihrem S3-Bucket aus

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

Beim Aktivieren und Ausführen der Pipeline an Wochenendtagen liest der Pipeline-Status der AWS-Konsole einen irreführenden "ERROR". Das Bash-Skript gibt einen Fehler zurück (Exit 1) und EC2 wurde nicht gestartet. An den Tagen 1 bis 5 lautet der Status "GESUND".

Verwenden Sie den AWS CLI-Befehl täglich ohne Vorbedingungen, um EC2 automatisch beim Schließen der Bürozeit zu stoppen.

2
user3526918

AutoScaling ist auf das Beenden von Instanzen beschränkt. Wenn Sie eine Instanz anhalten und den Serverstatus beibehalten möchten, ist ein externes Skript der beste Ansatz. 

Sie können dies tun, indem Sie einen Job in einer anderen Instanz ausführen, die rund um die Uhr läuft, oder Sie können einen Drittanbieter-Dienst wie Ylastic (oben erwähnt) oder Rocket Peak verwenden. 

In C # zum Beispiel ist der Code zum Anhalten eines Servers recht einfach: 

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
MrGreggs

Das Hinzufügen eines Zeitplans zu einer automatischen Skalierungsgruppe ist meiner Meinung nach der beste "Cloud-ähnliche" Ansatz. 

Falls Sie Ihre Instanzen jedoch nicht beenden und neue verwenden können, z. B. wenn Sie über elastische IPs usw. verfügen. 

Sie können ein Ruby-Skript erstellen, um Ihre Instanzen basierend auf einem Datumszeitbereich zu starten und zu stoppen.

#!/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

Werfen Sie einen Blick auf Amazon_start_stop , um einen kostenlosen Scheduler mit Heroku Scheduler zu erstellen.

1
Pablo Cantero

Ja, das ist mit AWS Lambda möglich. Sie können den Auslöser in Cloudwatch auswählen, der auf Cron-Ausdrücken unter UTC ausgeführt wird.

Hier ist ein verwandter Link https://aws.Amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/

Eine andere Alternative ist die Verwendung von awscli, die unter pip, apt-get, yum oder brew verfügbar ist, und anschließend aws configure mit Ihren aus IAM exportierten Anmeldeinformationen und Ausführen des folgenden Bash-Skripts ausgeführt werden, um ein vorhandenes EC2 zu stoppen markiert mit Name: Appname und Value: Appname Prod. Sie können awscli verwenden, um Ihre Instanzen zu kennzeichnen oder manuell von der AWS-Konsole aus zu kennzeichnen. aws ec2 stop-instances stoppt die Instanz und jq wird verwendet, um die json-Abfrage zu filtern und die richtige Instanz-ID mithilfe der Tags von aws ec2 describe-instances abzurufen.

Um zu überprüfen, dass aws configure erfolgreich war und den json-Ausgabelauf aws ec2 describe-instances zurückgibt, sollte Ihre laufende Instanz-ID in der Ausgabe enthalten sein. Hier ist eine Beispielausgabe

{
    "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"
        }
    ]
}

Das folgende Bash-Skript ist stop-ec2.sh in /home/centos/cron-scripts/, das von diesem SO post inspiriert wird.

(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} )

Führen Sie die Datei mit sh /home/centos/cron-scripts/stop-ec2.sh aus und stellen Sie sicher, dass die EC2-Instanz gestoppt wird. Um zu debuggen, führen Sie 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 aus und stellen Sie sicher, dass die richtige Instanz-ID zurückgegeben wird, die mit einem Tag versehen wurde.

Dann kann in crontab -e die folgende Zeile hinzugefügt werden 

30 14 * * * sh /home/centos/cron-scripts/stop-ec2.sh >> /tmp/stop

dadurch wird die Ausgabe in /tmp/stop protokolliert. Der 30 14 * * * ist der UTC-cron-Ausdruck, den Sie in https://crontab.guru/ einchecken können. Durch das Ersetzen durch aws ec2 start-instances kann eine Instanz gestartet werden.

1
devssh

Sie können Ylastic anschauen, um dies zu tun. Die Alternative scheint zu sein, dass ein Rechner läuft, der andere Instanzen mit einem Cron-Job oder einer geplanten Aufgabe herunterfährt/startet. 

Wenn Sie nur eine Instanz wünschen, ist dies natürlich eine teure Lösung, da eine Maschine immer ausgeführt werden muss und 80 US-Dollar pro Monat für eine Maschine zum Ausführen von Cron-Jobs zu zahlen sind, ist nicht kostengünstig.

1
Chris S

Obwohl es Möglichkeiten gibt, dies mithilfe der automatischen Skalierung zu erreichen, ist sie möglicherweise nicht für alle Gelegenheiten geeignet, da die Instanzen abgebrochen werden. Cron-Jobs funktionieren nie für eine einzelne Instanz (obwohl sie perfekt für Situationen wie das Stoppen einer einzelnen Instanz und das Planen anderer Instanzen beim Ausführen vieler Instanzen verwendet werden kann). Sie können API-Aufrufe wie StartInstancesRequest und StopInstancesRequest verwenden, um dasselbe zu erreichen, aber Sie müssen sich auf eine dritte Ressource verlassen. Es gibt viele Anwendungen zum Planen von AWS-Instanzen mit vielen Funktionen, aber für eine einfache Lösung würde ich eine kostenlose Anwendung wie snapleaf.io empfehlen. 

1
Upul Doluweera

Ich glaube, dass die erste Frage etwas verwirrend war. Das hängt davon ab, was Pasta braucht: 1. Starten/Beenden (Instanzspeicher) - Auto Scaling ist die richtige Lösung (Antwort von Nakedible) 2. Start/Stopp der EBS-Boot-Instanz - Auto Scaling hilft nicht, ich Verwenden Sie Remote-geplante Skripts (z. B. ec2-CLI).

0
lk7777