Posso avviare e terminare automaticamente la mia istanza Amazon utilizzando Amazon API? Puoi descrivere come si può fare? Idealmente ho bisogno di avviare l'istanza e arrestare l'istanza a intervalli di tempo specificati ogni giorno.
Posso avviare e terminare automaticamente la mia istanza Amazon utilizzando Amazon API? Puoi descrivere come si può fare? Idealmente ho bisogno di avviare l'istanza e arrestare l'istanza a intervalli di tempo specificati ogni giorno.
Risposte:
Nel caso in cui qualcuno inciampi su questa vecchia domanda, al giorno d'oggi puoi ottenere la stessa cosa aggiungendo una pianificazione a un gruppo di ridimensionamento automatico: aumentare la quantità di istanze in un gruppo di ridimensionamento automatico a 1 in determinati momenti e ridurlo a 0 in seguito .
E poiché questa risposta sta ottenendo molte visualizzazioni, ho pensato di collegarmi a una guida molto utile su questo: Esecuzione di istanze EC2 su una pianificazione ricorrente con Auto Scaling
Puoi provare a utilizzare direttamente gli strumenti API di Amazon EC2. Ci sono davvero solo due comandi di cui hai bisogno: ec2-start-instances ed ec2-stop-istanze. Assicurati che le variabili di ambiente come EC2_HOME, AWS_CREDENTIAL_FILE, EC2_CERT, EC2_PRIVATE_KEY e così via siano configurate correttamente e che tutte le credenziali AWS, i certificati e i file della chiave privata siano nella posizione corretta: puoi trovare ulteriori informazioni nella documentazione degli strumenti API di AWS EC2.
Puoi prima testare il comando manualmente e poi, quando tutto funziona correttamente, configurare Unix crontab o Scheduled Tasks su Windows. Di seguito è possibile trovare l'esempio per il file Linux / etc / crontab (non dimenticare che tutte le variabili di ambiente menzionate sopra devono essere presenti per l'utente "tuo 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.
Sono uno sviluppatore per il progetto BitNami Cloud, dove impacchettiamo gli strumenti AWS (compresi quelli che ho citato) in un programma di installazione gratuito e facile da usare che potresti voler provare: BitNami CloudTools pack stack
Ti consiglio di dare un'occhiata alla Guida introduttiva di EC2 , che ti mostra come fare ciò di cui hai bisogno utilizzando gli strumenti della riga di comando di EC2. Puoi facilmente inserire questo script in un cron job (su Linux / UNIX) o in un job pianificato su Windows per chiamare i comandi di avvio e arresto in un dato momento.
Se vuoi farlo dal tuo codice, puoi usare le API SOAP o REST; vedere il Guida per sviluppatori per i dettagli.
Ho scritto codice in Python, usando la libreria Boto, per farlo. Puoi regolarlo per il tuo uso personale. Assicurati di eseguirlo come parte di un cron job, quindi sarai in grado di avviare o arrestare tutte le istanze di cui hai bisogno durante l'esecuzione dei cron job.
#!/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])
Se non è mission critical - Una cosa semplicistica da fare è programmare il file batch per eseguire "SHUTDOWN" (Windows) alle 3 del mattino ogni giorno. Quindi almeno non corri il rischio di lasciare accidentalmente un'istanza indesiderata in esecuzione indefinitamente.
Ovviamente questa è solo metà della storia!
L'azienda per cui lavoro aveva clienti che lo chiedevano regolarmente, quindi abbiamo scritto un'app di pianificazione EC2 freeware disponibile qui:
http://blog.simple-help.com/2012/03/free-ec2-scheduler/
Funziona su Windows e Mac, ti consente di creare più pianificazioni giornaliere / settimanali / mensili e ti consente di utilizzare filtri di corrispondenza per includere facilmente un gran numero di istanze o include quelle che aggiungi in futuro.
AWS Data Pipeline funziona correttamente. https://aws.amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instances/
Se desideri escludere i giorni dall'inizio (es. Weekend) aggiungi un oggetto ShellCommandPrecondition.
Nella Console AWS / Data Pipeline, crea una nuova pipeline. È più facile modificare / importare una definizione (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"
}
}
Metti lo script Bash da scaricare ed eseguire come precondizione nel tuo bucket S3
#!/bin/sh
if [ "$(date +%u)" -lt 6 ]
then exit 0
else exit 1
fi
All'attivazione e all'esecuzione della pipeline nei giorni del fine settimana, lo stato di integrità della pipeline della console AWS legge un "ERRORE" fuorviante. Lo script bash restituisce un errore (uscita 1) e EC2 non viene avviato. Nei giorni da 1 a 5, lo stato è "SANO".
Per interrompere automaticamente EC2 alla chiusura dell'ufficio, utilizza il comando AWS CLI ogni giorno senza precondizioni.
Potresti guardare Ylastic per farlo. L'alternativa sembra avere una macchina in esecuzione che arresta / avvia altre istanze utilizzando un cron job o un'attività pianificata.
Ovviamente se vuoi solo un'istanza questa è una soluzione costosa, poiché una macchina deve essere sempre in esecuzione e pagare ~ $ 80 al mese per una macchina per eseguire cron job non è conveniente.
La scalabilità automatica è limitata alla terminazione delle istanze. Se si desidera arrestare un'istanza e mantenere lo stato del server, l'approccio migliore è uno script esterno.
Puoi farlo eseguendo un lavoro su un'altra istanza in esecuzione 24 ore su 24, 7 giorni su 7 oppure puoi utilizzare un servizio di terze parti come Ylastic (menzionato sopra) o Rocket Peak .
Ad esempio in C # il codice per arrestare un server è abbastanza semplice:
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));
}
IMHO l'aggiunta di una pianificazione a un gruppo di ridimensionamento automatico è il miglior approccio "simile a una nuvola" come menzionato prima.
Ma nel caso in cui non sia possibile terminare le istanze e utilizzarne di nuove, ad esempio se sono associati IP elastici ecc.
Puoi creare uno script Ruby per avviare e arrestare le istanze in base a un intervallo di date.
#!/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
Dai un'occhiata ad amazon_start_stop per creare uno scheduler gratuitamente utilizzando Heroku Scheduler .
Anche se ci sono modi per ottenere ciò utilizzando il ridimensionamento automatico, potrebbe non essere adatto a tutte le occasioni in quanto termina le istanze. I cron job non funzioneranno mai per una singola istanza (sebbene possano essere perfettamente utilizzati per situazioni come l'arresto di una singola istanza e la pianificazione di altre istanze durante l'esecuzione di molte istanze). Puoi utilizzare chiamate API come StartInstancesRequest e StopInstancesRequest per ottenere lo stesso risultato, ma ancora una volta devi fare affidamento su una terza risorsa. Esistono molte applicazioni per pianificare istanze AWS con molte funzionalità, ma per una soluzione semplice consiglierei un'app gratuita come snapleaf.io
Sì, puoi farlo utilizzando AWS Lambda. Puoi selezionare il trigger in Cloudwatch che viene eseguito su espressioni Cron su UTC.
Ecco un link correlato https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/
Un'altra alternativa è quella di utilizzare awscli
che è disponibile da pip
, apt-get
, yum
o brew
, e quindi eseguire aws configure
con le credenziali esportati da IAM ed eseguendo il seguente script bash, per fermare un EC2 che è stato etichettato con Name: Appname
e Value: Appname Prod
. Puoi utilizzare awscli
per taggare le tue istanze o taggarle manualmente dalla console AWS. aws ec2 stop-instances
interromperà l'istanza e jq
viene utilizzato per filtrare la query json e recuperare l'id dell'istanza corretto utilizzando i tag daaws ec2 describe-instances
.
Per verificare che sia aws configure
andato a buon fine e restituisca l'output json, esegui aws ec2 describe-instances
e l'ID dell'istanza in esecuzione dovrebbe essere presente nell'output. Ecco un esempio di output
{
"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"
}
]
}
Il seguente script bash è stop-ec2.sh
in /home/centos/cron-scripts/
cui è ispirato da questo post 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} )
Esegui il file utilizzando sh /home/centos/cron-scripts/stop-ec2.sh
e verifica che l'istanza EC2 venga arrestata. Per eseguire il debug, eseguiaws 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
e verifica che restituisca l'ID istanza corretto che è stato taggato.
Quindi nella crontab -e
riga seguente può essere aggiunto
30 14 * * * sh /home/centos/cron-scripts/stop-ec2.sh >> /tmp/stop
che registrerà l'output in /tmp/stop
. Il 30 14 * * *
è l'espressione cron UTC che è possibile controllare in https://crontab.guru/
. Allo stesso modo, la sostituzione con aws ec2 start-instances
può avviare un'istanza.
Credo che la domanda iniziale fosse un po 'confusa. Dipende da ciò di cui Pasta ha bisogno: 1.launch / terminate (instance store) - Auto Scaling è la soluzione giusta (risposta di Nakedible) 2.start / stop istanza di avvio EBS - Auto Scaling non aiuta, io uso script programmati remoti (es. , ec2 CLI).
Non è possibile farlo automaticamente, o almeno non senza un po 'di programmazione e manipolazione API nei file di script. Se desideri una soluzione affidabile per arrestare, riavviare e gestire le tue immagini (presumibilmente per controllare i costi nel tuo ambiente), allora potresti voler dare un'occhiata a LabSlice . Disclaimer: lavoro per questa azienda.