Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
36
Help us understand the problem. What is going on with this article?
@hatappi

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

More than 5 years have 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 
36
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
hatappi

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
36
Help us understand the problem. What is going on with this article?