Czy mogę automatycznie uruchamiać i zamykać moją instancję Amazon za pomocą Amazon API? Czy możesz opisać, jak można to zrobić? Najlepiej byłoby uruchamiać instancję i zatrzymywać ją w określonych odstępach czasu każdego dnia.
Czy mogę automatycznie uruchamiać i zamykać moją instancję Amazon za pomocą Amazon API? Czy możesz opisać, jak można to zrobić? Najlepiej byłoby uruchamiać instancję i zatrzymywać ją w określonych odstępach czasu każdego dnia.
Odpowiedzi:
Na wypadek, gdyby ktoś natknął się na to stare pytanie, obecnie możesz osiągnąć to samo, dodając harmonogram do grupy z automatycznym skalowaniem: zwiększ liczbę wystąpień w grupie z automatycznym skalowaniem do 1 w określonych momentach, a potem zmniejsz ją z powrotem do 0 .
Ponieważ ta odpowiedź ma wiele wyświetleń, pomyślałem, że zamieściłem link do bardzo pomocnego przewodnika na ten temat: Uruchamianie instancji EC2 w cyklicznym harmonogramie z automatycznym skalowaniem
Możesz spróbować bezpośrednio skorzystać z narzędzi API Amazon EC2. Potrzebujesz tylko dwóch poleceń: ec2-start-instances i ec2-stop-instances. Upewnij się, że zmienne środowiskowe, takie jak EC2_HOME, AWS_CREDENTIAL_FILE, EC2_CERT, EC2_PRIVATE_KEY, itp. Są odpowiednio skonfigurowane, a wszystkie poświadczenia AWS, pliki certyfikatów i kluczy prywatnych znajdują się we właściwej lokalizacji - więcej informacji znajdziesz w dokumentacji narzędzi AWS EC2 API.
Możesz najpierw przetestować polecenie ręcznie, a gdy wszystko działa dobrze, skonfigurować Unix crontab lub Scheduled Tasks w systemie Windows. Możesz znaleźć poniższy przykład dla pliku Linux / etc / crontab (nie zapominaj, że wszystkie wymienione powyżej zmienne środowiskowe muszą być obecne dla użytkownika „twoje konto”.
/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.
Jestem programistą projektu BitNami Cloud, w którym pakujemy narzędzia AWS (w tym te, o których wspomniałem) w darmowym, łatwym w użyciu instalatorze, który możesz wypróbować: stos pakietów BitNami CloudTools
Zalecam zapoznanie się z Przewodnikiem Pierwsze kroki EC2 , który pokazuje, jak zrobić to, czego potrzebujesz, używając narzędzi wiersza poleceń EC2. Możesz łatwo zapisać to w zadaniu cron (w systemie Linux / UNIX) lub zaplanowanym zadaniu w systemie Windows, aby wywołać polecenia uruchamiania i zatrzymywania w określonym czasie.
Jeśli chcesz to zrobić z własnego kodu, możesz użyć API SOAP lub REST; szczegółowe informacje można znaleźć w Podręczniku programisty .
Aby to zrobić, napisałem kod w Pythonie, korzystając z biblioteki Boto. Możesz to dostosować do własnego użytku. Upewnij się, że uruchamiasz to jako część zadania cron, a wtedy będziesz mógł uruchomić lub zamknąć tyle instancji, ile potrzebujesz podczas wykonywania zadań 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])
Jeśli nie jest to krytyczne dla misji - prostą rzeczą jest zaplanowanie uruchamiania pliku wsadowego „SHUTDOWN” (Windows) o 3 nad ranem każdego dnia. Wtedy przynajmniej nie ryzykujesz przypadkowego pozostawienia niechcianej instancji działającej w nieskończoność.
Oczywiście to tylko połowa historii!
Firma, dla której pracuję, miała klientów regularnie pytających o to, dlatego napisaliśmy bezpłatną aplikację do planowania EC2 dostępną tutaj:
http://blog.simple-help.com/2012/03/free-ec2-scheduler/
Działa w systemach Windows i Mac, umożliwia tworzenie wielu dziennych / tygodniowych / miesięcznych harmonogramów i pozwala używać pasujących filtrów w celu łatwego dołączania dużej liczby instancji lub zawiera te, które dodasz w przyszłości.
Potok danych AWS działa dobrze. https://aws.amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instances/
Jeśli chcesz wykluczyć dni od rozpoczęcia (np. Weekend), dodaj obiekt ShellCommandPrecondition.
W konsoli AWS / potoku danych utwórz nowy potok. Łatwiej jest edytować / importować definicję (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"
}
}
Umieść skrypt Bash do pobrania i wykonania jako warunek wstępny w swoim segmencie S3
#!/bin/sh
if [ "$(date +%u)" -lt 6 ]
then exit 0
else exit 1
fi
Podczas aktywacji i uruchamiania potoku w dni weekendowe stan kondycji rurociągu konsoli AWS wyświetla wprowadzający w błąd „BŁĄD”. Skrypt bash zwraca błąd (wyjście 1), a EC2 nie jest uruchamiany. W dniach od 1 do 5 stan jest „ZDROWY”.
Aby automatycznie zatrzymać EC2 po zamknięciu biura, używaj komendy AWS CLI codziennie bez warunku wstępnego.
Aby to zrobić, możesz spojrzeć na Ylastic . Wydaje się, że alternatywą jest uruchomienie jednej maszyny, która zamyka / uruchamia inne wystąpienia przy użyciu zadania cron lub zaplanowanego zadania.
Oczywiście, jeśli potrzebujesz tylko jednej instancji, jest to drogie rozwiązanie, ponieważ jedna maszyna musi zawsze działać, a płacenie ~ 80 USD miesięcznie za jedną maszynę do wykonywania zadań cron nie jest opłacalne.
Automatyczne skalowanie jest ograniczone do przerywania wystąpień. Jeśli chcesz zatrzymać instancję i zachować stan serwera, najlepszym rozwiązaniem jest zewnętrzny skrypt.
Możesz to zrobić, uruchamiając zadanie w innej instancji, która działa 24 godziny na dobę, 7 dni w tygodniu lub możesz skorzystać z usługi innej firmy, takiej jak Ylastic (wspomniana powyżej) lub Rocket Peak .
Na przykład w C # kod zatrzymujący serwer jest całkiem prosty:
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 dodawanie harmonogramu do grupy z automatycznym skalowaniem jest najlepszym podejściem podobnym do chmury, jak wspomniano wcześniej.
Ale jeśli nie możesz zamknąć swoich instancji i użyć nowych, na przykład jeśli masz powiązane elastyczne adresy IP itp.
Możesz utworzyć skrypt Ruby, aby uruchamiać i zatrzymywać instancje na podstawie zakresu dat i godzin.
#!/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
Zajrzyj na amazon_start_stop, aby za darmo utworzyć harmonogram za pomocą Heroku Scheduler .
Mimo że istnieją sposoby na osiągnięcie tego za pomocą automatycznego skalowania, może to nie być odpowiednie we wszystkich przypadkach, ponieważ powoduje zakończenie instancji. Zadania Cron nigdy nie będą działać dla pojedynczej instancji (chociaż można go doskonale wykorzystać w sytuacjach takich jak zatrzymanie pojedynczej instancji i planowanie innych instancji podczas uruchamiania wielu instancji). Możesz użyć wywołań interfejsu API, takich jak StartInstancesRequest i StopInstancesRequest, aby osiągnąć to samo, ale ponownie musisz polegać na trzecim zasobie. Istnieje wiele aplikacji do planowania wystąpień AWS z wieloma funkcjami, ale dla prostego rozwiązania polecam bezpłatną aplikację, taką jak snapleaf.io
Tak, możesz to zrobić za pomocą AWS Lambda. Możesz wybrać wyzwalacz w Cloudwatch, który działa na wyrażeniach Cron w UTC.
Oto powiązany link https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/
Inną alternatywą jest do użytku awscli
, który jest dostępny z pip
, apt-get
, yum
lub brew
, a następnie działa aws configure
z poświadczeniami eksportowanych z IAM i wykonując następujący skrypt bash, aby zatrzymać EC2 który został oznaczony z Name: Appname
i Value: Appname Prod
. Możesz użyć awscli
do otagowania swoich instancji lub otagowania ich ręcznie z konsoli AWS. aws ec2 stop-instances
zatrzyma instancję i jq
jest używany do filtrowania zapytania json i pobierania prawidłowego identyfikatora instancji przy użyciu tagów z aws ec2 describe-instances
.
Aby sprawdzić, czy się aws configure
powiodło i zwraca wynik json, uruchom, aws ec2 describe-instances
a identyfikator działającej instancji powinien znajdować się w danych wyjściowych. Oto przykładowe dane wyjściowe
{
"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"
}
]
}
Poniższy skrypt bash stop-ec2.sh
w /home/centos/cron-scripts/
którym jest inspirowana z tym SO postu
(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} )
Uruchom plik za pomocą sh /home/centos/cron-scripts/stop-ec2.sh
i sprawdź, czy instancja EC2 została zatrzymana. Aby debugować, uruchom 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
i sprawdź, czy zwraca poprawny identyfikator instancji, który został oznaczony.
Następnie crontab -e
można dodać następujący wiersz
30 14 * * * sh /home/centos/cron-scripts/stop-ec2.sh >> /tmp/stop
który będzie rejestrował dane wyjściowe /tmp/stop
. To 30 14 * * *
jest wyrażenie cron UTC, które możesz sprawdzić https://crontab.guru/
. Podobnie zamiana na aws ec2 start-instances
może rozpocząć instancję.
Uważam, że pierwsze pytanie było trochę zagmatwane. Zależy to od tego, czego potrzebuje Pasta: 1. uruchom / zakończ (magazyn instancji) - Automatyczne skalowanie to właściwe rozwiązanie (odpowiedź Nakedible) 2. uruchom / zatrzymaj instancję rozruchową EBS - automatyczne skalowanie nie pomoże, używam zdalnych zaplanowanych skryptów (tj. , ec2 CLI).
Nie możesz tego zrobić automatycznie, a przynajmniej nie bez programowania i manipulacji API w plikach skryptów. Jeśli chcesz mieć niezawodne rozwiązanie do zatrzymywania, ponownego uruchamiania i zarządzania obrazami (prawdopodobnie w celu kontrolowania kosztów w Twoim środowisku), możesz spojrzeć na LabSlice . Zastrzeżenie: pracuję dla tej firmy.