Cloud Run ジョブでCloud Storage FUSE機能を使ってみた
Cloud Storage FUSE機能とは
Cloud Runのコンテナで、Cloud Storageのバケットがストレージボリュームとして扱うことができるようになる機能です。
この機能を用いてバケットをマウントすると、バケット内のデータをコンテナ内のファイルとして扱うことができます。
例えば以下のようなバケットがあるとします。
test-bucket ├── sample1.txt ├── sample2.csv └── sample3.csv
上記バケットをCloud Storage FUSE機能でマウントしてコンテナを作成すると、コンテナ実行時は以下のような状態になります。
/ ├──test-bucket←マウントされてバケット内のデータがファイルとして存在している | ├── sample1.txt | ├── sample2.csv | └── sample3.csv ├── bin ├── boot ├── etc ├── home └── lib
注意点
- 2024/6/24時点ではプレビューとなっています
- マウントするバケットへのアクセス権限をCloud Run ジョブのサービスアカウントに付与されていること
- 何点か制限事項がある
料金
FUSE自体の料金は発生しませんが、Cloud Storageの料金は発生します。コンテナ内のディレクトリの一つとして扱うことができますが、リファレンスに以下の通りにあるように実態はCloud Storage APIになります。
Cloud Storage FUSE は、FUSE と Cloud Storage API を使用して、ファイル システムのローカルにマウントされたフォルダのようにバケットを透過的に公開します。
※引用:https://cloud.google.com/storage/docs/gcs-fuse?hl=ja#technical-overview
よって、例えばコンテナ内でファイル操作(解凍、圧縮)などを行うとコンテナにデータがAPIでコピーされてコンテナ内で処理され、またバケットへ戻すというような動きになりそれぞれのCloud StorgaeAPIの料金が発生します。
使い方
Cloud Run ジョブをデプロイするとき、または更新することでマウントすることができます。以下は既存のジョブを更新してマウントする、リファレンスのコマンド例です。
gcloud beta run jobs update JOB \ --add-volume name=VOLUME_NAME,type=cloud-storage,bucket=BUCKET_NAME \ --add-volume-mount volume=VOLUME_NAME,mount-path=MOUNT_PATH
--add-volume
と--add-volume-mount
を指定して、ボリュームのマウントを行います。ジョブのデプロイ時にマウントをするには同様に左記のフラグを用いることで可能となります。
gcloud run jobs deploy fuse-test \ --image "imageを指定" \ --add-volume name=VOLUME_NAME,type=cloud-storage,bucket=BUCKET_NAME \ --add-volume-mount volume=VOLUME_NAME,mount-path=MOUNT_PATH \ --region asia-northeast1 \
実際に使ってみる
事前準備
Cloud Shell上で実際にコンテナを作成して試してみました。
作成したファイルとしては以下となります。
- Dockerfile
- script.sh:検証用コード
- deploy.sh:デプロイコマンド
それぞれのファイルを以下に示します。
FROM google/cloud-sdk:latest COPY ./script.sh . RUN chmod +x ./script.sh CMD ["./script.sh"]
#!/bin/bash echo "---- ls start ----" ls echo "---- ls end ----" echo "---- ls gcs_bucket start ----" ls gcs_bucket echo "---- ls gcs_bucket end ----"
docker build -t fuse-test:latest . docker tag fuse-test asia-northeast1-docker.pkg.dev/プロジェクトID/リポジトリ名/fuse-test-image docker push asia-northeast1-docker.pkg.dev/プロジェクトID/リポジトリ名/fuse-test-image gcloud beta run jobs deploy fuse-test-job \ --image asia-northeast1-docker.pkg.dev/プロジェクトID/リポジトリ名/fuse-test-image \ --region=asia-northeast1 \ --tasks=1 \ --cpu=1 \ --max-retries=0 \ --memory=512Mi \ --parallelism=1 \ --task-timeout=600 \ --add-volume name=gcs_bucket,type=cloud-storage,bucket=バケット名 \ --add-volume-mount volume=gcs_bucket,mount-path=/gcs_bucket \ --region asia-northeast1 \
Cloud Storageバケットは作成されていることを前提としています。作成したバケット名をcloud-storage,bucket=
に指定します。
--add-volume-mount
で指定したマウントパスでバケットはマウントされます。
今回は事前に以下のようなCloud Storageバケットを用意しました。
test-bucket ├── test1.txt ├── test2.csv └── test3.csv
上記のファイルを作成したら、deploy.shを実行してジョブをデプロイします。実行コマンドは以下です。
sh deploy.sh
デプロイしたジョブは、実行するとscript.shを実行するというシンプルなものです。script.shは、マウントしたバケットをlsしてログに出力するので、
ログ内のデータにバケット内のファイル名が記載されていたら検証は成功です。
ちなみに、マウントに成功するとCloud Run ジョブのコンソール画面でジョブのボリューム
タブに、マウントしているCloud Storageの情報が表示されるようになります。
今回はgcs_bucket
という名前でバケットをマウントするように設定しました。
確認してみる
ジョブのデプロイができたら以下のコマンドでジョブを実行します。
gcloud run jobs execute fuse-test-job --region=asia-northeast1
実行できたら、ジョブのログの画面でログを確認します。
lsしたたくさんの結果の中に、gcs_bucket
がいました。確かにディレクトリとして扱われています。
続いて、gcs_bucket
内のデータがlsされているかも確認します。
ちゃんとバケットに保存したデータがlsされていました。確かにCloud Storageをマウントできているようです。
まとめ
簡潔ですが、Cloud Run ジョブでCloud Storage FUSE機能を使い、バケットをマウントしてみました。コンテナ内にバケットをマウントできることで、ファイルの解凍処理などをシェルスクリプト等で行う場合にCloud Storageからのコピー処理やアップロード処理を実装しなくて良いのは実装負担が楽になるなと思いました。
プレビューですが、早くGAになって欲しい機能です。
また、今回はマウントしてみただけですが、もう少し深掘りした記事を今後書いていこうと考えています。それではまた。