EmotionTechテックブログ

株式会社エモーションテックのProduct Teamのメンバーが、日々の取り組みや技術的なことを発信していくブログです。

Cloud Runのコンテナインスタンスはいつまで起動するのか試してみた

はじめに

こんにちは、エモーションテック SREのおかざきです。 今回は弊社プロダクトで利用しているGoogle CloudのCloud Runについて、実際に動かしてみた中で生じた疑問点を検証してみました。

疑問点

  • リクエスタイムアウトを超えた処理はどうなるのか
  • デプロイ時に旧リビジョンで稼働していた処理はどうなるのか

リクエスタイムアウトを超えた処理はどうなるのか

Cloud Runのドキュメントには以下のように記述されています。

Setting request timeout (services)  |  Cloud Run Documentation  |  Google Cloud

If a response isn't returned within the time specified, the request ends and an error 504 is returned. Note that the container instance that served the request is not terminated.

timeoutを超えた時点でクライアントには504レスポンスが返却されるようですが、コンテナインスタンスは停止されないようです。 では、コンテナインスタンスで行われていた処理はどうなるのでしょうか。

簡単ですが以下の構成で検証してみました。

  • Cloud Run
    • Node.js + Expressによる簡単なWebサーバを作り、リクエストを受信すると任意の時間sleepしてレスポンスを返す
    • Sidecarとしてシェルスクリプトを実行し、1秒ごとに標準出力に「起動中のリビジョン名と起動からの経過秒数」を出力させる
    • SidecarにてSIGTERMをトラップし、標準出力でSIGTERMを受信した旨を出力させる(こちらのドキュメントよりSidecar含むコンテナインスタンス終了時にはSIGTERMが送信される)
設定項目 設定値
Cloud Run世代 第一世代
リージョン asia-northeast1
Cloud Run timeout (timeoutSeconds) 30sec
maxScale 1
minScale パターンによって変化させる
Webサーバーがレスポンス返却するまでのsleep時間 60sec
Always on CPU 有効化
(有効/無効でtimeout時の挙動に変化は見られなかった)

minScale = 0、minScale = 1の場合の2パターン検証しました。

minScale = 0の場合

クライアントから接続後に30sec後に504が返却されましたが、その後もコンテナインスタンスのログは出力され続け、1分後にExpressよりレスポンスを処理した旨のログが出力されました。 冒頭で参照したドキュメントの通り、504返却後もコンテナインスタンスは停止されないようです。 そして、レスポンス返却後の15分後にSIGTERMが発生し、コンテナインスタンスが停止されました。

15分後というのは以下のドキュメントの記述に対応しているようです。

CPU allocation (services)  |  Cloud Run Documentation  |  Google Cloud

An instance will never stay idle for more than 15 minutes after processing a request

minScale = 1の場合

クライアントから接続後に30sec後に504が返却されましたが、その後もコンテナインスタンスのログは出力され続け、1分後にExpressよりレスポンスを処理した旨のログが出力されました。 その後コンテナは長時間起動したままとなりました。 今回試したところ、SIGTERMが検知されたのは起動から13000〜14000 sec経過後でした。

minScaleの数を満たすためのコンテナインスタンスについてはレスポンス返却後もしばらく起動したままになるようです。 ただ、timeout時間を超えて同じコンテナインスタンスが起動して処理が走り続ける時間については、以下のドキュメントにあるように保証されていないものと推測されます。 Container runtime contract  |  Cloud Run Documentation  |  Google Cloud

For Cloud Run services, an idle instance can be shut down at any time, including instances kept warm via a minimum number of instances.

なお、Cloud Runのtimeoutの上限(2024/1時点では3600sec)を超えて長時間の処理を行いたい場合は2023/9にCloud Run Jobsの長時間処理がGAになっているので、そちらを利用するのが良さそうです。 また、Cloud Runではtimeout経過後も条件によってはSidecarやバックグランドの処理が継続されますが、Cloud Run Jobsではtimeoutに到達した時点でジョブが失敗と判定され、コンテナインスタンスが停止されるようです。指定したtimeoutで確実に処理を止めたい場合もCloud Run Jobsを選択するのが良さそうです。

デプロイ時に旧リビジョンで稼働していた処理はどうなるのか

以下の条件で検証してみました。

設定項目 設定値
Cloud Run世代 第一世代
リージョン asia-northeast1
Cloud Run timeout (timeoutSeconds) パターンによって変化させる
maxScale 1
minScale 1
Webサーバーがレスポンス返却するまでのsleep時間 パターンによって変化させる
Always on CPU 有効
(有効/無効でtimeout時の挙動に変化は見られなかった)
デプロイ時のトラフィック切替割合 即時100%にする。

いくつかパラメータを変更して試した結果は以下の通りでした。

パターン Cloud Run timeout sleep時間 結果
パターン1 1200sec 600sec デプロイ前のリビジョンのExpressにてレスポンス処理完了のログが出力された
レスポンス返却直後にすぐに古いリビジョンのコンテナインスタンスに対してSIGTERMが送られた
パターン2 3600sec 3599sec デプロイ前のリビジョンのExpressにてレスポンス処理完了のログが出力された
レスポンス返却直後にすぐに古いリビジョンのコンテナインスタンスに対してSIGTERMが送られた
パターン3 3600sec 10800sec 3600sec後に504が返却された
同時に古いリビジョンのコンテナインスタンスにSIGTERMが送られた
パターン4 30sec 60sec 30sec後に504が返される。この時点ではSIGTERMが発生せず、60sec経過後にデプロイ前のリビジョンのExpressにてレスポンス処理完了のログが出力された
504発生から約1分半後にコンテナインスタンスにSIGTERMが送られた

timeout に収まる範囲内では古いリビジョンで処理が継続され、レスポンス処理が終わったタイミングで古いリビジョンのコンテナインスタンスは停止されました。 timeoutを超えるような処理の場合は、レスポンス処理が継続中であっても古いリビジョンのコンテナインスタンスは停止されました。

基本的にはtimeoutに収まる範囲であれば、デプロイによってリクエスト処理中のコンテナインスタンスが急に停止されることはなく、ユーザーには配慮されているようです。

おわりに

いかがでしたでしょうか。記事に示した製品の挙動は、ドキュメントを読むことである程度把握できると思います。しかし、実際にいくつかのケースを想定し、他製品と比べながら動作検証を行うことで、知識として定着することもあるかと思います。

個人的にはCloud RunのベースはKnativeとのことなので、(Cloud Runが全くKnativeと同一であるとは言えないですが) 今回調べた挙動についてより追求するならば、Knativeにも興味が湧いてきました。

日々の開発、運用に追われつつもこのような検証は少しずつ行なっていきたいと思います。

エモーションテックでは顧客体験・従業員体験の改善をサポートし世の中の体験を変えるプロダクトを開発しております。もし弊社に興味を持って頂けましたら、ぜひ採用ページからご応募をお願いいたします。

hrmos.co