Amazon API를 사용하여 Amazon 인스턴스를 자동으로 시작하고 종료 할 수 있습니까? 어떻게 할 수 있는지 설명해 주시겠습니까? 이상적으로는 매일 지정된 시간 간격으로 인스턴스를 시작하고 인스턴스를 중지해야합니다.
Amazon API를 사용하여 Amazon 인스턴스를 자동으로 시작하고 종료 할 수 있습니까? 어떻게 할 수 있는지 설명해 주시겠습니까? 이상적으로는 매일 지정된 시간 간격으로 인스턴스를 시작하고 인스턴스를 중지해야합니다.
답변:
누군가가이 예전 질문을 우연히 발견 할 경우를 대비하여 요즘에는 Auto Scaling 그룹에 일정을 추가하여 동일한 결과를 얻을 수 있습니다. Auto Scaling 그룹의 인스턴스 수를 특정 시간에 1로 늘리고 나중에 다시 0으로 줄입니다. .
그리고이 답변은 많은 견해를 얻고 있기 때문에 이에 대한 매우 유용한 가이드를 링크하려고 생각했습니다. Auto Scaling을 사용하여 반복 일정에 따라 EC2 인스턴스 실행
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 팩 스택
EC2 명령 줄 도구를 사용하여 필요한 작업을 수행하는 방법을 보여주는 EC2 시작 안내서를 살펴 보는 것이 좋습니다 . 이를 cron 작업 (Linux / UNIX에서) 또는 Windows에서 예약 된 작업으로 쉽게 스크립팅하여 주어진 시간에 시작 및 중지 명령을 호출 할 수 있습니다.
자체 코드에서이 작업을 수행하려면 SOAP 또는 REST API를 사용할 수 있습니다. 자세한 내용은 개발자 안내서 를 참조하십시오.
이 작업을 수행하기 위해 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])
제가 일하는 회사는 고객이 정기적으로 이에 대해 물어 보았으므로 여기에서 사용할 수있는 프리웨어 EC2 스케줄링 앱을 작성했습니다.
http://blog.simple-help.com/2012/03/free-ec2-scheduler/
Windows 및 Mac에서 작동하며 매일 / 주간 / 월간 일정을 여러 개 만들 수 있으며 일치하는 필터를 사용하여 많은 수의 인스턴스를 쉽게 포함하거나 나중에 추가 할 인스턴스를 포함 할 수 있습니다.
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 명령을 사용하십시오.
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));
}
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 을 살펴보십시오 .
자동 확장을 사용하여이를 달성 할 수있는 방법이 있지만 인스턴스를 종료하므로 모든 경우에 적합하지 않을 수 있습니다. 크론 작업은 단일 인스턴스에 대해 작동하지 않습니다 (단일 인스턴스를 중지하고 여러 인스턴스를 실행할 때 다른 인스턴스를 예약하는 것과 같은 상황에 완벽하게 사용할 수 있음). StartInstancesRequest 및 StopInstancesRequest 와 같은 API 호출을 사용 하여 동일한 결과 를 얻을 수 있지만 다시 세 번째 리소스에 의존해야합니다. 많은 기능이있는 AWS 인스턴스를 예약하는 많은 애플리케이션이 있지만 간단한 솔루션의 경우 snapleaf.io 와 같은 무료 앱을 권장합니다.
예, AWS Lambda를 사용하여 수행 할 수 있습니다. UTC의 Cron 표현식에서 실행되는 Cloudwatch에서 트리거를 선택할 수 있습니다.
다음은 관련 링크입니다 https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/
또 다른 대안은 사용하는 것입니다 awscli
에서 사용할 수 pip
, apt-get
, yum
또는 brew
다음 실행 aws configure
IAM에서 내 보낸 사용자의 자격 증명 및 태그되었습니다 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/stop
. 는 30 14 * * *
당신이 확인할 수있는 UTC 크론 표현이다 https://crontab.guru/
. 마찬가지로로 바꾸면 aws ec2 start-instances
인스턴스를 시작할 수 있습니다.
이 작업을 자동으로 수행 할 수 없거나 적어도 스크립트 파일에서 프로그래밍 및 API 조작 없이는 수행 할 수 없습니다. 이미지를 중지, 다시 시작 및 관리하는 신뢰할 수있는 솔루션 (아마도 환경의 비용을 제어하기 위해)을 원한다면 LabSlice 를 살펴볼 수 있습니다 . 면책 조항 : 저는이 회사에서 일합니다.