EC2로 작업을 하다보면, 우리가 실제로 사용하는 시간과 아예 사용하지 않는 시간이 따로 나뉘어져 있다.
회사로 예를 들자면, 오전 9시부터 오후 6시와 같이 사무실에서 일하는 시간 외에는 전혀 EC2 인스턴스에 접근할 일이 없는 경우이다.
(물론 야근이 없다면..😂)
따로 인스턴스를 중지 상태로 만들어주지 않는 이상 실행중이기 때문에 계속 초당 비용이 청구될 수 밖에 없어 굉장한 잉여 비용이다.
때문에, AWS Instance Scheduler를 설정해주어, 우리가 원하는 시간대에만 인스턴스를 실행 상태로, 그 외에 시간에는 인스턴스를 중지 상태로 만들어 비용 관리를 효율적으로할 수 있다.
사전 지식 및 작업
- IAM
IAM 설정은 꼭 사전에 습득하고 와야 해당 포스팅에 대해서 매끄럽게 진행이 가능하다!
그리고, 아래의 링크를 통해서 Scheduler CLI 를 미리 설치하고, IAM 권한도 꼭 잊지 않고 설정해주어야 한다.
https://docs.aws.amazon.com/solutions/latest/instance-scheduler/scheduler-cli.html
AWS Instance Scheduler 구성도
우리는 해당 스케줄 설정으로 EC2 인스턴스 뿐만 아니라, RDS 인스턴스도 원하는 시간대에 실행/중지 상태로 만들 수 있지만, 이번 포스팅에서는 EC2만 다룰 예정이다.
구조를 간단하게 살펴조자면 Amazon CloudWatch의 EventBridge 서비스에서 cron 설정으로 인해 주기적으로 Lambda 함수에 트리거 하도록 되어 있다. 그리고 Lambda 함수에서는 DynamoDB에 있는 설정 값을 통해서 특정 스케줄 태그가 붙어 있는 인스턴스의 상태를 변경하도록 한다. 처음에는 구조를 보고 이해하긴 쉽지 않다. 아래에서 작업을 해보고 다시 돌아와서 이해해도 늦지 않는다.
어..? 저는 CloudWatch도 DynamoDB도 심지어 Lambda 코드까지 작성할 수가 없는데요?
처음에는 구조를 보고 적잖이 당황했다. 사실 마냥 간단해 보이는 작업같진 않아 보인다.
그래서 그런지, AWS는 리소스를 한 번에 생성해줄 수 있도록 CloudFormation 템플릿을 제공해주고 있었다.
작업 시작
CloudFormation 템플릿으로 리소스 생성하기
콘솔에 로그인 후, CloudFormation 서비스에서 스택을 생성하는 작업을 진행한다.
준비된 템플릿을 선택하고 템플릿 소스는 Amazon S3 URL, 그리고 아래의 URL을 붙여넣기하고 다음으로 넘어간다.
우리가 여기서 설정해야 하는 부분은 스택 이름, Region(s), Default time zone, Frequency, Enable CloudWatch Logs, Started tags, Stopped tags 부분이다. 아래의 내용대로 설정해주되, 리전이나 Frequency(빈도) 부분은 직접 설정해주면 되는 선택 사항이다. 문서에 따르면, Lambda 함수를 통해 인스턴스 상태를 작업하기 때문에, 스케줄 작업에 포함된 인스턴스 수가 많으면 많을수록 빈도를 높게 설정하라는게 좋다고 한다. (나중에 변경이 가능하기 때문에 일단은 5분으로 설정하는 것을 권장한다.)
Region(s) : ap-northeast-2 # 선택사항
Default time zone : Asia/Seoul # 선택사항
Frequency : 5 # 분 단위, 스케줄이 동작할 주기를 의미함, 선택사항
Enable CloudWatch Logs : Yes
Started tags : state=started # 현재 인스턴스의 실행 상태를 식별하기 위한 태그
Stopped tags : state=stopped # 현재 인스턴스의 중지 상태를 식별하기 위한 태그
설정을 완료했다면, 다음으로 진행한다.
3단계인 스택 옵션 구성은 별 다른 설정없이 다음으로 진행한다.
마지막 4단계 검토에서는 'AWS CloudFormation에서 IAM 리소스를 생성할 수 있음을 승인합니다.' 문구만 체크해주고 스택을 생성하면 된다. 그리고, Cloudformation 스택 메뉴에서 확인해주면 우리가 설정한 스택 이름으로된 스택이 하나 생성되고 있음을 확인할 수 있다.
Scheduler CLI를 통한 원하는 시간대로 스케줄 조정 (feat. DynamoDB)
이제 사전 작업에서 설치한 Scheduler CLI를 통해서 우리가 원하는 시간대에 인스턴스 상태를 바꿀 수 있는 스케줄을 등록한다.
# 평일 스케줄
scheduler-cli create-period \
--stack {설정한_CloudFormation_스택_이름} \
--region {리전_이름} \
--name office-time \
--begintime 09:00 --endtime 18:00 \
--weekdays mon-fri
# 주말 스케줄
scheduler-cli create-period \
--stack {설정한_CloudFormation_스택_이름} \
--region {리전_이름} \
--name weekend-time \
--begintime 09:00 --endtime 18:00 \
--weekdays sat-sun
우리는 파라미터로 인스턴스의 상태를 시작(--begintime)하고 중지(--endtime)하는 시간을 설정할 수 있고, 요일(--weekdays)도 지정할 수 있다. 이제 DynamoDB 서비스로 이동하여 CLI 명령이 제대로 입력됐는지 확인해보자.
DynamoDB 서비스에서 ConfigTable의 항목을 확인해보면,
다음과 같이 우리가 CLI를 통해 설정한 period 타입의 office-time이 생성되어 있다. 이것을 통해 schedule 타입의 스케줄을 생성해주면 된다.
scheduler-cli create-schedule \
--stack Ec2instanceScheduler \
--name office-time \
--region ap-northeast-2 \
--periods office-time \
--timezone Asia/Seoul
scheduler-cli create-schedule \
--stack Ec2instanceScheduler \
--name weekend-time \
--region ap-northeast-2 \
--periods weekend-time \
--timezone Asia/Seoul
이제 설정은 거의 다 끝났다!
인스턴스 태그를 통한 스케줄 설정
EC2 서비스로 들어가 우리는 위에서 설정한 스케줄 office-time을(혹은, weekend-time) 인스턴스에 태그를 지정해주면 설정이 완료된다.
태그의 Key는 Schedule, Value는 위에서 CLI를 통해 설정한 schedule의 이름을 넣으면 된다.
CloudWatch Log를 통해 확인
계속 모니터링을 하기엔 너무 비효율적이다. CloudWatch 서비스를 이용해 로그스트림을 확인하여 제대로 동작하는지, 동작하지 않는다면 어떤 이유인지 확인해보도록 하자.
CloudFormation 이름에 맞춰서 로그 그룹이 생성되는데, 이곳에 들어가서 'Scheduler-ec2 ~~' 로 시작되는 로그 스트림을 확인하면 된다. 확인을 한 번 해봤더니...
스케줄 이름을 알 수 없다는 에러가 나왔는데, 우리가 위에서 설정한 내용대로 했다면 문제없다! 필자는 착각하여 period 까지만 설정하는 실수를 해버렸다.. (혹시, 해당 에러가 발생한다면 schedule이 설정이 안 된 것이므로, 등록만 해주면 된다!)
필자가 임의로 테스트 진행을 위해 오후 5시 55분에 인스턴스를 실행하고, 오후 6시 30분에 인스턴스를 종료하는 'test' 스케줄을 등록하고 진행해본 결과이다.
잘 보면 인스턴스가 scheduler에 의해 실행됐다(started) 라는 문구를 볼 수 있다.
주의사항
그렇다면, 우리가 그냥 임의로 인스턴스를 실행하고 종료하는 스케줄을 막 설정해도 되는걸까? 결론을 말하자면 아니다. 인스턴스를 중지하고 실행하는 데에는 꽤나 많은 공수가 들어가야 한다.
- 임시 메모리를 사용하는 애플리케이션이라면! 인스턴스 중지 전에, 인스턴스에 저장된 임시 메모리를 해결해야 한다.
- 스케줄 자동화를 위해 인스턴스 실행 시에, 프로세스도 실행해주는 스크립트를 작성해야 한다.
매일 개발 및 테스트를 해야하는 서버라면 스크립트가 필수이다. 아니면 관리가 매우 어려워진다! - 애플리케이션의 동작 흐름을 파악하여 시스템을 실행 및 중지한다.
이를 테면, 아주 간단한 웹 애플리케이션이라도 프로세스를 종료할 때는 데이터베이스 -> WAS서버 -> WEB서버 순으로 종료하는 게 권장되기 때문에 동작 흐름을 잘 파악해주어 시스템 실행 및 중지 순서를 구성해야 한다.
Reference
https://aws.amazon.com/ko/premiumsupport/knowledge-center/stop-start-instance-scheduler/