Cloud Storage バケットの IAP を有効にする

このドキュメントでは、Cloud Run と Identity-Aware Proxy を使用して Cloud Storage から安全な静的コンテンツを配信する方法について説明します。

Cloud Run を使用すると、限定公開の Cloud Storage バケットから静的コンテンツを配信するウェブサーバーをホストできます。IAP を追加すると、Cloud Run サービスを保護し、不正なアクセスを防ぐことができます。また、コンテンツが変更されたときにコンテナ イメージを再構築する必要がなくなります。

Cloud Storage の静的ウェブサイト ホスティングは公開コンテンツのみを配信し、allUsers への読み取りアクセス権の付与が必要です。組織が公開アクセスの防止やドメインで制限された共有などのポリシーを使用して公開バケットを制限している場合、組み込みの Cloud Storage 静的ウェブサイト ホスティング機能は使用できません。代わりに、バケットを非公開にして、バケットをボリュームとしてマウントした Cloud Run に NGINX ウェブサーバーをデプロイし、IAP を使用して Cloud Run サービスへのアクセスを制御します。

始める前に

このドキュメントの手順を完了するには、次のものが必要です。

  • 課金が有効になっている Google Cloud プロジェクト。 Google Cloud コンソールに移動
  • 静的ファイル(index.html、CSS、画像など)を含む限定公開の Cloud Storage バケット。バケットが公開されていないことを確認します。
  • Google Cloud CLI がインストールされている。

Cloud Storage バケットへのアクセス権を付与する

Cloud Run には、非公開の Cloud Storage バケットからファイルを読み取る権限が必要です。Cloud Run サービス ID に、バケットに対する Storage オブジェクト閲覧者(roles/storage.objectViewer)ロールを付与する必要があります。

Cloud Run サービスには、デフォルトの Compute Engine サービス アカウントではなく、ユーザー管理のサービス アカウントを使用することをおすすめします。

  1. サービス ID として使用するサービス アカウントを作成します。

    gcloud iam service-accounts create RUN_SERVICE_ACCOUNT \
        --description="Service account for Cloud Run serving Cloud Storage" \
        --display-name="Cloud Run Cloud Storage Reader"
    
  2. バケットに対する Storage オブジェクト閲覧者(roles/storage.objectViewer)ロールをサービス アカウントに付与します。

    gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
        --member="serviceAccount:RUN_SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com" \
        --role="roles/storage.objectViewer"
    

Cloud Run サービスをデプロイする

NGINX ウェブサーバーを Cloud Run にデプロイし、Cloud Storage バケットをマウントします。ボリューム マウントをサポートするには、第 2 世代の実行環境を使用する必要があります。

バケットをマウントするには、ボリューム フラグを使用してサービスをデプロイします。

gcloud run deploy SERVICE_NAME \
    --image=nginx \
    --port=80 \
    --execution-environment=gen2 \
    --service-account=RUN_SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com \
    --add-volume=name=static,type=cloud-storage,bucket=BUCKET_NAME,readonly=true \
    --add-volume-mount=volume=static,mount-path=/usr/share/nginx/html \
    --no-allow-unauthenticated

次のように置き換えます。

  • SERVICE_NAME: Cloud Run サービスの名前
  • RUN_SERVICE_ACCOUNT: 前の手順で作成したサービス アカウント
  • PROJECT_ID: 実際の Google Cloud プロジェクト ID
  • BUCKET_NAME: Cloud Storage バケットの名前

バケットは /usr/share/nginx/html にマウントされます。これは、NGINX が静的アセットを検索するデフォルトのディレクトリです。つまり、バケット内のファイルはサービスのルートパスに直接マッピングされます。たとえば、gs://BUCKET_NAME/index.html に保存されているファイルは https://SERVICE_URL/index.html でアクセスできます。

デプロイを確認するには、サービスが認証されていないアクセスをブロックし、認証情報なしでアクセスされたときに 403 Forbidden ステータスを返すことを確認します。

curl -I SERVICE_URL

または、IAP アクセスを構成する前に、限定公開の Cloud Storage バケットからコンテナがファイルを正しくレンダリングしているかどうかをテストすることもできます。これを行うには、次のコマンドを実行して、デベロッパー認証情報を使用して認証済みリクエストを送信します。

curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" SERVICE_URL

SERVICE_URL は、Cloud Run サービスの URL に置き換えます。

IAP を有効にする

Cloud Run サービスをデプロイしたら、IAP を有効にして保護できます。

Cloud Run サービスで IAP を直接有効にすることをおすすめします。手順については、Cloud Run 用 IAP を構成するをご覧ください。

または、Cloud Run サービスの前で外部 HTTPS ロードバランサを使用している場合は、バックエンド サービスで IAP を有効にできます。手順については、バックエンド サービスまたはロードバランサから IAP を有効にするをご覧ください。

キャッシュとパフォーマンス

Cloud Storage ボリューム マウントを使用すると、Cloud Run によって読み取られる各ファイルは Cloud Storage API 呼び出しに変換されます。レイテンシと API 費用を最小限に抑えるには、ウェブサーバーでキャッシュ保存を構成するか(NGINX キャッシュ保存ディレクティブを使用するなど)、Cloud Storage FUSE マウント オプションを構成します。

外部 HTTPS ロードバランサを使用する場合は、バックエンド サービスで Cloud CDN を有効にすることもできます。IAP には同じバックエンド サービス上の Cloud CDN との互換性がないため、両方が必要な場合は、それに応じてアーキテクチャを構築する必要があります。

制限事項

Cloud Storage ボリューム マウントからファイルを読み取る速度は、ローカル ファイル システムにアクセスするよりも遅くなる可能性があります。読み取りレイテンシを軽減するには、キャッシュ保存を構成します。

その他のユースケース

Cloud Storage ボリューム マウントは、他のシナリオでも使用できます。

  • イベント ドリブン関数: 関数は、アップロードされたファイルをファイル システムから直接読み取ります。
  • 生成 AI アプリケーション: アプリケーションは、標準のファイル システム読み取りを使用して、Cloud Storage バケットからベクトル データベース(Chroma など)を読み込みます。

代替方法: NFS ボリュームをマウントする

ファイルが Filestore またはセルフホスト NFS サーバーに保存されている場合は、Cloud Storage バケットではなく、NFS ボリュームを Cloud Run サービスにマウントできます。詳細については、NFS ボリュームのマウントをご覧ください。