Cloud Run で Firestore への書き込みがうまくいかなかった話について調べてみた
背景
- GCSのバケットに対するファイル更新をトリガーにfilestoreへそのファイルを保存したかった。
- 簡単にトリガーを設定できるCloud run functionsを利用したかった。
- filestoreへの書き込みは下記の制約があり、permisson deniedエラーによって失敗していたことが調べていてわかった。
試したこと
- サービスアカウントの問題?
- Cloud Run functionsを実行するサービスアカウントにfilestoreへの管理者権限付けたが、変わらず権限エラーが発生
- やはりベースイメージにroot権限がない?
https://cloud.google.com/run/docs/configuring/services/runtime-base-images?hl=ja
→ 調べてみた。
調べてみた結果
1. Cloud runのドキュメントに実行ユーザーの記載があるか確認
コンテナランタイムの契約
→ 特に記載なし
実際に、実行ユーザを見てみる。
def get_os_info(request):
"""
OS レベルの情報を取得する。
Returns:
OS 情報を含む文字列。
"""
try:
# UID と GID を取得
uid = os.getuid()
gid = os.getgid()
# id コマンドを実行
id_output = subprocess.check_output(["id"], text=True, stderr=subprocess.STDOUT)
# root 権限のチェック
is_root = os.geteuid() == 0
result = (
f"UID: {uid}\n"
f"GID: {gid}\n"
f"id command output:\n{id_output}\n"
f"Is root (unreliable): {is_root}\n"
)
return result
except Exception as e:
return f"Error: {e}"
実行結果
UID: 33
GID: 33
id command output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Is root (unreliable): False
→ やはり、最小権限原則からもroot権限で実行されていない。
2. Cloud Build (Cloud Run のビルドに使うやつ) のデフォルト ユーザー
Cloud BuildでCloud Run で使うコンテナイメージをビルドするのに使うやつ。Cloud Build のデフォルトの動きに関するドキュメントには、こう書いてある。
- デフォルトのサービスアカウント: 特に何も指定しないと、Cloud Build はデフォルトのサービスアカウントを使ってビルドする。
→ 可能性は低いが、このアカウントにfilestoreの書き込み権限がないから、コンテナも影響している?
→ build用のサービスアカウントに権限を付与しても相変わらず権限エラーで書き込み失敗。
まとめ
調査結果ではCloud Run Functions で自動的にビルドされるコンテナは、デフォルトで root 権限がないユーザー で動いており、ユーザ側でroot権限をもつイメージでビルドするように指定する方法は見つからなかった。
※ほかの方法をご存じの方がいらっしゃいましたら、是非コメントご教示いただけますと幸いです。
Filestore への書き込みを実現するには
cloud run functionsでなく、カスタムイメージを通じてCloud Runをデプロイする必要がある。
詳細は下記をご覧ください。
GCS バケット更新をトリガーに Filestore へ書き込む Cloud Run 構築 (Terraform)