こんにちは。GMO NIKKO エンジニアのN.I.です。
今回は検証環境のCompute Engine インスタンスを平日の9:30~21:00に自動起動して自動停止する仕組みを作成したのでこちらを紹介したいと思います。
今回の記事は下記GCPのを参考に作成していますが、GCPの記事のリソースラベルの設定が動作せず、instancesClient.listで該当のサーバー(instances.items)をうまく取得できなかった為、今回の紹介する内容はシンプルにCompute Engineのインスタンス名で起動、停止を実行する方法を紹介します。https://cloud.google.com/scheduler/docs/start-and-stop-compute-engine-instances-on-a-schedule?hl=JA
アプリケーション フロー
Compute Engineを自動起動/停止するためのフローは下記の様になります。- Cloud Scheduler ジョブ : スケジュールに従ってインスタンスの起動と停止情報をPub/Subに送付します。
- Pub/Subメッセージ : インスタンスの起動/停止のメッセージをCloud Schedulerから受信してCloud Functionsに情報を渡します。
- Cloud FunctionからCompute Engineの開始/停止指示を実施します。
- Compute Engineが開始/停止されます。
下記設定で作成したサーバーを停止起動出来るか確認します。
サーバー名 : testserver
ゾーン : asia-northeast1-b
では、実際に設備を作っていきます。
Pub/SubとCloud Functionsを設定する
まずpub/sub、Cloud Functionsを作成します。今回はGCP管理画面から作成する方法で説明します。-
- Cloud Console の [Cloud Functions] ページに移動します。
- 画面上部の [関数の作成] をクリックします。
- [関数名] に gceInstancepubsub を入力します。
- [リージョン] に asia-northsast1 (Tokyo) を選択します。
- [トリガーのタイプ] に Cloud Pub/Sub を選択します。
- [Cloud Pub/Sub トピックを選択してください] をクリックし、トピックを作成する をクリックします。
- [トピックの作成] ダイアログ ボックスが表示されます。
- [トピック ID ] に gceinstance-event を入力します。 (スキーマを使用する,メッセージの保持期間を設定する,顧客管理の暗号鍵を使用するの項目はチェック不要です。)
- [トピックを作成] をクリックしてダイアログ ボックスを閉じます。
- [トリガー] ボックスの下部にある [保存] をクリックします。
- ページの下部にある [次へ] をクリックします。
- [ランタイム] で [Node.js 16] を選択します。
- [エントリ ポイント] に gceinstancepubsub と入力します。
- コードエディタの左側にある [index.js] を選択します。
- コードを次のコードに置き換えます。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859const compute = require('@google-cloud/compute');const instancesClient = new compute.InstancesClient({fallback: 'rest'});/*** Start/Stop Compute Engine instances.*/exports.gceinstancepubsub = async (event, context, callback) => {try {const project = await instancesClient.getProjectId();const payload = _validatePayload(event);var message = '';if (payload.svstatus == 'start') {const options = {project,zone: payload.zone,instance: payload.instance,};await instancesClient.start(options);message = 'Successfully started instance ' + payload.instance;} else if (payload.svstatus == 'stop') {const options = {project,zone: payload.zone,instance: payload.instance,};await instancesClient.stop(options);message = 'Successfully stopped instance ' + payload.instance;}console.log(message);callback(null, message);} catch (err) {console.log(err);callback(err);}};/*** Validates that a request payload contains the expected fields.** @param {!object} payload the request payload to validate.* @return {!object} the payload object.*/const _validatePayload = event => {let payload;try {payload = JSON.parse(Buffer.from(event.data, 'base64').toString());} catch (err) {throw new Error('Invalid Pub/Sub message: ' + err);}if (!payload.zone) {throw new Error("Attribute 'zone' missing from payload");} else if (!payload.instance) {throw new Error("Attribute 'instance' missing from payload");}else if (!payload.svstatus) {throw new Error("Attribute 'instancestatus' missing from payload");}return payload;};
- コードエディタの左側にある [package.json] を選択します。
- コードを次のコードに書き換えます。
1234567891011121314151617{"name": "schedule-gceinstance","version": "1.0.0","private": true,"engines": {"node": ">=12.0.0"},"devDependencies": {"mocha": "^9.0.0","proxyquire": "^2.0.0","sinon": "^11.0.0"},"dependencies": {"@google-cloud/compute": "^3.0.0","googleapis": "^89.0.0"}}
- ページの下部にある [デプロイ] をクリックします。
※エラーになった場合は [package.json]が上記以外にsampleが登録されることがあるみたいなので削除して再度デプロイを行ってください。
Cloud Schedulerを設定する
Cloud Schedulerからインスタンスの起動/停止のメッセージを送付します。 下記手順で作成します。サーバー開始の作成
- Cloud Console の [Cloud Scheduler] ページに移動します。
- [ジョブを作成] をクリックします。
- [スケジュールを定義する] を入力します。
- [名前] を startup-testserver (任意) を入力します。
- [頻度] に 30 9 * * 1-5 を入力します。 (この例では平日9時30分に設定しています。任意で時間変更下さい。)
- [タイムゾーン] で、日本標準時 (JST) を選択します。
- [続行] をクリックします。
- [実行内容を構成する] を入力します。
- [ターゲットタイプ] で、 [Pub/Sub] を選択します。
- [トピック] に gceinstance-event と入力します。
- [メッセージ本文] に下記を入力します。
1{"zone":"asia-northeast1-b","instance":"testserver","svstatus":"start"}
- [続行] をクリックします。
- Configure the job’s retry (optional)になります。特に変更ありません。
- [作成] をクリックします。
サーバー停止の作成
- Cloud Console の [Cloud Scheduler] ページに移動します。
- [ジョブを作成] をクリックします。
- [スケジュールを定義する] を入力します。
- [名前] を shutdown-testserver (任意) を入力します。
- [頻度] に 0 21 * * 1-5 を入力します。 (この例では平日21時00分に設定しています。任意で時間変更下さい。)
- [タイムゾーン] で、日本標準時 (JST) を選択します。
- [続行] をクリックします。
- [実行内容を構成する] を入力します。
- [ターゲットタイプ] で、 [Pub/Sub] を選択します。
- [トピック] に gceinstance-event と入力します。
- [メッセージ本文] に下記を入力します。
1{"zone":"asia-northeast1-b","instance":"testserver","svstatus":"stop"}
- [続行] をクリックします。
- [Configure the job’s retry (optional)]は特に変更ありませんそのままで大丈夫です。
- [作成] をクリックします。
以上で設定完了です。スケジューラから [今すぐ実行] をクリックしてサーバーが開始/終了出来るか確認します。
CloudFunctionsで開始/停止テスト時に下記の様なログが出ます。実際にサーバーが停止されていたらOKです。
GECに作成したサーバーの自動起動/自動停止の設定は完了です。テストサーバーを決まった時間に開始/停止することで費用の節約になるので一回作れば約に立つと思います。
Cloud Schedulerはスケジュールを3個以上作成すると、有料になる為、料金にこだわる場合アメリカリージョンにE2-micro(無料枠)を作成しcloneのスケジューラからpub/subにメッセージを送付すれば同じことが出来ます。