Flask APIをGoogle Cloud Runへデプロイする
What is this?
「Slack slashコマンドから、Google Reminderを設定する」の後編です。前編ではFlaskを用いたAPI開発を行いました。後編では、開発したAPIをコンテナごとGoogle Cloud Runへデプロイします。
Google Cloud Runとは
公式ページからの引用によると、
Cloud Run は、マシンのプロビジョニング、クラスタの構成、自動スケーリングについて心配することなく、サーバーレス HTTP コンテナをデプロイしてスケールするためのフルマネージド コンピューティング環境です。
つまり、「コンテナごとアプリケーションを乗っけると、フルマネージドなサーバーレスサービスの上で動かしてくれる」「コンテナごとデプロイするので、Cloud Functions等と比べて言語・ランタイムの制約が少ない」と理解しています。
実行環境
- HP Elite c1030 Chromebook
- Debian 10.11
準備
Cloud SDKのインストール
$ sudo gcloud components update
上記を実行すると、下記のように怒られるので言われるがままに従います。
ERROR: (gcloud.components.update)
You cannot perform this action because the Google Cloud CLI component manager
is disabled for this installation. You can run the following command
to achieve the same result for this installation:
sudo apt-get update && sudo apt-get --only-upgrade install google-cloud-sdk-datalab google-cloud-sdk-kpt google-cloud-sdk-app-engine-java google-cloud-sdk-nomos google-cloud-sdk-cbt google-cloud-sdk-app-engine-python google-cloud-sdk-pubsub-emulator google-cloud-sdk-firestore-emulator google-cloud-sdk-gke-gcloud-auth-plugin kubectl google-cloud-sdk-datastore-emulator google-cloud-sdk-app-engine-grpc google-cloud-sdk google-cloud-sdk-local-extract google-cloud-sdk-skaffold google-cloud-sdk-cloud-build-local google-cloud-sdk-app-engine-go google-cloud-sdk-bigtable-emulator google-cloud-sdk-terraform-validator google-cloud-sdk-config-connector google-cloud-sdk-kubectl-oidc google-cloud-sdk-app-engine-python-extras google-cloud-sdk-minikube google-cloud-sdk-cloud-run-proxy google-cloud-sdk-spanner-emulator google-cloud-sdk-anthos-auth
GCP上での準備
- プロジェクト作成
- 各種APIの有効化(Cloud Build・Cloud Run)
デフォルトのプロジェクトとリージョンの設定
2022/03/05現在ではus-central1
以外のリージョンでも使用できそうですが、特に変える理由もないのでそのまま設定しています。
projectname
は準備したプロジェクト名称に合わせてください。
$ gcloud config set project projectname
$ gcloud config set run/region us-central1
Googleアカウントの認証
$ gcloud auth login
上記を実行すると、ブラウザが立ち上げるので、アカウントを認証します。
コンテナのビルド
まずはローカルでビルドと実行を確認
前編で開発したコンテナをまずはローカルでビルドします。
imagename
は好きな名称に書き換えてください。
$ docker build -t imagename
ビルドが完了したら、ローカルで実行してみます。
ここで、Cloud Runのデフォルトポートは8080
であるため、明示的に環境変数で指定します。[1]
$ PORT=8080 && docker run -it imagename
Cloud Buildでのコンテナビルド
Cloud Runにて参照するために、同じくGCP上のCloud Buildにてコンテナをビルドします。
$ gcloud builds submit --project projectname --tag gcr.io/projectname/applicationname
applicationname
は自由に設定できます。
ビルドは数分間かかり、最後にDONE
と表示されれば完了です。
原因不明のビルドエラー
理由は全くわからないのですが、作業をしている中で、下記のようなエラーに出会いました。
build step 0 "gcr.io/cloud-builders/docker" failed: step exited with non-zero status: 1
調べても、直接的な原因はわからず。色々試している中で、コマンドを実行しているディレクトリに.git
が含まれていると、このエラーが発生することだけがわかりました。
.dockerignoreで除外指定をしても効果はありませんでした。
Cloud Runへのデプロイ
上記でビルドしたコンテナをCloud Runへデプロイします。
$ gcloud run deploy applicationname --project projectname --platform managed --source .
以前は、Cloud Run用の設定ファイルを用意する必要が合ったようなのですが、--source .
を追加することで、そのあたりの設定を良しなに完了してくれるようです。
エラー処理
デプロイになにか異常があったときに、下記のようなエラーがでます。
Deployment failed
ERROR: (gcloud.beta.run.deploy) Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more information.
「ポートが空いていないから、コンテナを起動できないよ」とエラー文では言っているのですが、どうやらコンテナ内でどのようなエラーが起こっても、このエラー文が返る仕様になっているようです。
エラーの詳細は、Cloud Runのログを見に行くと、Warning以外の項目にしれっとでていたりします。ただ、毎回確認するのも面倒なので、まずはローカルでしっかり起動できることを確認するのをおすすめします。
ちなみに、上記エラー分を信じて環境変数などを色々いじっている中で、下記エラー文への変化はありましが、根本的解決にはなりませんでした。
Deployment failed
ERROR: (gcloud.beta.run.deploy) Deploying Revision.
最後に、Slashコマンドとの結合
デプロイしたAPIサーバーのURLを確認
無事にデプロイが完了したら、APIサーバーのURLを確認します。
Cloud Runのコンソールから確認できます。
Slackアプリの設定
Slashコマンドの設定に、上記のURL+APIのメソッドを指定します。今回はgoremind
というメソッドになるため、[URL]/goremind
をRequest URLへ設定します。
以上で、一連のAPI開発とCloud Runへのデプロイとなります!Cloud Runは始めて使用しましたが、サーバーレスの手軽さとコンテナ開発での自由さが両立できて良い感じですね。
参考文献
-
コード内で環境変数を読み取っています。 ↩︎
Discussion