자동 종료 및 Amazon EC2 인스턴스 시작


90

Amazon API를 사용하여 Amazon 인스턴스를 자동으로 시작하고 종료 할 수 있습니까? 어떻게 할 수 있는지 설명해 주시겠습니까? 이상적으로는 매일 지정된 시간 간격으로 인스턴스를 시작하고 인스턴스를 중지해야합니다.


2
EC2 인스턴스가 종료되면 데이터는 어떻게됩니까? 지속됩니까? 아니면 다시 재 구축해야합니까?
Matthew Lock

Amazon API를 사용하여 인스턴스를 자동으로 시작하고 종료하면 해당 이벤트에서 데이터가 손실 될 수 있습니다. 나는 중지를 추천 & 사용하여 작업을 복구 것 AWS CloudWatch에서 알람
Chetabahana

Amazon API 대신 AWS Lambda를 사용하여 EC2 시작 / 중지예약 하는 것이 좋습니다 . 귀하의 경우 비용은 월 $ 0.0004 USD 미만입니다.
Chetabahana

답변:


102

누군가가이 예전 질문을 우연히 발견 할 경우를 대비하여 요즘에는 Auto Scaling 그룹에 일정을 추가하여 동일한 결과를 얻을 수 있습니다. Auto Scaling 그룹의 인스턴스 수를 특정 시간에 1로 늘리고 나중에 다시 0으로 줄입니다. .

그리고이 답변은 많은 견해를 얻고 있기 때문에 이에 대한 매우 유용한 가이드를 링크하려고 생각했습니다. Auto Scaling을 사용하여 반복 일정에 따라 EC2 인스턴스 실행


6
링크에 설명 된 방법을 시도해 보았고 실제로 튜토리얼에 지정된 시간에 인스턴스를 시작 / 중지합니다. 그러나 AWS 웹 콘솔에서 인스턴스가이 방법으로 시작될 때 키로 시작되지 않고 (예 : ssh로 들어갈 수 있음), 또한 저와 동일한 항목을 갖지 않는 것 같습니다. 테스트로 사용하는 마이크로 인스턴스에 설치되었습니다 (클라우드 전문가는 아니지만 이것이 스핀 업 된이 새 인스턴스가 EBS에 연결되어 있지 않다는 의미라고 생각합니까?) 자동으로 시작하는 방법이 있습니까? 일정에 따라 동일한 인스턴스를 중지 하시겠습니까?
Kiran K.

@KiranK. 즉, 현재 사용중인 EBS 볼륨에 새 인스턴스가 연결되지 않았습니까? 무엇을 사용 했습니까?
밀짚 모자

26

Amazon EC2 API 도구를 직접 사용해 볼 수 있습니다. 실제로 필요한 명령은 ec2-start-instances 및 ec2-stop-instances입니다. 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 도구 (내가 언급 한 도구 포함)를 시도해 볼 수있는 사용하기 쉬운 무료 설치 프로그램으로 패키징 합니다. BitNami CloudTools 팩 스택


2
이를 위해서는 다른 인스턴스가 필요합니다. 종료는 문제가 아니라 시작이기 때문입니다. Crone 또는 그 어떤 것도 종료 된 후에 죽은 컴퓨터에서 실행되지 않습니다.
Upul Doluweera

AMazon Linux 인스턴스에서 AWS CLI 도구를 설정하기 위해 다음 단계 를 따랐습니다 . 인스턴스를 중지하면 정상적으로 작동합니다. 그러나 이미 중지 된 인스턴스를 시작하면 400 오류가 발생하고 Instance Id not found. 이미 중지 된 인스턴스를 시작하려면 어떻게해야합니까?
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시에 '종료'(Windows)를 실행하도록 배치 파일을 예약하는 것이 간단합니다. 그러면 적어도 원치 않는 인스턴스가 무한정 실행되도록 실수로 남겨 둘 위험이 없습니다.

분명히 이것은 이야기의 절반에 불과합니다!


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 콘솔 Pipeline Health Status에 잘못된 "ERROR"가 표시됩니다. bash 스크립트가 오류 (exit 1)를 반환하고 EC2가 시작되지 않습니다. 1 ~ 5 일의 상태는 "HEALTHY"입니다.

퇴근 시간에 EC2를 자동으로 중지하려면 전제 조건없이 매일 AWS CLI 명령을 사용하십시오.


1

이를 위해 Ylastic 을 볼 수 있습니다. 대안은 크론 작업 또는 예약 된 작업을 사용하여 다른 인스턴스를 종료 / 시작하는 하나의 시스템을 실행하는 것 같습니다.

하나의 인스턴스 만 원하는 경우에는 한 대의 컴퓨터가 항상 실행되어야하고 한 대의 컴퓨터가 크론 작업을 실행하는 데 월 ~ $ 80를 지불하는 것은 비용 효율적이지 않기 때문에 비용이 많이 드는 솔루션입니다.


1

AutoScaling은 인스턴스 종료로 제한됩니다. 인스턴스를 중지하고 서버 상태를 유지하려면 외부 스크립트가 가장 좋은 방법입니다.

연중 무휴로 실행되는 다른 인스턴스에서 작업을 실행하여이를 수행하거나 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

IMHO가 Auto Scaling 그룹에 일정을 추가하는 것은 앞서 언급 한 바와 같이 최상의 "클라우드 유사"접근 방식입니다.

그러나 인스턴스를 종료하고 새 인스턴스를 사용할 수없는 경우 (예 : 탄력적 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

Heroku Scheduler를 사용하여 무료로 스케줄러를 생성하려면 amazon_start_stop 을 살펴보십시오 .


1

자동 확장을 사용하여이를 달성 할 수있는 방법이 있지만 인스턴스를 종료하므로 모든 경우에 적합하지 않을 수 있습니다. 크론 작업은 단일 인스턴스에 대해 작동하지 않습니다 (단일 인스턴스를 중지하고 여러 인스턴스를 실행할 때 다른 인스턴스를 예약하는 것과 같은 상황에 완벽하게 사용할 수 있음). StartInstancesRequestStopInstancesRequest 와 같은 API 호출을 사용 하여 동일한 결과 를 얻을 수 있지만 다시 세 번째 리소스에 의존해야합니다. 많은 기능이있는 AWS 인스턴스를 예약하는 많은 애플리케이션이 있지만 간단한 솔루션의 경우 snapleaf.io 와 같은 무료 앱을 권장합니다.


1

예, AWS Lambda를 사용하여 수행 할 수 있습니다. UTC의 Cron 표현식에서 실행되는 Cloudwatch에서 트리거를 선택할 수 있습니다.

다음은 관련 링크입니다 https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/

또 다른 대안은 사용하는 것입니다 awscli에서 사용할 수 pip, apt-get, yum또는 brew다음 실행 aws configureIAM에서 내 보낸 사용자의 자격 증명 및 태그되었습니다 EC2 중지하려면 다음 bash는 스크립트를 실행 Name: Appname하고를 Value: Appname Prod. 를 사용 awscli하여 인스턴스에 태그를 지정하거나 AWS 콘솔에서 수동으로 태그를 지정할 수 있습니다. aws ec2 stop-instances인스턴스를 중지하고 jqjson 쿼리를 필터링하고에서 태그를 사용하여 올바른 인스턴스 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.shEC2 인스턴스가 중지되었는지 확인합니다. 실행을 디버그 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/stop. 는 30 14 * * *당신이 확인할 수있는 UTC 크론 표현이다 https://crontab.guru/. 마찬가지로로 바꾸면 aws ec2 start-instances인스턴스를 시작할 수 있습니다.


0

나는 초기 질문이 약간 혼란 스러웠다 고 생각합니다. 파스타에 필요한 사항에 따라 다릅니다. 1. 시작 / 종료 (인스턴스 스토어)-Auto Scaling이 올바른 솔루션입니다 (Nakedible의 답변) 2. EBS 부팅 인스턴스 시작 / 중지-Auto Scaling이 도움이되지 않습니다. 원격 예약 스크립트를 사용합니다 (예 : , ec2 CLI).


-8

이 작업을 자동으로 수행 할 수 없거나 적어도 스크립트 파일에서 프로그래밍 및 API 조작 없이는 수행 할 수 없습니다. 이미지를 중지, 다시 시작 및 관리하는 신뢰할 수있는 솔루션 (아마도 환경의 비용을 제어하기 위해)을 원한다면 LabSlice 를 살펴볼 수 있습니다 . 면책 조항 : 저는이 회사에서 일합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.