Подтвердить что ты не робот

Автоматическое завершение работы и запуск Amazon EC2 Instance

Можно ли автоматически запускать и завершать экземпляр Amazon с помощью API Amazon? Не могли бы вы описать, как это можно сделать? Мне в идеале нужно запустить экземпляр и останавливать экземпляр с заданными временными интервалами каждый день.

4b9b3361

Ответ 1

На всякий случай кто-то наткнется на этот старый вопрос, в настоящее время вы можете добиться того же, добавив расписание в группу автоматического масштабирования: увеличьте количество экземпляров в группе автоматического масштабирования до 1 в определенное время и уменьшите ее до 0 после.

И так как этот ответ получает много просмотров, я думал связать с очень полезным руководством об этом: Запуск экземпляров EC2 в повторяющемся расписании с автоматическим масштабированием

Ответ 2

Вы можете напрямую использовать инструменты API Amazon EC2. Есть вам нужны только две команды: ec2-start-экземпляры и ec2-stop-экземпляры. Убедитесь, что переменные среды, такие как 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 pack стек

Ответ 3

Я рекомендую вам взглянуть на Руководство по началу работы с EC2, в котором показано, как делать то, что вам нужно, используя инструменты командной строки EC2, Вы можете легко script выполнить это задание cron (в Linux/UNIX) или запланированное задание в Windows, чтобы вызвать команды запуска и остановки в заданное время.

Если вы хотите сделать это из своего собственного кода, вы можете использовать API SOAP или REST; Подробнее см. Руководство разработчика.

Ответ 4

Я написал код на 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])

Ответ 5

В компании, в которой я работаю, клиенты регулярно спрашивали об этом, поэтому мы написали бесплатное приложение для планирования EC2, доступное здесь:

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

Он работает на Windows и Mac, позволяет создавать несколько ежедневных/еженедельных/ежемесячных расписаний и позволяет использовать соответствующие фильтры для включения большого количества экземпляров легко или включает в себя те, которые вы добавляете в будущем.

Ответ 6

Если это не критически важно - проще всего планировать командный файл для запуска "SHUTDOWN" (окна) в 3 часа ночи каждый день. Тогда, по крайней мере, вы не рискуете случайно покинуть нежелательный экземпляр, работающий на неопределенный срок.

Очевидно, что это только половина истории!

Ответ 7

AWS Data Pipeline работает нормально. https://aws.amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instances/

Если вы хотите исключить дни с начала (например, выходные), добавьте объект ShellCommandPrecondition.

В AWS Console/Data Pipeline создайте новый конвейер. Легче редактировать/импортировать определение (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 script, чтобы загрузить и выполнить как предварительное условие в вашем ведре S3

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

При активации и запуске конвейера в выходные дни, состояние здоровья трубопровода AWS сообщает об ошибке "ОШИБКА". Bash script возвращает ошибку (выход 1), а EC2 не запускается. В дни с 1 по 5 статус "ЗДОРОВЫЙ".

Чтобы остановить EC2 автоматически при закрытии офисного времени, ежедневно используйте команду AWS CLI с предварительным условием.

Ответ 8

Вы можете посмотреть Ylastic для этого. Кажется, что у альтернативы есть одна машина, которая выключает/запускает другие экземпляры, используя задание cron или запланированную задачу.

Очевидно, что если вам нужен только один экземпляр, это дорогостоящее решение, так как одна машина всегда должна работать, а оплата ~ 80 долларов в месяц для одной машины для запуска заданий cron не является экономически эффективной.

Ответ 9

AutoScaling ограничивается завершающими экземплярами. Если вы хотите остановить экземпляр и сохранить состояние сервера, лучшим вариантом будет внешний script.

Вы можете сделать это, запустив задание в другом экземпляре, который работает 24/7, или вы можете использовать стороннюю службу, такую ​​как Ylastic (упомянутый выше) или Ракетный пик.

Например, в С# код для остановки сервера довольно прост:

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

Ответ 10

ИМХО Добавление расписания в группу автоматического масштабирования - лучший подход к "облачным", как упоминалось ранее.

Но в случае, если вы не можете прервать свои экземпляры и использовать новые, например, если у вас есть Elastic IPs, связанные с ним.

Вы можете создать Ruby script, чтобы запустить и остановить свои экземпляры на основе диапазона дат.

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

Ответ 11

Несмотря на то, что есть способы достичь этого с помощью автоматического масштабирования, он может не подходить для всех случаев, поскольку он завершает экземпляры. Задачи Cron никогда не будут работать для одного экземпляра (хотя он отлично может использоваться для ситуаций, таких как остановка одного экземпляра и планирование других экземпляров при запуске многих экземпляров). Вы можете использовать вызовы API, такие как StartInstancesRequest, и StopInstancesRequest для достижения того же, но снова вам нужно полагаться на третий ресурс. Существует множество приложений для планирования экземпляров AWS со многими функциями, но для простого решения я бы рекомендовал бесплатное приложение, например snapleaf.io

Ответ 12

Я считаю, что первоначальный вопрос был немного запутанным. Это зависит от того, что нужно макаронам: 1.launch/terminate (хранилище экземпляров) - автоматическое масштабирование - правильное решение (Nakedible answer) 2.start/stop EBS boot instance - автоматическое масштабирование не поможет, я использую удаленные запланированные сценарии (например, ec2 CLI).

Ответ 13

Да, вы можете сделать это с помощью 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, и выполнение следующего скрипта bash, чтобы остановить 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 и в выводе должен быть 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"
        }
    ]
}

Следующий скрипт bash - это 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 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 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 * * * - это выражение cron UTC, которое вы можете проверить в https://crontab.guru/. Аналогично замена на aws ec2 start-instances может запустить экземпляр.

Ответ 14

Вы не можете делать это автоматически или, по крайней мере, не без программирования и манипулирования API в файлах script. Если вы хотите найти надежное решение для остановки, перезагрузки и управления вашими изображениями (предположительно для контроля затрат в вашей среде), вы можете посмотреть LabSlice. Отказ от ответственности: я работаю в этой компании.