サービスのインメモリ ボリュームのマウントを構成する

このページでは、Cloud Run のボリューム マウントを使用したファイルの読み取りと書き込みで使用可能な専用のインメモリ ボリュームを構成する方法について説明します。この機能は、Cloud Run が提供する組み込みのインメモリ ファイル システムとは異なります。

Cloud Run でインメモリ ボリュームをマウントすると、インメモリ ボリュームがコンテナ ファイル システム内のファイルとして表示されます。インメモリ ボリュームをマウントしたら、プログラミング言語のファイル システム オペレーションとライブラリを使用して、ローカル ファイル システム上のディレクトリと同じようにアクセスします。

インメモリ ボリュームを使用すると、次のことができます。

  • インメモリ ボリュームのサイズを制限します。ボリュームのサイズを制限すると、ボリューム全体への書き込みが失敗します。これは、ボリュームが大量のメモリを消費したときに Cloud Run でインスタンスを終了するのではなく、この方法を使用することをおすすめします。
  • 1 つの Cloud Run インスタンスの異なるコンテナ間でインメモリ ボリュームを共有します。Cloud Run がサービスの複数のインスタンスにスケールアウトすると、各インスタンスには、そのインスタンス上のすべてのコンテナで共有される独自のインメモリ ボリュームが存在します。このボリュームは、Cloud Run がトラフィックを処理するためにスケールアウトするときに、すべてのコンテナで使用できます。

動作

インメモリ ボリュームを作成する場合は、サイズの上限を指定することをおすすめします。ボリュームがサイズの上限に達すると、それ以上の書き込みはメモリ不足エラーで失敗します。インスタンスは、このエラーを処理して実行を継続できます。

サイズの上限はあくまでも上限です。インメモリ ボリュームに追加容量を割り当てることはありません。インメモリ ボリュームは、コンテナ用に構成したメモリを消費します。複数のコンテナをデプロイした場合、ボリュームへの書き込みごとに使用されるメモリは、データを書き込んだコンテナのメモリ使用量としてカウントされます。

サイズの上限を指定しないと、ジョブまたはサービス内のすべてのコンテナの合計サイズの半分が上限として自動的に設定されます。たとえば、emptyDir ボリューム サイズ = [メモリ(コンテナ A) + メモリ(コンテナ B) + メモリ(コンテナ N)] ÷ 2 となります。このデフォルトの動作では、インメモリ ボリュームのサイズの上限が、一部のコンテナに割り当てられたメモリよりも大きくなる可能性があります。この状況で、コンテナがメモリの内容をボリュームに書き込み続けると、割り当てられたメモリを超え、ボリューム サイズの上限に達する前にクラッシュします。

サイズの上限の設定は任意ですが、コンテナのメモリ不足やクラッシュを防ぐため、設定することをおすすめします。

使用できないパス

Cloud Run では、/dev/proc/sys、またはそのサブディレクトリにボリュームをマウントすることはできません。

ボリュームの所有権は実行環境とデプロイタイプによって異なる

ボリュームをマウントする場合、ファイルとディレクトリを所有する ID は、ワークロードの実行環境や、デプロイが 1 つまたは複数のコンテナで構成されているかどうかによって異なります。

単一のコンテナをデプロイする第 1 世代の実行環境の場合、コンテナに使用されている ID がボリュームを所有します。それ以外の場合はすべて、root がボリュームを所有します。以下に例を示します。

  • 複数のコンテナをデプロイする第 1 世代の実行環境
  • 第 2 世代の環境

インメモリ ボリュームを構成する

構成を変更すると、新しいリビジョンが作成されます。明示的に更新しない限り、以降のリビジョンでも、この構成が自動的に設定されます。

Cloud Run サービスのインメモリ ボリュームを構成すると、起動した Cloud Run インスタンスごとに空のボリュームが作成されます。このボリュームは、そのインスタンスが実行されている間、存続します。インスタンスの実行が停止すると、ボリューム内のデータは完全に削除されます。

コンソール

  1. Google Cloud コンソールで、[Cloud Run] に移動します。

    Cloud Run に移動

  2. デプロイ先の新しいサービスを構成する場合は、[サービスを作成] をクリックします。既存のサービスを構成する場合は、サービスをクリックし、[新しいリビジョンの編集とデプロイ] をクリックします。

  3. 新しいサービスを構成する場合は、最初のサービス設定のページに入力してから、[コンテナ、ボリューム、ネットワーキング、セキュリティ] をクリックしてサービス構成ページを開きます。

  4. [ボリューム] タブをクリックします。

    イメージ

    • [ボリューム] で、次の操作を行います。
      • [ボリュームを追加] をクリックします。
      • [ボリュームのタイプ] プルダウンで、ボリューム タイプとして [インメモリ] を選択します。
      • [ボリューム名] フィールドに、ボリュームに使用する名前を入力します。
      • [完了] をクリックします。
    • [コンテナ] タブをクリックします。
    • [ボリュームのマウント] タブをクリックします。
      • [ボリュームをマウント] をクリックします。
      • メニューからインメモリ ボリュームを選択します。
      • ボリュームをマウントするパスを指定します。
      • [ボリュームをマウント] をクリックします。
  5. [作成] または [デプロイ] をクリックします。

gcloud

  • ボリュームを追加してマウントするには:

    gcloud beta run services update SERVICE \
    --add-volume=name=VOLUME_NAME,type=in-memory,size-limit=SIZE_LIMIT \
    --add-volume-mount=volume=VOLUME_NAME,mount-path=MOUNT_PATH

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

    • SERVICE: 実際のサービスの名前。
    • VOLUME_NAME は、ボリュームに付ける名前に置き換えます。VOLUME_NAME 値は、ボリュームをボリューム マウントにマッピングするために使用されます。
    • MOUNT_PATH は、このボリュームをマウントするコンテナ ファイル システム内の相対パス(/mnt/my-volume など)に置き換えます。
    • SIZE_LIMIT は、ボリュームに割り当てるメモリ上限を MiB または GiB 単位(Mi または Gi などで指定)に置き換えます(例: 500Mi)。この上限は、コンテナに指定された合計メモリより小さくする必要があります。
  • 複数のコンテナを使用している場合は、まずボリュームを指定してから、各コンテナのボリューム マウントを指定します。

    gcloud beta run services update SERVICE \
    --add-volume=name= VOLUME_NAME,type=in-memory,size-limit=SIZE_LIMIT \
    --container=CONTAINER_1 \
    --add-volume-mount=volume= VOLUME_NAME,mount-path=MOUNT_PATH \
    --container==CONTAINER_2 \
    --add-volume-mount=volume= VOLUME_NAME,mount-path=MOUNT_PATH2

YAML

  1. 新しいサービスを作成する場合は、この手順をスキップします。既存のサービスを更新する場合は、その YAML 構成をダウンロードします。

    gcloud run services describe SERVICE --format export > service.yaml
  2. 次に示すように、volumeMounts 属性と volumes 属性を構成します。

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
     annotations:
      run.googleapis.com/launch-stage: BETA
    spec:
      template:
        metadata:
        spec:
          containers:
          - image: IMAGE_URL
            volumeMounts:
            - mountPath: MOUNT_PATH
              name: VOLUME_NAME
          volumes:
          - name: VOLUME_NAME
            emptyDir:
              sizeLimit: SIZE_LIMIT
              medium: Memory

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

    • IMAGE_URL: コンテナ イメージへの参照(us-docker.pkg.dev/cloudrun/container/hello:latest など)。Artifact Registry を使用する場合は、リポジトリ REPO_NAME がすでに作成されている必要があります。URL の形式は LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG です。
    • VOLUME_NAME は、ボリュームに付ける名前に置き換えます。VOLUME_NAME 値は、ボリュームをボリューム マウントにマッピングするために使用されます。
    • MOUNT_PATH は、このボリュームをマウントするコンテナ ファイル システム内の相対パス(/mnt/my-volume など)に置き換えます。
    • SIZE_LIMIT は、ボリュームに割り当てるメモリ上限を MiB または GiB 単位(Mi または Gi などで指定)に置き換えます(例: 500Mi)。この上限は、コンテナに指定された合計メモリより小さくする必要があります。
  3. 次のコマンドを使用して、サービスを作成または更新します。

    gcloud run services replace service.yaml

ボリュームの読み取りと書き込み

Cloud Run のボリューム マウント機能を使用する場合、ローカル ファイル システムでファイルの読み取りと書き込みに使用するプログラミング言語のライブラリを使用して、マウントされたボリュームにアクセスします。

これは、ローカル ファイル システムにデータが保存されることを想定し、通常のファイル システム オペレーションを使用してデータにアクセスする既存のコンテナを使用している場合に特に便利です。

次のスニペットは、mountPath/mnt/my-volume に設定されたボリューム マウントを前提としています。

Node.js

ファイル システム モジュールを使用して、ボリューム /mnt/my-volume に新しいファイルを作成するか、既存のファイルに追加します。

var fs = require('fs');
fs.appendFileSync('/mnt/my-volume/sample-logfile.txt', 'Hello logs!', { flag: 'a+' });

Python

ボリューム /mnt/my-volume に保存されているファイルに書き込みます。

f = open("/mnt/my-volume/sample-logfile.txt", "a")

Go

os パッケージを使用して、ボリューム /mnt/my-volume に新しいファイルを作成します。

f, err := os.Create("/mnt/my-volume/sample-logfile.txt")

Java

Java.io.File クラスを使用して、ボリューム /mnt/my-volume にログファイルを作成します。

import java.io.File;
File f = new File("/mnt/my-volume/sample-logfile.txt");