自動シャットダウンとAmazon EC2インスタンスの起動


90

Amazon APIを使用してAmazonインスタンスを自動的に開始および終了できますか?これをどのように行うことができるか説明できますか?理想的には、毎日指定された時間間隔でインスタンスを開始および停止する必要があります。


2
シャットダウンすると、EC2インスタンスのデータはどうなりますか?持続するか、それとも再構築する必要がありますか?
マシューロック

Amazon APIを使用してインスタンスを自動的に開始および終了すると、そのイベントでデータが失われる可能性があります。AWS CloudWatchアラーム
Chetabahana 2016

Amazon APIの代わりに、AWS Lambdaを使用してEC2の開始/停止をスケジュールすることをお勧めします。この場合、月額$ 0.0004 USD未満です。
Chetabahana 2016

回答:


102

誰かがこの古い質問に出くわした場合に備えて、現在、自動スケーリンググループにスケジュールを追加することで同じことを達成できます。自動スケーリンググループのインスタンスの数を特定の時間に1に増やし、後で0に戻します。 。

そして、この答えは多くの見解を得ているので、これについて非常に役立つガイドにリンクを張ろうと思いました:Auto Scalingを使用した定期的なスケジュールでのEC2インスタンスの実行


6
リンクに記載されている方法を試しましたが、チュートリアルで指定された時間にインスタンスを実際に開始/停止します。ただし、AWS Webコンソールで、インスタンスがこの方法で開始された場合、キーで開始されない(それにSSHでログインできる)ことに気付きました。テストとして使用するマイクロインスタンスにインストールしました(私はクラウドのエキスパートではありませんが、これは、スピンアップされたこの新しいインスタンスがEBSに接続されていないことを意味します?)自動的に起動して同じインスタンスをタイムスケジュールで停止しますか?
キランK. 14年

@KiranK。これは、現在使用されているEBSボリュームに新しいインスタンスがアタッチされていないことを意味しますか?何を使いましたか
麦わら帽子2014

26

Amazon EC2 APIツールを直接使用してみることができます。実際に必要なコマンドは、ec2-start-instancesとec2-stop-instancesの2つだけです。EC2_HOME、AWS_CREDENTIAL_FILE、EC2_CERT、EC2_PRIVATE_KEYなどの環境変数が適切に構成されていること、およびすべてのAWS認証情報、証明書、秘密鍵ファイルが適切な場所にあることを確認してください。詳細については、AWS EC2 APIツールのドキュメントをご覧ください。

コマンドを最初に手動でテストし、すべてが正常に機能したら、WindowsでUnix crontabまたはスケジュールタスクを構成できます。以下のLinux / etc / crontabファイルの例を見つけることができます(上記のすべての環境変数が「your-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.

私はBitNami Cloudプロジェクトの開発者です。ここでは、AWSツール(前述のツールを含む)を無料で使いやすい インストーラーにパッケージ化します。BitNamiCloudToolsパックスタック


2
このためには、別のインスタンスが必要です。シャットダウンは問題ではなく、起動です。シャットダウンした後、死んだコンピューターでクローネなどは実行されません。
Upul Doluweera 2014年

AMazon LinuxインスタンスでAWS CLIツールを設定するには、次の手順に従いました。インスタンスの停止は正常に機能します。ただし、すでに停止しているインスタンスを開始すると400エラーが発生し、インスタンスIDが見つかりません。すでに停止したインスタンスをどのように開始できますか?
Amol Chakane 2015年

17

EC2入門ガイドをご覧になることをお勧めしますEC2コマンドラインツールを使用して必要な操作を行う方法を示す。これをcronジョブ(Linux / UNIXの場合)またはWindowsのスケジュールされたジョブに簡単にスクリプト化して、特定の時間に開始および停止コマンドを呼び出すことができます。

独自のコードからこれを行う場合は、SOAPまたはREST APIを使用できます。詳細については、開発者ガイドを参照してください。


15

これを行うために、私はBotoライブラリーを使用してPythonでコードを書きました。これは自分で使用するために調整できます。これを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])

1
これはElastic Beanstalk環境でも可能ですか?
Amol Chakane

5

ミッションクリティカルではない場合-バッチファイルを毎日午前3時に実行するようにスケジュールするのが最も簡単なことです。そうすれば、少なくとも、不要なインスタンスが誤って無期限に実行されたままになる危険性はありません。

明らかに、これは話の半分だけです!


5

私が働いている会社では、これについて顧客から定期的に質問があったので、ここから入手できるフリーウェアEC2スケジューリングアプリを作成しました。

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

これはWindowsとMacで動作し、複数の日次/週次/月次スケジュールを作成でき、一致フィルターを使用して多数のインスタンスを簡単に含めたり、将来追加するインスタンスを含めたりできます。


2

AWS Data Pipelineは正常に動作しています。https://aws.amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instances/

開始日(週末など)を除外する場合は、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コンソールのパイプラインヘルスステータスに誤解を招く「エラー」が表示されます。bashスクリプトがエラー(出口1)を返し、EC2が開始されていません。1〜5日目のステータスは「HEALTHY」です。

営業時間の終了時にEC2を自動的に停止するには、AWS CLIコマンドを前提条件として毎日使用します。


1

Ylasticを見てこれを行うことができます。代替手段は、cronジョブまたはスケジュールされたタスクを使用して他のインスタンスをシャットダウン/開始する1台のマシンを実行しているようです。

明らかに、1つのインスタンスのみが必要な場合、これは高価なソリューションです。1台のマシンを常に実行する必要があり、1台のマシンがcronジョブを実行するために1か月あたり約80ドルを支払うことはコスト効率が良くありません。


1

AutoScalingは、インスタンスの終了に制限されています。インスタンスを停止してサーバーの状態を保持する場合は、外部スクリプトが最適なアプローチです。

これは、24時間年中無休で実行されている別のインスタンスでジョブを実行するか、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));
        }

1

上述のように、自動スケーリンググループにスケジュールを追加することは、「クラウドのような」最良のアプローチです。

ただし、Elastic 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スケジューラを使用して無料でスケジューラを作成してください


1

自動スケーリングを使用してこれを実現する方法はありますが、インスタンスを終了するため、すべての状況に適しているとは限りません。cronジョブは、単一のインスタンスに対しては機能しません(単一のインスタンスを停止したり、多数のインスタンスを実行しているときに他のインスタンスをスケジュールしたりする場合などに完全に使用できます)。StartInstancesRequestStopInstancesRequestなどのAPI呼び出しを使用して同じことを達成できますが、やはり3番目のリソースに依存する必要があります。多くの機能を備えたAWSインスタンスをスケジュールする多くのアプリケーションがありますが、簡単な解決策として、snapleaf.ioのような無料のアプリをお勧めします


1

はい、AWS Lambdaを使用してそれを行うことができます。CloudWatchで、UTCのCron式で実行されるトリガーを選択できます。

ここに関連リンクがありますhttps://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/

別の方法としては、使用することですawscliから入手可能であるpipapt-getyumまたはbrew、その後、実行しているaws configureIAMからエクスポートされた資格情報とし、でタグ付けされたEC2停止するには、次のbashスクリプトを実行Name: AppnameしてをValue: Appname Prod。を使用awscliして、インスタンスにタグを付けるか、AWSコンソールから手動でタグを付けることができます。aws ec2 stop-instancesはインスタンスを停止しjq、jsonクエリをフィルタリングして、からのタグを使用して正しいインスタンスIDをフェッチするために使用されaws ec2 describe-instancesます。

それaws configureが成功してjson出力が返されたことを確認するにはaws ec2 describe-instances、実行中のインスタンスIDが出力に含まれている必要があります。これはサンプル出力です

{
    "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、タグ付けされた正しいインスタンスIDを返すことを確認します。

次に crontab -e、次の行に追加できます

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

これにより、出力がに記録されます/tmp/stop30 14 * * *あなたがチェックできることをUTCのcron表現ですhttps://crontab.guru/。同様に、と置き換えるとaws ec2 start-instancesインスタンスを開始できます。


0

最初の質問は少し混乱したと思います。それはパスタが必要とするものに依存します。 、ec2 CLI)。


-8

これを自動的に行うことはできません。少なくとも、スクリプトファイルでプログラミングやAPI操作を行わないとできません。(おそらく環境内のコストを制御するために)イメージを停止、再起動、および管理するための信頼できるソリューションが必要な場合は、LabSliceを確認することをお勧めします。免責事項:私はこの会社で働いています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.