Cloud Runサービスで「Failed to start and then listen on the port」が出たら、portの数字だけを変更せず、失敗したrevisionの起動ログを確認します。アプリがlistenする前に例外で終了した場合も、PORTやbind先が違う場合も、入口では似たエラーとして見えることがあります。
この記事はHTTP要求を受けるCloud Runサービスのingress containerを扱います。Jobsやworker poolsへ同じlisten要件を適用しません。以下は架空の診断表で、Cloud Runへの接続、image build、container実行、deploy、probe変更は行っていません。
目次
対象revisionと失敗段階を固定する
Cloud Runのservice、project、region、失敗revision、image識別、作成時刻を対応付けます。稼働中の旧revisionと、新しくreadyになれなかったrevisionのログを混ぜないようにします。tagが同じでも、意図したimageの内容が同じとは限りません。
表は横にスクロールできます
| 観測した状態 | 最初に確認するもの | 別問題として扱うもの |
|---|---|---|
| image取得前に失敗 | image参照・取得権限 | appのlisten設定 |
| processがすぐ終了 | 起動直後の例外・exit | port変更だけの対応 |
| processは動くがlistenしない | entrypoint・初期化・bind | HTTP要求の処理timeout |
| ready後に応答が失敗 | 要求ログ・業務依存 | 起動時のport不一致 |
GoogleのCloud Run troubleshooting(新しいタブで開く)は、まずcontainer imageをローカルでも実行できるか確かめる流れを示しています。試験する場合は実サービスへの副作用やsecretの扱いを管理した検証環境を使い、ローカル成功をCloud Runでも成功した証拠にはしません。
listenより前のprocess終了を調べる
revisionの起動時刻付近のstdout/stderrで、module不在、起動commandの誤り、設定不足、依存サービス接続失敗などを確認します。これは原因候補の例で、portエラーから特定の一つを断定するものではありません。
entrypointやcommandの上書きが、imageの既定動作と一致しているかを見ます。HTTP サーバーではなく一回限りの処理を実行して終了する設定なら、portを合わせてもlistenは始まりません。起動時に重いdownloadやmigrationを行う場合は、どこで止まったかをログの段階で区別します。
imageの実行形式も確認します。container runtime contract(新しいタブで開く)はLinux x86_64 ABIやmulti-architecture imageのlinux/amd64を説明しています。開発端末で動いた別architectureのimageを、そのまま同条件と考えないようにします。
PORTとbind先を組み合わせて照合する
公式contractでは、ingress containerは要求先portで0.0.0.0へlistenし、127.0.0.1へ限定しないよう定めています。Cloud Runはingress containerへPORT環境変数を注入します。既定portだけを暗記するより、対象revisionに設定されたcontainer portと、processが実際に使う値を照合します。
表は横にスクロールできます
| 設定の架空例 | processの状態 | 確認する差分 |
|---|---|---|
| PORT=8080 | 0.0.0.0:8080へlisten | port・bindの基本条件は合う |
| PORT=8080 | 127.0.0.1:8080だけ | bind先の限定 |
| PORT=8080 | 0.0.0.0:3000へlisten | portの読込・固定値 |
| PORT=8080 | listen前にprocess終了 | port以外の起動失敗 |
表は成功保証ではありません。DockerfileのEXPOSEなどの宣言と、processがsocketを開くことも別です。frameworkのhost/port設定、環境変数の読込時点、起動引数を確認します。multi-container構成では、どれがingressで、どれがsidecarかも分けます。
startup probeと要求timeoutを混同しない
Cloud Runのhealth check資料(新しいタブで開く)はstartup、liveness、readinessの役割を分けています。起動準備が終わったかを確認するprobeと、起動後の一件のHTTP要求に許す時間は別です。要求timeoutを延ばせば起動失敗も直る、とは扱いません。
表は横にスクロールできます
| probeの確認 | 確認する事実 | 不適切な成功判定 |
|---|---|---|
| TCP | 対象portで接続を受けるか | 必要な業務処理まで保証 |
| HTTP | 設定pathと応答条件が一致するか | 別pathの200だけで判断 |
| gRPC | 対応health checkを実装しているか | HTTP用設定をそのまま流用 |
| 起動が遅い | 初期化の進行と必要時間 | 例外終了を待機延長で隠す |
遅いだけなのか、永久に待つ・失敗するのかを区別してからprobe設定を検討します。health endpointには秘密や内部状態を過剰に返さず、意味のある準備状態を返す設計にします。probeだけ無条件成功へ変えて、準備前のアプリへtrafficを流す方法にはしません。
修正後は起動と応答を別々に確認する
変更候補は一つずつにし、image、entrypoint、PORT、bind、probeのどれを変えたか記録します。新revisionがreadyになったこと、そのrevisionへ意図した要求が届いたこと、必要最小限の応答が返ることを分けて確認します。旧revisionの成功応答を、新revisionの検証結果へ流用しません。
うまくいかなければ、変更前のimageと設定へ戻すための識別を保ちます。本番traffic変更を診断の最初の手順にせず、検証用の経路と運用の復旧手順を決めてから実施します。実施していない経路は未確認として残します。
