Shutdown Otomatis dan Mulai Instans Amazon EC2


90

Dapatkah saya secara otomatis memulai dan menghentikan instans Amazon saya menggunakan API Amazon? Bisakah Anda menjelaskan bagaimana ini bisa dilakukan? Idealnya, saya perlu memulai instance dan menghentikan instance pada interval waktu yang ditentukan setiap hari.


2
Apa yang terjadi pada data instans EC2 Anda saat dimatikan? Apakah itu bertahan atau Anda harus membangunnya kembali?
Matthew Lock

Memulai dan menghentikan instans secara otomatis menggunakan API Amazon dapat menyebabkan kehilangan data pada peristiwa itu. Saya akan merekomendasikan Tindakan Berhenti & Pulihkan menggunakan AWS CloudWatch Alarms
Chetabahana

Alih-alih Amazon API, saya sarankan untuk Menjadwalkan EC2 Start / Stop menggunakan AWS Lambda , dalam kasus Anda biayanya kurang dari $ 0,0004 USD / bulan.
Chetabahana

Jawaban:


102

Seandainya seseorang tersandung pada pertanyaan lama ini, saat ini Anda dapat mencapai hal yang sama dengan menambahkan jadwal ke grup penskalaan otomatis: tingkatkan jumlah instance dalam grup penskalaan otomatis menjadi 1 pada waktu tertentu dan turunkan kembali ke 0 setelahnya .

Dan karena jawaban ini mendapatkan banyak tampilan, saya berpikir untuk menautkan ke panduan yang sangat membantu tentang ini: Menjalankan Instans EC2 pada Jadwal Berulang dengan Auto Scaling


6
Saya mencoba metode yang dijelaskan dalam tautan, dan itu memang memulai / menghentikan contoh pada waktu yang ditentukan oleh tutorial. Namun, saya perhatikan di konsol web AWS bahwa ketika sebuah instans dimulai dengan metode ini, ia tidak dimulai dengan kunci (sehingga Anda dapat ssh ke dalamnya), dan itu juga tampaknya tidak memiliki hal yang sama dengan saya. diinstal pada instans mikro yang saya gunakan sebagai pengujian (saya bukan pakar cloud, tetapi menurut saya ini berarti instans baru yang dipintal tidak terhubung ke EBS?) Apakah ada cara untuk memulai dan hentikan contoh yang sama pada jadwal waktu?
Kiran K.

@Kiran. apakah itu berarti instans baru tidak dilampirkan ke volume EBS yang saat ini digunakan? apa yang kamu gunakan?
Topi Jerami

26

Anda dapat mencoba menggunakan alat API Amazon EC2 secara langsung. Hanya ada dua perintah yang Anda butuhkan: ec2-start-instance dan ec2-stop-instance. Pastikan variabel lingkungan seperti EC2_HOME, AWS_CREDENTIAL_FILE, EC2_CERT, EC2_PRIVATE_KEY, dll. Dikonfigurasi dengan benar dan semua kredensial AWS, sertifikat, dan file kunci pribadi berada di lokasi yang tepat - Anda dapat menemukan info selengkapnya di dokumentasi alat API AWS EC2.

Anda dapat menguji perintah dengan tangan terlebih dahulu dan kemudian, ketika semuanya berfungsi dengan baik, konfigurasikan crontab Unix atau Tugas Terjadwal di Windows. Anda dapat menemukan contoh di bawah ini untuk file Linux / etc / crontab (jangan lupa bahwa semua variabel lingkungan yang disebutkan di atas harus ada untuk pengguna 'akun-Anda'.

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

Saya seorang pengembang untuk proyek BitNami Cloud, di mana kami mengemas alat AWS (termasuk yang saya sebutkan) dalam penginstal gratis dan mudah digunakan yang mungkin ingin Anda coba: BitNami CloudTools pack stack


2
Untuk ini, Anda masih perlu memiliki contoh lain. Karena shut down bukan masalah tapi start up. Crone atau apapun tidak akan berjalan di komputer mati setelah dimatikan.
Upul Doluweera

Saya mengikuti langkah-langkah ini untuk menyiapkan Alat AWS CLI di Instans AMazon Linux saya. Menghentikan instance berfungsi dengan baik. Tetapi memulai instance yang sudah dihentikan memberikan 400 kesalahan, ID Instance tidak ditemukan. Bagaimana saya bisa memulai instance yang sudah dihentikan?
Amol Chakane

17

Saya menyarankan Anda untuk melihat Panduan Memulai EC2 , yang menunjukkan kepada Anda bagaimana melakukan apa yang Anda perlukan dengan menggunakan alat baris perintah EC2. Anda dapat dengan mudah membuat skrip ini menjadi pekerjaan cron (di Linux / UNIX) atau pekerjaan terjadwal di Windows untuk memanggil perintah start dan stop pada waktu tertentu.

Jika Anda ingin melakukan ini dari kode Anda sendiri, Anda dapat menggunakan SOAP atau REST API; lihat Panduan Pengembang untuk detailnya.


16

Saya menulis kode dengan Python, menggunakan pustaka Boto, untuk melakukan ini. Anda dapat menyesuaikan ini untuk penggunaan Anda sendiri. Pastikan untuk menjalankan ini sebagai bagian dari tugas cron, dan Anda akan dapat memulai atau mematikan sebanyak mungkin instans yang Anda perlukan selama pekerjaan cron dijalankan.

#!/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
Apakah ini mungkin untuk lingkungan Elastic Beanstalk juga?
Amol Chakane

5

Jika bukan misi penting - Hal sederhana yang harus dilakukan adalah menjadwalkan file batch untuk menjalankan 'SHUTDOWN' (windows) pada jam 3 pagi setiap hari. Maka setidaknya Anda tidak mengambil risiko secara tidak sengaja meninggalkan instance yang tidak diinginkan berjalan tanpa batas.

Jelas ini hanya separuh cerita!


5

Perusahaan tempat saya bekerja memiliki pelanggan yang secara teratur bertanya tentang hal ini sehingga kami telah menulis aplikasi penjadwalan EC2 freeware yang tersedia di sini:

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

Ini berfungsi di Windows dan Mac, memungkinkan Anda membuat beberapa jadwal harian / mingguan / bulanan dan memungkinkan Anda menggunakan filter yang cocok untuk menyertakan sejumlah besar contoh dengan mudah atau menyertakan yang Anda tambahkan di masa mendatang.


2

AWS Data Pipeline berfungsi dengan baik. https://aws.amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instances/

Jika Anda ingin mengecualikan hari dari awal (misalnya akhir pekan) tambahkan objek ShellCommandPrecondition.

Di AWS Console / Data Pipeline, buat pipeline baru. Lebih mudah untuk mengedit / mengimpor definisi (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"
}
}

Letakkan skrip Bash yang akan di-dowload dan dijalankan sebagai prasyarat di bucket S3 Anda

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

Saat mengaktifkan dan menjalankan pipeline pada hari-hari akhir pekan, Status Kesehatan Pipeline konsol AWS membaca "ERROR" yang menyesatkan. Skrip bash mengembalikan kesalahan (keluar 1) dan EC2 tidak dimulai. Pada hari ke 1 sampai ke 5, statusnya adalah "SEHAT".

Untuk menghentikan EC2 secara otomatis pada waktu penutupan kantor, gunakan perintah AWS CLI setiap hari tanpa prasyarat.


1

Anda bisa melihat Ylastic untuk melakukan ini. Alternatifnya tampaknya menjalankan satu mesin yang mematikan / memulai instance lain menggunakan tugas cron atau tugas terjadwal.

Jelas jika Anda hanya menginginkan satu contoh, ini adalah solusi yang mahal, karena satu mesin harus selalu berjalan, dan membayar ~ $ 80 sebulan untuk satu mesin menjalankan tugas cron tidaklah efektif dari segi biaya.


1

AutoScaling terbatas pada instans penghentian. Jika Anda ingin menghentikan sebuah instance dan mempertahankan status server, maka skrip eksternal adalah pendekatan terbaik.

Anda dapat melakukan ini dengan menjalankan pekerjaan di instans lain yang berjalan 24/7 atau Anda dapat menggunakan layanan pihak ketiga seperti Ylastic (disebutkan di atas) atau Rocket Peak .

Misalnya di C # kode untuk menghentikan server cukup mudah:

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

IMHO menambahkan jadwal ke grup penskalaan otomatis adalah pendekatan "seperti cloud" terbaik seperti yang disebutkan sebelumnya.

Tetapi jika Anda tidak dapat menghentikan instans Anda dan menggunakan yang baru, misalnya jika Anda memiliki IP Elastis yang terkait dengan dll.

Anda dapat membuat skrip Ruby untuk memulai dan menghentikan instance Anda berdasarkan rentang waktu tanggal.

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

Silahkan lihat pada amazon_start_stop untuk membuat scheduler gratis menggunakan Heroku Scheduler .


1

Meskipun ada cara untuk mencapai ini menggunakan penskalaan otomatis, ini mungkin tidak cocok untuk semua kesempatan karena ini menghentikan instans. Cron job tidak akan pernah berfungsi untuk satu instance (meskipun ini dapat digunakan dengan sempurna untuk situasi seperti menghentikan satu instance dan menjadwalkan instance lain saat menjalankan banyak instance). Anda dapat menggunakan panggilan API seperti StartInstancesRequest , dan StopInstancesRequest untuk mencapai hal yang sama, tetapi sekali lagi Anda harus mengandalkan sumber daya ketiga. Ada banyak aplikasi untuk menjadwalkan instans AWS dengan banyak fitur, tetapi untuk solusi sederhana saya akan merekomendasikan aplikasi gratis seperti snapleaf.io


1

Ya, Anda dapat melakukannya menggunakan AWS Lambda. Anda dapat memilih pemicu di Cloudwatch yang berjalan pada ekspresi Cron pada UTC.

Ini adalah tautan terkait https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/

Alternatif lain adalah dengan menggunakan awscliyang tersedia dari pip, apt-get, yumatau brew, dan kemudian berjalan aws configuredengan mandat Anda yang diekspor dari IAM dan mengeksekusi skrip bash berikut, untuk menghentikan EC2 yang telah ditandai dengan Name: Appnamedan Value: Appname Prod. Anda dapat menggunakan awscliuntuk menandai instans Anda atau menandainya secara manual dari konsol AWS. aws ec2 stop-instancesakan menghentikan instance dan jqdigunakan untuk memfilter kueri json dan mengambil id instance yang benar menggunakan tag dari aws ec2 describe-instances.

Untuk memverifikasi bahwa aws configureberhasil dan mengembalikan keluaran json yang dijalankan aws ec2 describe-instancesdan id instance yang sedang berjalan harus ada di keluaran. Berikut adalah contoh keluarannya

{
    "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"
        }
    ]
}

The bash script berikut ini stop-ec2.shdi /home/centos/cron-scripts/mana terinspirasi dari SO posting ini

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

Jalankan file menggunakan sh /home/centos/cron-scripts/stop-ec2.shdan verifikasi bahwa instans EC2 dihentikan. Untuk men-debug, jalankan 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 .[].InstanceIddan lihat apakah itu mengembalikan ID instance yang benar yang telah diberi tag.

Kemudian di crontab -ebaris berikut dapat ditambahkan

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

yang akan mencatat keluaran ke /tmp/stop. Ini 30 14 * * *adalah ekspresi cron UTC yang dapat Anda periksa https://crontab.guru/. Demikian pula, mengganti dengan aws ec2 start-instancesdapat memulai sebuah instance.


0

Saya yakin pertanyaan awal itu agak membingungkan. Itu tergantung pada apa yang dibutuhkan Pasta: 1. meluncurkan / mengakhiri (penyimpanan instans) - Penskalaan Otomatis adalah solusi yang tepat (jawaban Nakedible) 2. memulai / menghentikan instans boot EBS - Penskalaan Otomatis tidak membantu, saya menggunakan skrip terjadwal jarak jauh (mis. , ec2 CLI).


-8

Anda tidak dapat melakukan ini secara otomatis, atau setidaknya tidak tanpa beberapa pemrograman dan manipulasi API dalam file skrip. Jika Anda ingin solusi yang dapat diandalkan untuk menghentikan, memulai ulang, dan mengelola gambar Anda (mungkin untuk mengontrol biaya di lingkungan Anda) maka Anda mungkin ingin melihat LabSlice . Penafian: Saya bekerja untuk perusahaan ini.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.