App Engineのインスタンスを定期的に再起動する

App Engineの自動再起動には超えるべきステップが二つある

  1. Google App Engine は Compute Engine のように素朴な VM ではないので OS 内部から再起動することはできない
    • App Engine の instance は service, version で特定しないといけない
  2. App Engineには機能がないのでスケジュールは外部から与える必要がある

VM インスタンスの起動と停止をスケジュールする  |  Compute Engine ドキュメント  |  Google Cloud Compute Engine にはインスタンススケジュールがある

instanceの特定

App Engine の概要  |  App Engine ドキュメント  |  Google Cloud

App Engine は以下のように

  • service
    • version
      • instance

という構成になっているので、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 を埋めることができる。

定期実行

これは

  1. Cloud Build の手動トリガー
  2. これをスケジュール実行

の組み合わせでいける。

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 にしておいて呼び出してもよい。

More