Cloud Run Job はイメージが凍る。直したのに直らない理由
※本記事にはアフィリエイトリンクを含む場合があります。内容は広告の有無に影響されません。
結論
Cloud Run Job が使うイメージは job 定義側で固定されているため、ソースを直して commit しただけでは反映されず、イメージの tag を更新して apply するまで古いコードが実行され続ける。
まず確認する
job が実際に使っているイメージを取得します。
gcloud run jobs describe <job> --region=asia-northeast1 \
--format="value(spec.template.spec.template.spec.containers[0].image)"
修正コミットがそのイメージに含まれているかを確認します。
git merge-base --is-ancestor <修正commit> <イメージsha> && echo "含む" || echo "含まない"
「含まない」なら、何度実行しても結果は変わりません。むしろ古い挙動でデータを上書きし直すことがあります。
何が起きているか
job が使うイメージは job 定義側で固定されています。IaC で管理している場合は tag が変数として宣言されており、その tag を更新して apply するまで、job は昔のコードを実行し続けます。
ローカルで修正 → commit → 【ここに壁】 → job 実行
↑ イメージは古いまま
厄介なのは、実行そのものは成功することです。ログにもエラーは出ません。「実行したのに直らない」という状態だけが残ります。
直し方
A. 実行時の環境変数で上書きする
対象コードが process.env.X ?? 既定値 の形なら、イメージを変えずに実行時だけ差し替えられます。
gcloud run jobs execute <job> --region=asia-northeast1 \
--update-env-vars=KEY=value --wait
ビルドも apply も不要で速いのが利点です。ただし効くのはその実行だけで、job 定義は変わりません。次に付け忘れて実行すると、また古い既定値に戻ります。
B. イメージを更新する(根治)
ビルドして tag を上げ、IaC を apply します。手順は環境によりますが、「tag を上げる」を飛ばせないという一点が共通です。
再発防止
この事故のあと、実行前に必ず sha を確認する手順を runbook の冒頭に置きました。確認せずに実行できてしまうこと自体が原因なので、手順の順序を変えるのがいちばん効きます。
あわせて、環境変数での上書きは「その場しのぎである」と runbook に明記しました。速いぶん、根治したつもりになりやすいためです。
よくある質問
Q1実行しても直らないとき、まず何を見ればいいですか?
job が実際に使っているイメージの sha です。gcloud run jobs describe で取得し、修正コミットがそのイメージに含まれているかを git merge-base --is-ancestor で確認します。含まれていなければ、何度実行しても結果は変わりません。
Q2急いでいるときの回避策はありますか?
対象コードが環境変数から値を読む形になっていれば、実行時に --update-env-vars で上書きできます。ビルドも apply も不要ですが、効くのはその実行だけです。次に付け忘れると元の値に戻ります。
Q3なぜ Cloud Run Service では同じ問題が起きにくいのですか?
Service はデプロイのたびに新しいリビジョンを作るのが普通の運用なので、イメージの更新が手順に組み込まれています。Job は実行するだけで更新の手順を挟まないため、イメージが据え置かれていることに気づきにくいという違いです。