⛰️
GCS FUSEでGitHubコードをCloud Runにマウントする方法
はじめに
この記事は、GCP(Google Cloud Platform) Advent Calendar 2024の4日目の記事です。
今回は Cloud Storage FUSE (以下、GCS FUSE) を使って、Cloud Run Job から Google Cloud Storage (GCS) 上に置かれた GitHub のソースコードを操作する方法を解説します。
筆者が実際のプロジェクトでソースコード解析の結果を BigQuery に書き出すワークフローを組んだ際、GitHub 上で管理しているコードをその都度コンテナに同梱せず、なるべく動的に参照したかったために利用した仕組みになります。
ソースコードは開発チームの更新のタイミングで常に変化する可能性があるため、変更のたびに Cloud Run のイメージをビルドしてデプロイし直すのは避けたい。そのような状況で便利なのが GCS FUSE です。
GCS FUSE とは
GCS FUSE は、Google Cloud Storage バケットをファイルシステムとしてマウントできるオープンソースのツールです。これにより、Cloud Run(第二世代ランタイム) や Compute Engine、GKE などの環境でも、まるでローカルディスクのように GCS 上のファイルにアクセスできます。
たとえば、アプリケーションが通常のファイル I/O API(open()
, read()
, write()
など)でファイルを扱うだけで、実際には裏側で GCS バケットとのやり取りが行われます。コードの修正がほぼ不要で GCS をマウントできるため、レガシーアプリケーションのクラウド移行の一助としてもよく使われます。
アーキテクチャ概要
具体的な構成イメージは下記のようになります。
GCS バケット
GitHub から取得したソースコードを保管する先(またはすでにソースコードが保管されている先)。
Cloud Run Job で読み書きする対象。
Cloud Run Job(第二世代ランタイム)
起動時に Docker イメージを Pull してコンテナを立ち上げ、GCS FUSE で GCS バケットを
/mnt/gcs
など任意のディレクトリにマウント。ジョブ用のエントリポイントスクリプト(
execute.sh
)を実行。スクリプトの中で GCS 上のソースコードを git pull する、またはクローンする。
最終的にアプリケーションロジック(
main.py
など)を実行して処理を行う。Secret Manager(SSH 秘密鍵の管理)
GitHub のプライベートリポジトリにアクセスするための SSH 鍵を安全に保管。
Cloud Run Job 実行時に API 経由で鍵を取得し、
.ssh/id_github
として設定。
この仕組みを使うことで、コンテナを再ビルドせずに、最新のソースコードにアクセスできます。ビルド時間の短縮や、デプロイの手間を軽減できるうえ、GitHub API の利用制限にも引っかかりにくいメリットがあります。
実装手順
ここからは、実際に Dockerfile とエントリポイントスクリプトをどのように書くかを説明します。
1. Dockerfile
以下は Python 3.11 ベースのイメージを利用した例です。gcsfuse
のインストールに加えて、必要に応じて google-cloud-sdk
もインストールしています。
FROM python:3.11-buster
# ========== 1. 必要なパッケージをインストール ==========
RUN -e; \
apt-get update -y && apt-get install -y \
tini \
lsb-release; \
gcsFuseRepo=gcsfuse-`lsb_release -c -s`; \
| \
/etc/apt/sources.list.d/gcsfuse.list; \
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
apt-key add -; \
apt-get update; \
apt-get install -y gcsfuse \
&& apt-get clean
# ========== 2. 環境変数や PATH の設定 ==========
ENV MNT_DIR /mnt/gcs
# Install google-cloud-sdk
RUN curl -sSL https://sdk.cloud.google.com | bash
ENV PATH $PATH:/root/google-cloud-sdk/bin
ENV APP_HOME /app
ENV ROOT /root
WORKDIR
# ========== 3. ソースコードのコピーと権限付与 ==========
COPY . ./
RUN +x /app/execute.sh
# ========== 4. ENTRYPOINT の指定 ==========
ENTRYPOINT [, ]
ポイント解説
tini コンテナ内でプロセスを安全に終了させるためのイニシエータです。Zombie プロセスの処理などが楽になります。
lsb-release
によるリポジトリ設定 Debian 系のディストリビューションでバージョンに応じたgcsfuse
のリポジトリをセットアップしています。google-cloud-sdk のインストール
gcloud secrets
コマンドなどを使う場合に必要です。Cloud Run にはデフォルトで入っていないので注意してください。
2. ジョブ用スクリプト (execute.sh
)
Cloud Run Job の開始時に呼び出されるスクリプトの例です。ここでは以下の操作を行います。
GCS のバケットをマウント
gcsfuse BUCKET /mnt/gcs
などのコマンドでマウントします。Secret Manager から SSH 鍵を取得して設定 GitHub プライベートリポジトリへのアクセスに必要な SSH 鍵を
.ssh/id_github
に配置します。GitHub リポジトリのクローン / 更新 すでにクローン済みなら
git pull
、なければgit clone
。メインの Python スクリプトを実行 例として
main.py
を実行します。
#!/usr/bin/env bash
set -eo pipefail
# ========== 1. GCS FUSE のマウント ==========
mkdir -p $MNT_DIR
echo "Mounting GCS Fuse."
gcsfuse --debug_gcs --debug_fuse $BUCKET $MNT_DIR
echo "Mounting completed."
# ========== 2. Secret Manager から SSH 鍵を取得 ==========
# set SSH key
mkdir -p ${ROOT}/.ssh
gcloud secrets versions access latest --secret=ID_GITHUB >> ${ROOT}/.ssh/id_github
chmod 400 ${ROOT}/.ssh/id_github
ssh-keyscan github.com >> ${ROOT}/.ssh/known_hosts
echo -e "Host github.com\n HostName github.com\n IdentityFile /.ssh/id_github\n User git\n StrictHostKeyChecking no" >> ${ROOT}/.ssh/config
chmod 700 ${ROOT}/.ssh
# ========== 3. GitHub リポジトリの更新またはクローン ==========
if [ -d "/" ]; then
cd ${MNT_DIR}/${REPO_NAME}
git pull origin main
else
git clone git@github.com:${ORG_NAME}/${REPO_NAME}.git
fi
# ========== 4. メインロジックの実行 ==========
python3 main.py
ポイントの解説
--debug_gcs
/--debug_fuse
デバッグ用のログが大量に出るため、本番運用では外してもかまいません。トラブルシューティング時に有用です。Secret Manager へのアクセス権限 事前に Cloud Run Job 用のサービスアカウントに対して
Secret Manager Secret Accessor
権限(roles/secretmanager.secretAccessor
)を付与しておく必要があります。GitHub SSH 設定
ssh-keyscan
やssh/config
により、ホストキーのチェックを自動化。StrictHostKeyChecking no
はセキュリティリスクになる場合があるので、CI/CD 用途などで割り切りが必要です。Pull or Clone の分岐 すでに同名ディレクトリがあれば
git pull
で最新化、なければgit clone
。
まとめ
以上、GCS FUSE を使って Cloud Run Job から GitHub 上のソースコードを取得・操作する方法を詳しく解説しました。
Dockerfile で
gcsfuse
をインストール。Cloud Run Job 起動時のスクリプトで GCS バケットをマウントし、Secret Manager から取得した SSH 鍵を利用して GitHub にアクセス。
ローカルファイルと同様の感覚で GCS 上のコードを取り扱う ことが可能。
特に「最新コードを常に参照しつつコンテナを再ビルドしたくない」「GitHub API の利用制限に対処したい」という場面では非常に有効です。一方で、パフォーマンスやセキュリティ、コスト面での配慮は欠かせません。必要に応じてローカルへの一時コピーやキャッシュを利用し、業務要件に見合った構成を検討してください。
もしパフォーマンス要件が厳しい場合は、GCS FUSE を最小限にとどめたり、Cloud Run Job で一旦バケットからソースをローカルへダウンロードしてから処理する方法も検討しましょう。
ぜひ、この記事を参考にして、可用性や保守性、セキュリティを確保しながら Cloud Run Job と GCS FUSE の連携を活用してみてください。
Read next
Loading recommendations...