Otomatik Kapatma ve Amazon EC2 Bulut Sunucusunu Başlatma


90

Amazon örneğimi Amazon API kullanarak otomatik olarak başlatıp sonlandırabilir miyim? Bunun nasıl yapılabileceğini açıklar mısınız lütfen? İdeal olarak örneği başlatmam ve örneği her gün belirli zaman aralıklarında durdurmam gerekiyor.


2
Kapatıldığında EC2 bulut sunucunuzun verilerine ne olur? Devam ediyor mu yoksa yeniden inşa etmeniz mi gerekiyor?
Matthew Lock

Bulut sunucusunu Amazon API kullanarak otomatik olarak başlatmak ve sonlandırmak, bu olayda veri kayıplarına neden olabilir. AWS CloudWatch Alarmlarını
Chetabahana

Amazon API yerine, AWS Lambda kullanarak EC2 Başlatma / Durdurma Planlamanızı öneririm , sizin durumunuzda size maliyeti 0.0004 USD / ay'dan daha az.
Chetabahana

Yanıtlar:


102

Birinin bu eski soruya tökezlemesi durumunda, bugünlerde bir otomatik ölçeklendirme grubuna bir program ekleyerek aynı şeyi başarabilirsiniz: bir otomatik ölçeklendirme grubundaki örnek sayısını belirli zamanlarda 1'e yükseltin ve ardından tekrar 0'a düşürün .

Ve bu yanıt çok sayıda görüntü aldığından, bununla ilgili çok yararlı bir kılavuza bağlantı vermeyi düşündüm: Otomatik Ölçeklendirme ile Yinelenen Bir Programda EC2 Bulut Sunucularını Çalıştırma


6
Bağlantıda açıklanan yöntemi denedim ve gerçekten de öğreticide belirtilen zamanlarda örnekleri başlatıyor / durduruyor. Bununla birlikte, AWS web konsolunda bir örnek bu yöntemle başlatıldığında, bir anahtarla başlamadığını (içine ssh yapabileceğiniz şekilde) ve benimle aynı şeylere sahip görünmediğini fark ettim. test olarak kullandığım mikro örneğime yüklendi (ben bir bulut uzmanı değilim, ancak bunun, döndürülen bu yeni örneğin EBS'ye bağlı olmadığı anlamına geldiğini düşünüyorum.) Otomatik olarak başlamanın bir yolu var mı ve aynı örneği bir zaman çizelgesinde durdurur mu?
Kiran K.

@KiranK. Bu, şu anda kullanılan EBS birimine yeni örneğin eklenmediği anlamına mı geliyor? ne kullandın
Hasır Şapka

26

Amazon EC2 API araçlarını doğrudan kullanmayı deneyebilirsiniz. Gerçekten ihtiyacınız olan yalnızca iki komut vardır: ec2-start-instances ve ec2-stop-instances. EC2_HOME, AWS_CREDENTIAL_FILE, EC2_CERT, EC2_PRIVATE_KEY vb. Gibi ortam değişkenlerinin doğru şekilde yapılandırıldığından ve tüm AWS kimlik bilgilerinin, sertifika ve özel anahtar dosyalarının doğru konumda olduğundan emin olun - daha fazla bilgiyi AWS EC2 API araçları belgelerinde bulabilirsiniz.

Komutu önce elle test edebilir ve ardından her şey yolunda gittiğinde, Windows'ta Unix crontab veya Zamanlanmış Görevler'i yapılandırabilirsiniz. Linux / etc / crontab dosyası için aşağıdaki örneği bulabilirsiniz (yukarıda bahsedilen tüm ortam değişkenlerinin 'hesabınız' kullanıcısı için mevcut olması gerektiğini unutmayın.

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

AWS araçlarını (bahsettiklerim dahil) denemek isteyebileceğiniz ücretsiz, kullanımı kolay bir yükleyicide paketlediğimiz BitNami Cloud projesi için bir geliştiriciyim: BitNami CloudTools paket yığını


2
Bunun için hala başka bir örneğiniz olması gerekiyor. Çünkü kapatmak sorun değil, başlangıçtır. Kapandıktan sonra ölü bir bilgisayarda Crone veya herhangi bir şey çalışmayacaktır.
Upul Doluweera

Ben takip adımları benim Amazon Linux Derece kurulum AWS CLI Araçlarına. Örneği durdurmak iyi çalışıyor. Ancak zaten durdurulmuş bir örneğin başlatılması 400 hatası veriyor, Örnek Kimliği bulunamadı. Zaten durdurulmuş örneği nasıl başlatabilirim?
Amol Chakane

17

EC2 komut satırı araçlarını kullanarak ihtiyacınız olanı nasıl yapacağınızı gösteren EC2 Başlangıç ​​Kılavuzuna bir göz atmanızı tavsiye ederim . Başlatma ve durdurma komutlarını belirli bir zamanda çağırmak için bunu bir cron işi (Linux / UNIX üzerinde) veya Windows'ta zamanlanmış bir işe kolayca komut dosyası oluşturabilirsiniz.

Bunu kendi kodunuzdan yapmak istiyorsanız, SOAP veya REST API'lerini kullanabilirsiniz; ayrıntılar için Geliştirici Kılavuzuna bakın.


16

Bunu yapmak için Python'da Boto kütüphanesini kullanarak kod yazdım. Bunu kendi kullanımınız için ayarlayabilirsiniz. Bunu bir cron işinin bir parçası olarak çalıştırdığınızdan emin olun ve ardından cron işleri çalışırken ihtiyaç duyduğunuz kadar çok örneği başlatabilir veya kapatabilirsiniz.

#!/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
Bu, Elastic Beanstalk ortamları için de mümkün müdür?
Amol Chakane

5

Görev açısından kritik değilse - Yapılması gereken basit bir şey, toplu iş dosyasını her gün 3: 00'da 'KAPATMA' (pencereler) çalıştıracak şekilde programlamaktır. O zaman en azından yanlışlıkla istenmeyen bir örneği süresiz olarak çalıştırma riskiyle karşı karşıya kalmazsınız.

Açıkçası bu, hikayenin sadece yarısı!


5

Çalıştığım şirketin müşterileri düzenli olarak bunu soruyordu, bu yüzden burada ücretsiz bir EC2 planlama uygulaması yazdık:

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

Windows ve Mac'te çalışır, birden fazla günlük / haftalık / aylık program oluşturmanıza olanak tanır ve çok sayıda örneği kolayca dahil etmek için eşleşen filtreleri kullanmanıza veya gelecekte ekleyeceğinizleri dahil etmenize olanak tanır.


2

AWS Data Pipeline sorunsuz çalışıyor. https://aws.amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instances/

Başlamadan günleri hariç tutmak istiyorsanız (örneğin, hafta sonu) bir ShellCommandPrecondition nesnesi ekleyin.

AWS Console / Data Pipeline'da yeni bir ardışık düzen oluşturun. Bir tanımı (JSON) düzenlemek / içe aktarmak daha kolaydır

    {
"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 komut dosyasını indirilecek ve S3 klasörünüzde ön koşul olarak çalıştırılacak şekilde yerleştirin

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

Hafta sonu günlerinde ardışık düzeni etkinleştirip çalıştırırken, AWS konsolu Ardışık Düzen Durumu Durumu yanıltıcı bir "HATA" okur. Bash betiği bir hata verir (çıkış 1) ve EC2 başlatılmaz. 1 ila 5. günlerde durum "SAĞLIKLI" dır.

EC2'yi ofis kapanış saatinde otomatik olarak durdurmak için, ön koşul olmaksızın her gün AWS CLI komutunu kullanın.


1

Bunu yapmak için Ylastic'e bakabilirsin . Alternatif, bir cron işi veya zamanlanmış görev kullanarak diğer örnekleri kapatan / başlatan çalışan bir makineye sahip olmak gibi görünüyor.

Açıkçası, sadece bir örnek istiyorsanız, bu pahalı bir çözümdür, çünkü bir makinenin her zaman çalışıyor olması gerekir ve cron işlerini yürütmek için bir makineye ayda ~ 80 $ ödeme yapmak uygun maliyetli değildir.


1

Otomatik Ölçekleme, örnekleri sonlandırmakla sınırlıdır. Bir örneği durdurmak ve sunucu durumunu korumak istiyorsanız, en iyi yaklaşım harici bir komut dosyasıdır.

Bunu, 7/24 çalışan başka bir örnekte bir iş çalıştırarak yapabilir veya Ylastic (yukarıda bahsedilen) veya Rocket Peak gibi bir 3. taraf hizmeti kullanabilirsiniz .

Örneğin, C # 'da bir sunucuyu durdurma kodu oldukça basittir:

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, bir otomatik ölçeklendirme grubuna bir program eklemek, daha önce belirtildiği gibi en iyi "bulut benzeri" yaklaşımdır.

Ancak örneklerinizi sonlandırıp yenilerini kullanamamanız durumunda, örneğin, vb. İle ilişkili Esnek IP'leriniz varsa.

Örneklerinizi bir tarih zaman aralığına göre başlatmak ve durdurmak için bir Ruby komut dosyası oluşturabilirsiniz.

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

Heroku Scheduler'ı kullanarak ücretsiz bir zamanlayıcı oluşturmak için amazon_start_stop'a bir göz atın .


1

Otomatik ölçeklendirmeyi kullanarak bunu başarmanın yolları olsa da, örnekleri sonlandırdığı için tüm durumlar için uygun olmayabilir. Cron işleri hiçbir zaman tek bir örnek için çalışmaz (tek bir örneği durdurmak ve birçok örneği çalıştırırken diğer örnekleri zamanlamak gibi durumlarda mükemmel bir şekilde kullanılabilir). Sen gibi API çağrıları kullanabilirsiniz StartInstancesRequest ve StopInstancesRequest aynı elde etmek ancak yine bir üçüncü kaynak güvenmek zorunda. Birçok özelliğe sahip AWS örneklerini planlamak için birçok uygulama vardır ancak basit bir çözüm için snapleaf.io gibi ücretsiz bir uygulama öneririm


1

Evet, bunu AWS Lambda kullanarak yapabilirsiniz. UTC'deki Cron ifadelerinde çalışan tetikleyiciyi Cloudwatch'ta seçebilirsiniz.

İlgili bir bağlantı https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/

Başka alternatif kullanım için awscliedinilebilir pip, apt-get, yumveya brew, sonra çalışan aws configureIAM ihraç Kimlik bilgilerinizle ve kullanıcılarla etiketlendiği bir EC2 durdurmak için aşağıdaki bash komut yürütme Name: Appnameve Value: Appname Prod. awscliÖrneklerinizi etiketlemek veya AWS konsolundan manuel olarak etiketlemek için kullanabilirsiniz . aws ec2 stop-instancesörneği durdurur ve jqjson sorgusunu filtrelemek ve içindeki etiketleri kullanarak doğru örnek kimliğini getirmek için kullanılır aws ec2 describe-instances.

Bunun aws configurebaşarılı olduğunu ve json çıktı çalışması döndürdüğünü doğrulamak için aws ec2 describe-instancesve çalışan örnek kimliğiniz çıktıda olmalıdır. İşte örnek bir çıktı

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

Aşağıdaki darbe komut olduğu stop-ec2.shiçinde /home/centos/cron-scripts/olan esinlenerek bu yüzden post

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

Dosyayı kullanarak çalıştırın ve sh /home/centos/cron-scripts/stop-ec2.shEC2 bulut sunucusunun durdurulduğunu doğrulayın. Çalıştırmak için hata ayıklamak 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 .[].InstanceIdve etiketlenmiş doğru örnek kimliğini döndürdüğünü görmek için.

Sonra crontab -eaşağıdaki satıra eklenebilir

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

hangi çıktıyı günlüğe kaydeder /tmp/stop. 30 14 * * *Check-in ki UTC cron ifadesidir https://crontab.guru/. Benzer şekilde ile değiştirmek aws ec2 start-instancesbir örneği başlatabilir.


0

İlk sorunun biraz kafa karıştırıcı olduğuna inanıyorum. Pasta'nın neye ihtiyacı olduğuna bağlıdır: 1. başlat / sonlandır (örnek deposu) - Otomatik Ölçeklendirme doğru çözümdür (Nakedible'ın yanıtı) 2. EBS önyükleme örneğini başlat / durdur - Otomatik Ölçeklendirme yardımcı olmaz, uzaktan programlanmış komut dosyaları kullanırım (ör. , ec2 CLI).


-8

Bunu otomatik olarak veya en azından komut dosyalarında bazı programlama ve API işlemleri olmadan yapamazsınız. Görüntülerinizi durdurmak, yeniden başlatmak ve yönetmek için (muhtemelen ortamınızdaki maliyetleri kontrol etmek için) güvenilir bir çözüm istiyorsanız, LabSlice'a bakabilirsiniz . Sorumluluk reddi: Bu şirket için çalışıyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.