今回やりたいこと
GCEインスタンスの自動起動と自動停止をスケジューリングしたい。
例えば日中しか使わないから夜とかは停止しておいて朝になったら起動させることでコスト節約したいなどなど。。。
AWSでいうLambdaのScheduleイベントでEC2を自動起動&自動停止してみた#reinvent
GCPにはAWSのLambdaのようなGoogle Cloud Functionsがあるが
まだ出たばかりでLamdaのようなスケジューリングの機能はない。
※2016/04/25 現在
GCPでは今のところスケジューリングなどはGoogle App Engineのcronサービスを使うらしい。
https://cloud.google.com/appengine/docs/python/config/cron#Python_app_yaml_The_schedule_format
検証環境
- 今回はGAEはpythonのDjangoを使用します。
- gceを起動、再起動するためにはcompute apiを使用するので認証周りなどここらへんを参考にします。ここで取得したものを
credentials.json
とする
インスタンスリストを取得してみる
まずはインスタンスリストを取得して認証が正しく通っているかなどを確認する
#!/usr/bin/python
import os
from oauth2client.client import GoogleCredentials
from googleapiclient.discovery import build
root_path = os.path.dirname(os.path.realpath(__file__))
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = '【credentials.jsonへのpath】'
credentials = GoogleCredentials.get_application_default()
compute = build('compute', 'v1', credentials=credentials)
project = '【プロジェクト名】'
zone = '【gceのインスタンスがあるゾーン】'
result_exec = compute.instances().list(project=project, zone=zone).execute()
items = result_exec['items']
for item in items:
print '''
id is %s
name is %s
zone is %s
status is %s
''' %(item['id'], item['name'], item['zone'], item['status'])
cronの設定や実行スクリプトなど
cron.yaml
GAEのスケジュールはURLを指定して、そのスクリプトを実行する。
このファイルではいつどのURLにアクセスするかを指定する。
scheduleのformatに関してはここをみる
urlは任意でよい。
今回は/instance/startと/instance/stopを作成したとしておく
cron:
- description: instance start
url: /instance/start
schedule: every day 09:00
timezone: Asia/Tokyo
- description: instance stop
url: /instance/stop
schedule: every day 22:00
timezone: Asia/Tokyo
app.yaml
上記で設定したurlがアクセスした時に実行するscriptを定義する。
login: admin
と設定しているのは仮にURLをたたかれた時に認証をさせるため
-----
handlers:
- url: /instance/start
script: instance.app
login: admin
- url: /instance/stop
script: instance.app
login: admin
instance.py
起動したり停止したりするスクリプトがかかれたスクリプト
#!/usr/bin/python
import os
import sys
import webapp2 as webapp
from google.appengine.ext import vendor
vendor.add('lib')
from oauth2client.client import GoogleCredentials
from googleapiclient.discovery import build
root_path = os.path.dirname(os.path.realpath(__file__))
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = '【credentials.jsonへのpath】'
project = '【プロジェクト名】'
zone = '【gceのインスタンスがあるゾーン】'
instance_names = [インスタンス名の配列]
credentials = GoogleCredentials.get_application_default()
compute = build('compute', 'v1', credentials=credentials)
# 開始用のHandler class
class InstanceStartHandler(webapp.RequestHandler):
def get(self):
print 'instance start process start'
for instance_name in instance_names:
# project, zone, instance名からインスタンスの情報を取得
instance = compute.instances().get(project=project, zone=zone, instance=instance_name).execute()
print '%s is %s' %(instance['name'], instance['status'])
# インスタンスが停止している場合は開始処理を行う
if instance['status'] == 'TERMINATED':
print 'instance %s start......' %(instance['name'])
compute.instances().start(project=project, zone=zone, instance=instance['name']).execute()
print 'instance start process end'
# 停止用のHandler class
class InstanceStopHandler(webapp.RequestHandler):
def get(self):
print 'instance stop process start'
for instance_name in instance_names:
# project, zone, instance名からインスタンスの情報を取得
instance = compute.instances().get(project=project, zone=zone, instance=instance_name).execute()
print '%s is %s' %(instance['name'], instance['status'])
# インスタンスが動いている場合は止める処理を行う
if instance['status'] == 'RUNNING':
print 'instance %s stop......' %(instance['name'])
compute.instances().stop(project=project, zone=zone, instance=instance['name']).execute()
print 'instance stop process end'
# app.yamlで設定したURLと実行するclassのセットを配列で定義する
app = webapp.WSGIApplication(
[
('/instance/start', InstanceStartHandler),
('/instance/stop', InstanceStopHandler)
],
debug=True
)
フォルダ構成
今回は3つファイルをいじったけどフォルダ構成は下記
※ GAEはDjangoを使用している想定です
今回作成・編集したファイルはroot_dirにおく
root_dir
├─ polls
| └─ ....
├─ lib
| └─ ....
├─ mysite
| └─ ....
└─ instance.py
└─ cron.yaml
└─ app.yaml
タスクのuploadと確認
- GAEのコードをデプロイするには
appcfg.py -A stellar-mercury-734 update app.yaml
- cron情報を更新するには
appcfg.py -A stellar-mercury-734 update_cron .
ここまでくるとGAEのタスクキューのcronジョブから下記のように設定したものが確認できる
後は画面上から「今すぐ実行」するなり時間になるまでまつと指定したインスタンスが自動起動、自動停止するはず
Tips
3rd party製のツールを使用する際には下記のようにコマンドをうってDjangoのlib内にインストールする
公式ドキュメント
pip install -t lib oauth2client