Чи можу я автоматично запускати та припиняти свій екземпляр Amazon за допомогою API Amazon? Чи можете ви описати, як це можна зробити? Мені в ідеалі потрібно запускати екземпляр і зупиняти екземпляр через визначені інтервали часу щодня.
Чи можу я автоматично запускати та припиняти свій екземпляр Amazon за допомогою API Amazon? Чи можете ви описати, як це можна зробити? Мені в ідеалі потрібно запускати екземпляр і зупиняти екземпляр через визначені інтервали часу щодня.
Відповіді:
Про всяк випадок, якщо хтось натрапить на це старе питання, сьогодні ви можете досягти того самого, додавши розклад до групи автоматичного масштабування: збільште кількість випадків у групі автоматичного масштабування до 1 у певний час і зменшіть її назад до 0 згодом .
І оскільки ця відповідь отримує багато переглядів, я подумав зробити посилання на дуже корисний посібник з цього приводу: Запуск екземплярів EC2 за періодичним розкладом з автоматичним масштабуванням
Ви можете спробувати скористатися інструментами Amazon EC2 API безпосередньо. Насправді вам потрібні лише дві команди: ec2-start-instances та ec2-stop-instances. Переконайтесь, що змінні середовища, такі як EC2_HOME, AWS_CREDENTIAL_FILE, EC2_CERT, EC2_PRIVATE_KEY тощо, правильно налаштовані, і всі облікові дані AWS, сертифікати та приватні ключі знаходяться у правильному місці - ви можете знайти більше інформації в документації до інструментів API AWS EC2.
Ви можете спочатку протестувати команду вручну, а потім, коли все працює нормально, налаштувати Unix crontab або заплановані завдання в Windows. Ви можете знайти приклад нижче для файлу Linux / etc / crontab (не забувайте, що всі ці змінні середовища, згадані вище, повинні бути присутніми для користувача "вашого облікового запису".
/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.
Я розробник проекту BitNami Cloud, де ми пакуємо інструменти AWS (включаючи ті, про які я вже згадував) у безкоштовний, простий у використанні інсталятор, який ви можете спробувати: стек пакета BitNami CloudTools
Я рекомендую вам поглянути на Посібник із початку роботи EC2 , де показано, як зробити те, що потрібно, за допомогою інструментів командного рядка EC2. Ви можете легко скриптувати це у завдання cron (у Linux / UNIX) або заплановане завдання в Windows, щоб викликати команди запуску та зупинки в певний час.
Якщо ви хочете зробити це з власного коду, ви можете використовувати API SOAP або REST; докладніше див. у Посібнику розробника .
Для цього я написав код на Python, використовуючи бібліотеку Boto. Ви можете налаштувати це для власного використання. Не забудьте запустити це як частину завдання cron, і тоді ви зможете запустити або вимкнути стільки екземплярів, скільки вам потрібно під час запуску завдань 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])
У компанії, в якій я працюю, клієнти регулярно запитували про це, тому ми написали безкоштовну програму планування EC2, яка доступна тут:
http://blog.simple-help.com/2012/03/free-ec2-scheduler/
Він працює на Windows і Mac, дозволяє створювати кілька щоденних / тижневих / щомісячних розкладів і дозволяє використовувати відповідні фільтри, щоб легко включати велику кількість екземплярів або включати ті, які ви додасте в майбутньому.
AWS Data Pipeline працює нормально. https://aws.amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instance/
Якщо ви хочете виключити дні з початку (наприклад, вихідні), додайте об'єкт ShellCommandPrecondition.
У консолі AWS / конвеєрі даних створіть новий конвеєр. Легше редагувати / імпортувати визначення (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"
}
}
Помістіть скрипт Bash для завантаження та виконання як попередню умову у вашому сегменті S3
#!/bin/sh
if [ "$(date +%u)" -lt 6 ]
then exit 0
else exit 1
fi
Під час активації та запуску трубопроводу у вихідні дні на консолі стану конвеєра AWS Pipeline Status відображається оманливе повідомлення "ПОМИЛКА". Скрипт bash повертає помилку (вихід 1) і EC2 не запускається. З 1 по 5 день статус "ЗДОРОВИЙ".
Щоб автоматично зупинити EC2 під час закриття офісу, використовуйте команду AWS CLI щодня без попередньої умови.
Ви можете подивитися на Ylastic, щоб зробити це. Здається, альтернативою є одна запущена машина, яка вимикає / запускає інші екземпляри за допомогою завдання cron або запланованого завдання.
Очевидно, що якщо вам потрібен лише один екземпляр, це дороге рішення, оскільки одна машина повинна завжди працювати, і платити ~ 80 доларів на місяць за те, щоб одна машина запускала завдання cron, не є економічно вигідною.
Автомасштабування обмежується завершенням екземплярів. Якщо ви хочете зупинити екземпляр і зберегти стан сервера, найкращим підходом є зовнішній сценарій.
Ви можете зробити це, запустивши завдання в іншому екземплярі, який працює цілодобово та без вихідних, або скористатися сторонньою службою, такою як Ylastic (згадана вище) або Rocket Peak .
Наприклад, у C # код зупинки сервера досить простий:
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 - найкращий підхід, схожий на хмару, як згадувалося раніше.
Але на випадок, якщо ви не можете завершити роботу своїх екземплярів і використовувати нові, наприклад, якщо у вас є еластичні IP-адреси, пов’язані з ін.
Ви можете створити сценарій Ruby для запуску та зупинки ваших екземплярів на основі діапазону часу.
#!/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
Погляньте на amazon_start_stop, щоб безкоштовно створити планувальник за допомогою Heroku Scheduler .
Незважаючи на те, що існують способи досягти цього за допомогою автоматичного масштабування, він може не підходити для всіх випадків, оскільки припиняє екземпляри. Завдання Cron ніколи не працюватимуть для одного екземпляра (хоча його цілком можна використовувати в таких ситуаціях, як зупинка одного екземпляра та планування інших екземплярів при запуску багатьох екземплярів). Ви можете використовувати виклики API, такі як StartInsngthRequest та StopInsngthRequest, щоб досягти того ж, але знову ж таки вам доведеться покладатися на третій ресурс. Є багато програм для планування екземплярів AWS з багатьма функціями, але для простого рішення я б порадив безкоштовний додаток, такий як snapleaf.io
Так, ви можете зробити це за допомогою AWS Lambda. Ви можете вибрати тригер у Cloudwatch, який працює на виразах Cron на UTC.
Ось відповідне посилання https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/
Іншою альтернативою є використання awscli
яка доступна pip
, apt-get
, yum
або brew
, а потім працює aws configure
з обліковими даними , що експортуються з IAM і виконавши наступний Баш скрипт, щоб зупинити EC2, яка була позначена з Name: Appname
і Value: Appname Prod
. Ви можете використовувати awscli
для позначення своїх екземплярів або тегу вручну за допомогою консолі AWS. aws ec2 stop-instances
зупинить екземпляр і jq
використовується для фільтрації запиту json та отримання правильного ідентифікатора екземпляра за допомогою тегів з aws ec2 describe-instances
.
Щоб переконатися, що це aws configure
було успішно, і повертає вихідний прогін json, aws ec2 describe-instances
а ваш вихідний ідентифікатор екземпляра повинен бути там у вихідних даних. Ось зразок вихідних даних
{
"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"
}
]
}
Наступний сценарій Баш знаходиться stop-ec2.sh
в /home/centos/cron-scripts/
яких натхненний цієї посади 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} )
Запустіть файл за допомогою 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
і переконайтеся, що він повертає правильний ідентифікатор екземпляра, який був позначений тегом.
Потім у crontab -e
наступному рядку можна додати
30 14 * * * sh /home/centos/cron-scripts/stop-ec2.sh >> /tmp/stop
який буде реєструвати вихідні дані /tmp/stop
. 30 14 * * *
Цей вислів хрон UTC , що ви можете перевірити https://crontab.guru/
. Подібним чином заміна на aws ec2 start-instances
може запустити екземпляр.
Я вважаю, що початкове запитання було трохи заплутаним. Це залежить від того, що потрібно макаронам: 1.запуск / завершення (зберігання екземплярів) - автоматичне масштабування є правильним рішенням (відповідь Nakedible) 2.запуск / зупинка екземпляра завантаження EBS - автоматичне масштабування не допоможе, я використовую віддалені заплановані сценарії (тобто , ec2 CLI).
Ви не можете зробити це автоматично або, принаймні, без певного програмування та маніпулювання API у файлах сценаріїв. Якщо ви хочете отримати надійне рішення, щоб зупинити, перезапустити та керувати своїми зображеннями (імовірно, щоб контролювати витрати у вашому середовищі), тоді ви можете переглянути LabSlice . Застереження: я працюю в цій компанії.