⛰️
GCS FUSEでGitHubコードをCloud Runにマウントする方法
公開
2024-12-04
更新
2025-02-26
文章量
約4798字
株式会社ヤードの代表で、Yardの開発者です。 データプロダクトの受託開発や技術顧問・アドバイザーもお受けしております。 #データ利活用 #DevOps #個人開発
はじめに
この記事は、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 の連携を活用してみてください。