App Engineのインスタンスを定期的に再起動する
App Engineの自動再起動には超えるべきステップが二つある
- Google App Engine は Compute Engine のように素朴な VM ではないので OS 内部から再起動することはできない
- App Engine の instance は service, version で特定しないといけない
- App Engineには機能がないのでスケジュールは外部から与える必要がある
※ VM インスタンスの起動と停止をスケジュールする | Compute Engine ドキュメント | Google Cloud Compute Engine にはインスタンススケジュールがある
instanceの特定
App Engine の概要 | App Engine ドキュメント | Google Cloud
App Engine は以下のように
- service
- version
- instance
- version
という構成になっているので、instance の version をどうにかして特定する必要がある。特定できれば以下のように gcloud SDK を使ったコマンドを叩くと停止と開始を行うことができる。
gcloud app versions <stop|start> <version ID>
gcloud app versions start | Google Cloud CLI Documentation
問題は version ID で、これは
- ルールを決めて
- ルールに従って version を特定
する必要がある。方法はなんでもよいが、個人的には
gcloud app versions
の出力を見た瞬間に「これはawk向き」と判断、以下のような感じで抽出している。
gcloud app versions list --service <service> --sort-by '~last_deployed_time' --limit 1 | awk '
NR != 1 {
printf("%s", $2)
}
'
これは
- LAST_DEPLOYED の timestamp で降順に
- 1件のみ
にすることで最新の instance だけを抽出、
- printf() で改行なしの versiond ID だけに
これをリダイレクトでファイルに書き出し、
gcloud app versions stop $(cat <FILE>)
とすればその書き出したファイルの内容から version ID を埋めることができる。
定期実行
これは
- Cloud Build の手動トリガー
- これをスケジュール実行
の組み合わせでいける。
2 は普通に Cloud Scheduler なので、実態は
- gcloud app versions からどうにかして指定の version を取得する
- Cloud Build で gcloud を叩く設定を作る
- Cloud Scheduler でこれを定期実行する
の組み合わせで実行することになる。
Cloud Build で gcloud を叩くには
cloud-builders/gcloud at master · GoogleCloudPlatform/cloud-builders
によると以下のような感じになる。注意点は gcloud をそのまま呼ぶのではなく entrypoint を bash にしておかないとリダイレクトしたり bash の機能で version ID をファイルから読み取ったりできないところ。
steps:
- name: gcr.io/google.com/cloudsdktool/cloud-sdk
entrypoint: /bin/bash
args:
- -c
- 'gcloud app versions ... > version'
- name:
- name: gcr.io/google.com/cloudsdktool/cloud-sdk
entrypoint: /bin/bash
args:
- -c
- 'gcloud app versions stop $(cat version)'
みたいな感じだ。上の例で awk を使うようなコードは YAML の中に埋め込むのはやりにくそうなので、sh script にしておいて呼び出してもよい。