cron
GoogleAppEngine
googlecomputeengine
GoogleCloudPlatform
gce

GCEの自動起動・自動停止をスケジューリングする

More than 1 year has passed since last update.


今回やりたいこと

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ジョブから下記のように設定したものが確認できる

スクリーンショット 2016-04-26 1.08.38.png

後は画面上から「今すぐ実行」するなり時間になるまでまつと指定したインスタンスが自動起動、自動停止するはず


Tips

3rd party製のツールを使用する際には下記のようにコマンドをうってDjangoのlib内にインストールする

公式ドキュメント

pip install -t lib oauth2client