Cloud Storage FUSE CSI ドライバを使用して Cloud Storage バケットにアクセスする


Filesystem in Userspace(FUSE)は、ファイル システムを Linux カーネルにエクスポートするために使用されるインターフェースです。Cloud Storage FUSE を使用すると、Cloud Storage バケットをファイル システムとしてマウントできます。これにより、アプリケーションは、クラウド固有の API を使用せずに、一般的なファイル IO オペレーション(オープン、読み取り、書き込みなど)を使用してバケット内のオブジェクトにアクセスできます。

Cloud Storage FUSE の CSI ドライバを使用すると、Kubernetes API を使用して既存の Cloud Storage バケットをボリュームとして使用できます。アプリケーションでは、Cloud Storage FUSE ファイル システム セマンティクスを使用して、オブジェクトのアップロードとダウンロードを行うことができます。Cloud Storage FUSE の CSI ドライバは、オープンソースの Google Cloud Storage FUSE の CSI ドライバを利用したフルマネージドのエクスペリエンスを提供します。

ドライバは、Cloud Storage を使用するボリュームを構成するために、次の方法をネイティブにサポートしています。

Cloud Storage FUSE CSI ドライバとファイル キャッシュを併用することで、Cloud Storage バケットの小さなファイルを扱うアプリケーションの読み取りパフォーマンスを改善できます。Cloud Storage FUSE ファイル キャッシュ機能は、クライアント ベースの読み取りキャッシュで、これにより、選択したキャッシュ ストレージから繰り返し行うファイルの読み取りを、より短時間で行えるようにします。読み取りキャッシュは、ローカル SSD や Persistent Disk ベースのストレージなどのさまざまなストレージ オプションから、価格とパフォーマンスのニーズに基づいて選択できます。Cloud Storage FUSE CSI ドライバでファイル キャッシュを有効にするには、オプトインする必要があります。キャッシュのベスト プラクティスの詳細については、Cloud Storage FUSE のパフォーマンスとベスト プラクティスをご覧ください。

利点

  • クラスタの Cloud Storage FUSE の CSI ドライバにより、ドライバの自動デプロイと管理が有効になります。ドライバは、Standard と Autopilot の両方のクラスタで機能します。
  • Cloud Storage FUSE の CSI ドライバには、FUSE のクライアントで通常必要となる特権アクセスは必要ありません。これにより、セキュリティ対策が改善されます。
  • CSI エフェメラル ボリュームのサポートにより、PersistentVolumeClaim オブジェクトと PersistentVolume オブジェクトが不要になり、ボリュームの構成と管理が簡素化されます。
  • Cloud Storage FUSE の CSI ドライバは、ReadWriteManyReadOnlyManyReadWriteOnceアクセスモードをサポートしています。
  • GKE 用 Workload Identity 連携を使用すると、Pod が Cloud Storage オブジェクトにアクセスする方法を詳細に制御しながら、認証を管理できます。Workload Identity 連携を使用する場合、読み書きワークロードには均一なバケットレベルのアクセスが必要です。
  • Ray、PyTorch、Spark、TensorFlow などのフレームワークを使用して、ML トレーニングを実行し、ワークロードを提供している場合、Cloud Storage FUSE CSI ドライバによるポータビリティとシンプルさにより、追加のコード変更をすることなく、ワークロードを GKE クラスタで直接実行できます。
  • ファイル キャッシュを有効にして Cloud Storage オブジェクトを読み取ると、読み取りパフォーマンスを向上させることができます。ファイル キャッシュの利点については、Cloud Storage FUSE のドキュメントをご覧ください。
  • Cloud Storage FUSE ボリュームを init コンテナで使用できます。

始める前に

始める前に、次の作業が完了していることを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得する。
  • Cloud Storage バケットを作成します。パフォーマンスを改善するには、Location type フィールドを Region に設定し、GKE クラスタが実行されているリージョンを選択します。

制限事項

  • Cloud Storage FUSE ファイル システムでは、POSIX ファイル システムと比較して、パフォーマンス、可用性、アクセス承認、セマンティクスが異なります。
  • Cloud Storage FUSE の CSI ドライバは、GKE Sandbox ではサポートされていません。
  • Cloud Storage FUSE の CSI ドライバは、ボリューム スナップショット、ボリュームのクローン作成、ボリュームの拡張をサポートしていません。
  • Cloud Storage FUSE の CSI ドライバの GitHub プロジェクトで既知の問題をご覧ください。
  • Cloud Storage FUSE の CSI ドライバの GitHub プロジェクトで未解決の問題をご覧ください。現在、問題の優先度を判断しており、今後のアップデートで解決する予定です。

要件

Cloud Storage FUSE の CSI ドライバを使用するには、クラスタが次の要件を満たしている必要があります。

Cloud Storage FUSE の CSI ドライバを有効にする

Cloud Storage FUSE の CSI ドライバが有効な Standard クラスタを作成するには、gcloud CLI を使用します。

gcloud container clusters create CLUSTER_NAME \
    --addons GcsFuseCsiDriver \
    --cluster-version=VERSION \
    --location=LOCATION \
    --workload-pool=PROJECT_ID.svc.id.goog

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

  • CLUSTER_NAME: クラスタの名前。
  • VERSION: GKE のバージョン番号。 1.24 以降を選択する必要があります。
  • LOCATION: クラスタの Compute Engine のロケーション
  • PROJECT_ID: プロジェクト ID。

既存の Standard クラスタでドライバを有効にするには、gcloud container clusters update コマンドを使用します。

gcloud container clusters update CLUSTER_NAME \
    --update-addons GcsFuseCsiDriver=ENABLED \
    --location=LOCATION

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

Cloud Storage FUSE CSI ドライバを有効にした後は、ドライバとプロビジョナーの名前(gcsfuse.csi.storage.gke.io)を指定して Kubernetes ボリュームでドライバを使用できます。

GKE 用 Workload Identity 連携を使用して Cloud Storage バケットへのアクセスを構成する

GKE 用の Workload Identity 連携を使用して、GKE クラスタから Cloud Storage バケットにアクセスできるようにするには、次の操作を行います。詳細については、GKE 用 Workload Identity 連携を使用するようにアプリケーションを構成するをご覧ください。

  1. クラスタの認証情報を取得します。

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=LOCATION
    

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

  2. Kubernetes ServiceAccount に使用する Namespace を作成します。default Namespace を使用することも、既存の Namespace を使用することもできます。

    kubectl create namespace NAMESPACE
    

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

    • NAMESPACE: Kubernetes ServiceAccount の Kubernetes Namespace の名前。
  3. アプリケーションで使用する Kubernetes ServiceAccount を作成します。また、default Kubernetes ServiceAccount を含む任意の Namespace で既存の Kubernetes ServiceAccount を使用することもできます。

    kubectl create serviceaccount KSA_NAME \
        --namespace NAMESPACE
    

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

    • KSA_NAME: 新しい Kubernetes ServiceAccount の名前。
    • NAMESPACE: Kubernetes ServiceAccount の Kubernetes Namespace の名前。
  4. Cloud Storage の IAM ロールのいずれかを Kubernetes ServiceAccount に付与します。

    次のコマンドを使用して、特定の Cloud Storage バケットにアクセスするためだけのロールを Kubernetes ServiceAccount に付与できます。

    gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
        --member "principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME" \
        --role "ROLE_NAME"
    

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

    • BUCKET_NAME: Cloud Storage バケット名。
    • PROJECT_NUMBER: GKE クラスタの数値のプロジェクト番号。プロジェクト番号を確認するには、プロジェクトの識別をご覧ください。
    • PROJECT_ID: GKE クラスタのプロジェクト ID。
    • NAMESPACE: Kubernetes ServiceAccount の Kubernetes Namespace の名前。
    • KSA_NAME: 新しい Kubernetes ServiceAccount の名前。
    • ROLE_NAME: Kubernetes ServiceAccount に割り当てる IAM ロール。
      • 読み取り専用ワークロードの場合は、ストレージ オブジェクト閲覧者ロール(roles/storage.objectViewer)を使用します。
      • 読み取り / 書き込みワークロードの場合は、Storage Object ユーザーロールを使用します(roles/storage.objectUser)。

    必要に応じて、次のコマンドを使用して Kubernetes ServiceAccount にロールを付与し、プロジェクト内のすべての Cloud Storage バケットにアクセスできるようにします。

    gcloud projects add-iam-policy-binding GCS_PROJECT \
        --member "principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME" \
        --role "ROLE_NAME"
    

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

    • GCS_PROJECT: Cloud Storage バケットのプロジェクト ID。
    • PROJECT_NUMBER: GKE クラスタの数値のプロジェクト番号。プロジェクト番号を確認するには、プロジェクトの識別をご覧ください。
    • PROJECT_ID: GKE クラスタのプロジェクト ID。
    • NAMESPACE: Kubernetes ServiceAccount の Kubernetes Namespace の名前。
    • KSA_NAME: 新しい Kubernetes ServiceAccount の名前。
    • ROLE_NAME: Kubernetes ServiceAccount に割り当てる IAM ロール。
      • 読み取り専用ワークロードの場合は、ストレージ オブジェクト閲覧者ロール(roles/storage.objectViewer)を使用します。
      • 読み取り / 書き込みワークロードの場合は、Storage Object ユーザーロールを使用します(roles/storage.objectUser)。

Cloud Storage FUSE バケットをマウントする準備をする

このセクションでは、クラスタに Cloud Storage FUSE バケットをマウントするための準備を行う方法について説明します。

Pod アノテーションを指定する

CSI ドライバは、Pod アノテーションを使用して、Cloud Storage を利用するボリュームを Pod が使用しているかどうかを判別します。ドライバが必要なアノテーションを検出すると、gke-gcsfuse-sidecar というサイドカー コンテナをワークロード Pod に追加します。Cloud Storage FUSE インスタンスは、サイドカー コンテナ内で実行され、ワークロードの Cloud Storage バケットをマウントします。

CSI ドライバが Cloud Storage バケットをマウントできるようにするには、Pod 仕様の metadata フィールドにアノテーション gke-gcsfuse/volumes: "true" を指定します。Cloud Storage でサポートされるボリュームを他の Kubernetes ワークロード タイプ(JobDeploymentStatefulSet など)で使用する場合は、アノテーションを spec.template.metadata.annotations フィールドに構成します。

Istio または Cloud Service Mesh を使用している場合は、次の Pod レベルのアノテーションを追加します。

proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
traffic.sidecar.istio.io/excludeOutboundIPRanges: 169.254.169.254/32

サイドカー コンテナのリソースを構成する

デフォルトでは、サイドカー コンテナは次のリソース リクエストで構成され、リソースの上限は設定されていません。

  • 250m CPU
  • 256 MiB のメモリ
  • 5 GiB のエフェメラル ストレージ

これらの値を上書きするには、必要に応じて次の例に示すようにアノテーション gke-gcsfuse/[cpu-limit|memory-limit|ephemeral-storage-limit|cpu-request|memory-request|ephemeral-storage-request] を指定します。

apiVersion: v1
kind: Pod
metadata:
  annotations:
    gke-gcsfuse/volumes: "true"
    gke-gcsfuse/cpu-limit: "10"
    gke-gcsfuse/memory-limit: 10Gi
    gke-gcsfuse/ephemeral-storage-limit: 1Ti
    gke-gcsfuse/cpu-request: 500m
    gke-gcsfuse/memory-request: 1Gi
    gke-gcsfuse/ephemeral-storage-request: 50Gi

割り当てるリソースの量を決定する際は、次の点を考慮してください。

  • リソース リクエストまたはリソース上限のアノテーションのいずれか一方のみを設定した場合、GKE はリソース リクエストとリソース上限に同じ値を適用します。
  • ワークロード Pod が複数の Cloud Storage ボリュームを使用する場合、サイドカー コンテナ リソースは複数の Cloud Storage FUSE インスタンスによって共有されます。これに該当する場合は、複数の Cloud Storage ボリュームに対するリソース割り当てを増やすことを検討してください。
  • ワークロードでより高いスループットが必要な場合は、サイドカー コンテナにより多くの CPU を割り当てます。CPU が不足すると、Cloud Storage FUSE スロットリングが発生します。
  • ワークロードで大量のファイルを処理する必要があり、Cloud Storage FUSE のメタデータ キャッシュが有効になっている場合は、サイドカー コンテナのメモリ割り当てを増やします。メタデータをキャッシュに保存する際の Cloud Storage FUSE のメモリ消費量は、ファイル数に比例しますが、ファイルサイズには比例しません。メモリが不足すると、Cloud Storage FUSE のメモリ不足エラーが発生し、ワークロード アプリケーションがクラッシュします。
  • ファイル キャッシュの場合、Cloud Storage FUSE はデフォルトでローカルの一時ディレクトリにファイルをキャッシュに保存します。ファイル キャッシュに必要なワークロードの空き容量を見積もり、それに応じてエフェメラル ストレージの上限を引き上げます。詳細については、ボリューム属性をご覧ください。
  • 書き込みオペレーションの場合、ファイルが Cloud Storage バケットにアップロードされる前に、デフォルトで Cloud Storage FUSE がローカルの一時ディレクトリにあるファイルをステージングします。大きなファイルを書き込むときにワークロードがステージングに必要な空き容量を見積もり、それに応じてエフェメラル ストレージの上限を引き上げます。詳細については、Cloud Storage FUSE GitHub ドキュメントの読み取り / 書き込みのセマンティクスをご覧ください。
  • "0" を使用すると、Standard クラスタに対するリソース上限またはリクエストの設定を解除できます。たとえば、アノテーション gke-gcsfuse/memory-limit: "0" により、サイドカー コンテナのメモリ上限はデフォルトのメモリ リクエストで空になります。これは、ワークロードに対して Cloud Storage FUSE で必要になるリソースの量を特定できず、ノード上の使用可能なすべてのリソースを Cloud Storage FUSE が消費できるようにする必要がある場合に有効です。ワークロードの指標に基づいて Cloud Storage FUSE のリソース要件を計算した後、適切な上限を設定できます。

サイドカー コンテナの非公開イメージを構成する

このセクションでは、限定公開コンテナ レジストリにホストされているサイドカー コンテナ イメージの使用方法について説明します。このシナリオは、セキュリティ上の目的で限定公開クラスタを使用する必要がある場合や、クラスタで公共のインターネットへのアクセスが制限されている場合に適用されます。限定公開のサイドカー コンテナ イメージを構成して使用するには、次の操作を行います。

  1. 互換性のある公開サイドカー コンテナ イメージについては、こちらのページをご覧ください。

  2. ローカル環境に pull して限定公開コンテナ レジストリに push します。

  3. マニフェストで、image フィールドのみを含む gke-gcsfuse-sidecar という名前のコンテナを指定します。GKE は、指定されたサイドカー コンテナ イメージを使用して、サイドカー コンテナ インジェクションを準備します。以下に例を示します。

apiVersion: v1
kind: Pod
metadata:
  annotations:
    gke-gcsfuse/volumes: "true"
spec:
  containers:
  - name: gke-gcsfuse-sidecar
    image: PRIVATE_REGISTRY/gcs-fuse-csi-driver-sidecar-mounter:PRIVATE_IMAGE_TAG
  - name: main # your main workload container.

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

  • PRIVATE_REGISTRY: 限定公開のコンテナ レジストリ。
  • PRIVATE_IMAGE_TAG: 限定公開のサイドカー コンテナ イメージのタグ。

サイドカー コンテナのカスタム書き込みバッファ ボリュームを構成する

このセクションでは、Cloud Storage FUSE 書き込みバッファリング用のカスタム バッファ ボリュームを構成する方法について説明します。このシナリオは、Cloud Storage FUSE のデフォルトの emptyDir ボリュームを置き換えて、書き込みオペレーションでファイルをステージングする必要がある場合に適用できます。GKE でサポートされている任意のタイプのストレージ(PersistentVolumeClaim など)を指定できます。GKE は、指定されたボリュームをファイルの書き込みバッファに使用します。これは、Autopilot クラスタで 10 GiB を超えるファイルを書き込む必要がある場合に有効です。カスタム バッファ ボリュームを使用するには、ゼロ以外の fsGroup を指定する必要があります。次の例は、バッファ ボリュームとして事前定義済みの PVC を使用する方法を示しています。

apiVersion: v1
kind: Pod
metadata:
  annotations:
    gke-gcsfuse/volumes: "true"
spec:
  securityContext:
    fsGroup: FS_GROUP
  containers:
  ...
  volumes:
  - name: gke-gcsfuse-buffer
    persistentVolumeClaim:
      claimName: BUFFER_VOLUME_PVC

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

  • FS_GROUP: fsGroup ID。
  • BUFFER_VOLUME_PVC: 事前定義された PVC 名。

サイドカー コンテナのカスタム読み取りキャッシュ ボリュームを構成する

このセクションでは、Cloud Storage FUSE 読み取りキャッシュ用にカスタム キャッシュ ボリュームを構成する方法について説明します。このシナリオは、Cloud Storage FUSE のデフォルトの emptyDir ボリュームを置き換えて、読み取りオペレーションでファイルをキャッシュに保存する必要がある場合に適用できます。GKE でサポートされている任意のタイプのストレージ(PersistentVolumeClaim など)を指定できます。GKE は、指定されたボリュームをファイル キャッシュに使用します。これは、Autopilot クラスタで 10 GiB を超えるファイルをキャッシュに保存する必要がある場合に有効です。カスタム キャッシュ ボリュームを使用するには、ゼロ以外の fsGroup を指定する必要があります。次の例では、キャッシュ ボリュームとして事前定義済みの PVC を使用する方法を示します。

apiVersion: v1
kind: Pod
metadata:
  annotations:
    gke-gcsfuse/volumes: "true"
spec:
  securityContext:
    fsGroup: FS_GROUP
  containers:
  ...
  volumes:
  - name: gke-gcsfuse-cache
    persistentVolumeClaim:
      claimName: CACHE_VOLUME_PVC

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

  • FS_GROUP: fsGroup ID。
  • CACHE_VOLUME_PVC: 事前定義された PVC 名。

ボリュームを CSI エフェメラル ボリュームとしてプロビジョニングする

Cloud Storage バケットを基盤とする CSI エフェメラル ボリュームは、Pod のライフサイクルに関連付けられます。このプロビジョニング方法では、Pod の終了後に、Cloud Storage バケットに関連付けられた PersistentVolume オブジェクトと PersistentVolumeClaim オブジェクトを維持する必要はありません。

Pod で CSI エフェメラル ストレージ ボリュームを使用する

  1. 次の YAML マニフェストを保存します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-example-ephemeral
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true"
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - image: busybox
        name: busybox
        command: ["sleep"]
        args: ["infinity"]
        volumeMounts:
        - name: gcs-fuse-csi-ephemeral
          mountPath: /data
          readOnly: true
      serviceAccountName: KSA_NAME
      volumes:
      - name: gcs-fuse-csi-ephemeral
        csi:
          driver: gcsfuse.csi.storage.gke.io
          readOnly: true
          volumeAttributes:
            bucketName: BUCKET_NAME
            mountOptions: "implicit-dirs"
            gcsfuseLoggingSeverity: warning
    

    上記の例は、Pod マニフェストで Cloud Storage バケットをインラインで指定する方法を示しています。この例には次のフィールドがあります。

    • metadata.annotations: アノテーション gke-gcsfuse/volumes: "true" は必須です。オプションのアノテーションについては、サイドカー コンテナのリソースを構成するをご覧ください。
    • spec.terminationGracePeriodSeconds: 省略可。デフォルトの設定値は 30 です。サイズの大きいファイルを Cloud Storage バケットに書き込む必要がある場合は、この値を引き上げて、Cloud Storage FUSE がアプリケーションの終了後にデータをフラッシュするのに十分な時間を確保します。詳細については、Kubernetes のベスト プラクティス: 猶予期間による終了をご覧ください。
    • spec.serviceAccountName: GKE 用 Workload Identity 連携を使用して Cloud Storage バケットへのアクセスを構成するの手順と同じ Kubernetes ServiceAccount を使用します。
    • spec.volumes[n].csi.driver: CSI ドライバ名として gcsfuse.csi.storage.gke.io を使用します。
    • spec.volumes[n].csi.volumeAttributes.bucketName: Cloud Storage FUSE のバケット名を指定します。アンダースコア(_)を指定すると、Kubernetes ServiceAccount がアクセスできるすべてのバケットをマウントできます。詳細については、Cloud Storage FUSE ドキュメントの動的マウントをご覧ください。
    • spec.volumes[n].csi.volumeAttributes.mountOptions: 省略可。マウント オプションを Cloud Storage FUSE に渡します。フラグはスペースなしのカンマ区切りの 1 つの文字列で指定します。
    • spec.volumes[n].csi.volumeAttributes: 省略可。他のボリューム属性を Cloud Storage FUSE に渡します。
    • spec.volumes[n].csi.readOnly: 省略可。すべてのボリューム マウントが読み取り専用の場合は、true を指定します。
    • spec.containers[n].volumeMounts[m].readOnly: 省略可。特定のボリューム マウントのみが読み取り専用の場合は、true を指定します。
  2. マニフェストをクラスタに適用します。

    kubectl apply -f FILE_PATH
    

    FILE_PATH は、YAML ファイルのパスに置き換えます。

ジョブ ワークロードで CSI エフェメラル ストレージ ボリュームを使用する

  1. 次の YAML マニフェストを保存します。

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: gcs-fuse-csi-job-example
      namespace: NAMESPACE
    spec:
      template:
        metadata:
          annotations:
            gke-gcsfuse/volumes: "true"
        spec:
          serviceAccountName: KSA_NAME
          containers:
          - name: writer
            image: busybox
            command:
              - "/bin/sh"
              - "-c"
              - touch /data/test && echo $(date) >> /data/test && sleep 10
            volumeMounts:
            - name: gcs-fuse-csi-ephemeral
              mountPath: /data
          - name: reader
            image: busybox
            command:
              - "/bin/sh"
              - "-c"
              - sleep 10 && cat /data/test
            volumeMounts:
            - name: gcs-fuse-csi-ephemeral
              mountPath: /data
              readOnly: true
          volumes:
          - name: gcs-fuse-csi-ephemeral
            csi:
              driver: gcsfuse.csi.storage.gke.io
              volumeAttributes:
                bucketName: BUCKET_NAME
          restartPolicy: Never
      backoffLimit: 1
    

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

    マニフェストは、CSI エフェメラル ボリュームを介して Cloud Storage FUSE バケットを使用する Job をデプロイします。

  2. マニフェストをクラスタに適用します。

    kubectl apply -f FILE_PATH
    

    FILE_PATH は、YAML ファイルのパスに置き換えます。

Job ワークロードで CSI ドライバを使用している場合、または Pod RestartPolicyNever の場合、サイドカー コンテナは他のすべてのワークロード コンテナが終了した後に自動的に終了します。

その他の例については、GitHub プロジェクトに関するドキュメントのサンプル アプリケーションをご覧ください。

静的プロビジョニングを使用してボリュームをプロビジョニングする

静的プロビジョニングを使用して、基盤となるストレージ システムの詳細を含む 1 つ以上の PersistentVolume(PV)オブジェクトを作成します。クラスタ内の Pod は、PersistentVolumeClaim(PVC)を通じてストレージを消費できます。

PersistentVolume を作成する

  1. 次の YAML マニフェストを保存します。

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: gcs-fuse-csi-pv
    spec:
      accessModes:
      - ReadWriteMany
      capacity:
        storage: 5Gi
      storageClassName: example-storage-class
      mountOptions:
        - implicit-dirs
      csi:
        driver: gcsfuse.csi.storage.gke.io
        volumeHandle: BUCKET_NAME
        volumeAttributes:
          gcsfuseLoggingSeverity: warning
    

    マニフェストの例は、Cloud Storage バケットに PersistentVolume を定義する方法を示しています。この例には次のフィールドがあります。

    • spec.csi.driver: CSI ドライバ名として gcsfuse.csi.storage.gke.io を使用します。
    • spec.csi.volumeHandle: Cloud Storage バケット名を指定します。アンダースコア(_)を渡すことで、Kubernetes ServiceAccount がアクセスできるように構成しているすべてのバケットをマウントできます。詳細については、Cloud Storage FUSE ドキュメントの動的マウントをご覧ください。
    • spec.mountOptions: 省略可。マウント オプションを Cloud Storage FUSE に渡します。
    • spec.csi.volumeAttributes: 省略可。ボリューム属性を Cloud Storage FUSE に渡します。
  2. マニフェストをクラスタに適用します。

    kubectl apply -f FILE_PATH
    

    FILE_PATH は、YAML ファイルのパスに置き換えます。

PersistentVolumeClaim を作成する

  1. 次の YAML マニフェストを保存します。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: gcs-fuse-csi-static-pvc
      namespace: NAMESPACE
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 5Gi
      volumeName: gcs-fuse-csi-pv
      storageClassName: example-storage-class
    

    マニフェストの例は、PersistentVolumeClaim を定義して PersistentVolume をバインドする方法を示しています。この例には次のフィールドがあります。

    • metadata.namespace: ワークロードの Namespace と一貫している必要がある PersistentVolumeClaim Namespace を指定します。
    • spec.volumeName: PersistentVolume の名前を指定します。

    PersistentVolume を PersistentVolumeClaim にバインドするには、次のガイドラインに沿ってください。

    • PV マニフェストと PVC マニフェストの spec.storageClassName フィールドは一致する必要があります。storageClassName は、既存の StorageClass オブジェクトを参照する必要はありません。要求をボリュームにバインドするには、任意の名前を使用できますが、空にすることはできません。
    • PV マニフェストと PVC マニフェストの spec.accessModes フィールドは一致する必要があります。
    • PersistentVolume マニフェストの spec.capacity.storage は、PersistentVolumeClaim マニフェストの spec.resources.requests.storage と一致する必要があります。Cloud Storage バケットにはサイズ制限がないため、任意の数を容量として設定できますが、空にすることはできません。
  2. マニフェストをクラスタに適用します。

    kubectl apply -f FILE_PATH
    

    FILE_PATH は、YAML ファイルのパスに置き換えます。

PersistentVolumeClaim のボリュームを使用する

  1. 次の YAML マニフェストを保存します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-example-static-pvc
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true"
    spec:
      containers:
      - image: busybox
        name: busybox
        command: ["sleep"]
        args: ["infinity"]
        volumeMounts:
        - name: gcs-fuse-csi-static
          mountPath: /data
          readOnly: true
      serviceAccountName: KSA_NAME
      volumes:
      - name: gcs-fuse-csi-static
        persistentVolumeClaim:
          claimName: gcs-fuse-csi-static-pvc
          readOnly: true
    

    この例では、PersistentVolumeClaim を介して Cloud Storage FUSE バケットを使用する Pod を定義する方法を示しています。この例には次のフィールドがあります。

  2. マニフェストをクラスタに適用します。

    kubectl apply -f FILE_PATH
    

    FILE_PATH は、YAML ファイルのパスに置き換えます。

その他の例については、GitHub プロジェクトに関するドキュメントのサンプル アプリケーションをご覧ください。

ファイル キャッシュを有効にしてボリュームを使用する

デフォルトでは、GKE におけるファイル キャッシュ機能は無効になっています。ファイル キャッシュを有効にして制御するには、ボリューム属性 fileCacheCapacity を使用します。

GKE は、ノード VM ブートディスクによってサポートされる Cloud Storage FUSE のファイル キャッシュに emptyDir ボリュームを使用します。ノードでローカル SSD を有効にすると、GKE はローカル SSD を使用して emptyDir ボリュームをサポートします。

読み取りオペレーションにおけるファイル キャッシュのデフォルトの emptyDir ボリュームは、サイドカー コンテナのカスタム読み取りキャッシュ ボリュームを構成することで置き換えできます。ローカル SSD をサポートする CPU VM ファミリーと GPU VM ファミリーでは、ローカル SSD ストレージの使用をおすすめします。TPU ファミリーや Autopilot の場合は、バランス永続ディスクか SSD 永続ディスクの使用をおすすめします。

ファイル キャッシュを有効にして CSI エフェメラル ストレージ ボリュームを使用する

ファイル キャッシュがある CSI エフェメラル ボリュームを介して Cloud Storage FUSE バケットを使用する Pod をデプロイするには、以下の手順に沿って操作します。

  1. ローカル SSD を基盤とするエフェメラル ストレージを備えたクラスタまたはノードプールを作成します。

    GKE のドキュメントに従って、ローカル SSD を基盤とするエフェメラル ストレージを備えたクラスタまたはノードプールを作成します。

  2. 次の YAML マニフェストを保存します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-file-cache-example
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true"
        gke-gcsfuse/ephemeral-storage-limit: "50Gi"
    spec:
      nodeSelector:
        cloud.google.com/gke-ephemeral-storage-local-ssd: "true"
      restartPolicy: Never
      initContainers:
      - name: data-loader
        image: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
        resources:
          limits:
            cpu: 500m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 1Gi
        command:
          - "/bin/sh"
          - "-c"
          - |
            mkdir -p /test_files
            for i in $(seq 1 1000); do dd if=/dev/zero of=/test_files/file_$i.txt bs=1024 count=64; done
            gcloud storage cp /test_files gs://BUCKET_NAME --recursive
      containers:
      - name: data-validator
        image: busybox
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
          requests:
            cpu: 500m
            memory: 512Mi
        command:
          - "/bin/sh"
          - "-c"
          - |
            echo "first read with cache miss"
            time cat /data/test_files/file_* > /dev/null
    
            echo "second read from local cache"
            time cat /data/test_files/file_* > /dev/null
        volumeMounts:
        - name: gcs-fuse-csi-ephemeral
          mountPath: /data
      serviceAccountName: KSA_NAME
      volumes:
      - name: gcs-fuse-csi-ephemeral
        csi:
          driver: gcsfuse.csi.storage.gke.io
          volumeAttributes:
            bucketName: BUCKET_NAME
            mountOptions: "implicit-dirs"
            fileCacheCapacity: "10Gi"
    

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

    init コンテナ data-loader は、サイズが 64 KiB のファイルを 1,000 個作成して、Cloud Storage バケットにアップロードします。メインコンテナ data-validator は、バケット内のすべてのファイルを 2 回読み取り、それにかかった期間をログに記録します。

  3. マニフェストをクラスタに適用します。

    kubectl apply -f FILE_PATH
    

    FILE_PATH は、YAML ファイルのパスに置き換えます。

  4. ログ出力を表示するには、次のコマンドを実行します。

    kubectl logs -n NAMESPACE gcs-fuse-csi-file-cache-example -c data-validator
    

    NAMESPACE は、ワークロードの名前空間に置き換えます。

    出力は次のようになります。

    first read with cache miss
    real    0m 54.68s
    ...
    second read from local cache
    real    0m 0.38s
    ...
    

    出力から、ローカル キャッシュを使用した 2 回目の読み取りが、キャッシュミスを使用した 1 回目の読み取りよりもはるかに高速であることがわかります。

Cloud Storage FUSE バケットのマウント方法を構成する

このセクションでは、Cloud Storage FUSE ボリュームを構成する方法について説明します。

マウント オプション

Cloud Storage FUSE CSI ドライバは、Cloud Storage バケットをローカル ファイル システムにどのようにマウントするかを構成するマウント オプションをサポートします。サポートされているマウント オプションの全一覧については、gcsfuse CLI のドキュメントをご覧ください。

マウントフラグは次の方法で指定できます。

  • 静的プロビジョニングを使用する場合、PersistentVolume マニフェストの spec.mountOptions フィールド。
  • CSI エフェメラル ボリュームを使用する場合、spec.volumes[n].csi.volumeAttributes.mountOptions フィールド。

ボリューム属性

Cloud Storage FUSE CSI ドライバでは、Cloud Storage FUSE 構成ファイルを直接指定できません。以下のボリューム属性を使用して、構成ファイル内の一部のフィールドを構成できます。値は構成ファイルのフィールドに変換されます。

  • gcsfuseLoggingSeverity

    • 説明: Cloud Storage FUSE で生成するログの重大度が列挙型で表されます。すでに debug_fusedebug_fs、または debug_gcs のマウント オプションを使用している場合、この新しい構成は自動的に trace に設定されます。このボリューム属性は、構成ファイルの logging:severity フィールドに変換されます。

    • 有効な値(重大度が低い順):

      • trace
      • debug
      • info
      • warning
      • error
    • デフォルト値: info

  • fileCacheCapacity

    • 説明: ファイル キャッシュで使用できる最大サイズ。ゼロ以外の値が指定された場合、このボリューム属性により、Cloud Storage FUSE でのファイル キャッシュが有効になります。このボリューム属性は、構成ファイルの file-cache:max-size-mb フィールドに変換されます。

    • 有効な値:

      • 数量値(例: 500Mi10Gi)。
      • 「-1」: キャッシュ ボリュームの使用可能な容量全体を使用します。
      • 「0」: ファイルのキャッシュ保存は無効です。
    • デフォルト値: 「0」

  • fileCacheForRangeRead

    • 説明: ゼロ以外のオフセットから最初の読み取りが行われたときに、オブジェクト全体を非同期的にダウンロードして Cloud Storage FUSE キャッシュ ディレクトリに保存するかどうかを示します。ランダム読み取りまたは部分読み取りを複数回行う場合は、この値を「true」に設定する必要があります。このボリューム属性は、構成ファイルの file-cache:cache-file-for-range-read フィールドに変換されます。

    • 有効な値:

      • 文字列形式のブール値(「true」、「false」)。
    • デフォルト値: 「false」

  • metadataStatCacheCapacity

    • 説明: 統計情報キャッシュで使用できる最大サイズ。統計情報キャッシュは常にメモリ内に保持されます。stat-cache-capacity マウント オプションをすでに使用している場合、その値は引き続き有効で、この新しい構成に適切に変換されます。このボリューム属性は、構成ファイルの metadata-cache:stat-cache-max-size-mb フィールドに変換されます。

    • 有効な値:

      • 数量値(例: 500Mi1Gi)。
      • 「-1」: 統計キャッシュが必要なだけメモリを使用できるようにします。
      • 「0」: 統計キャッシュは無効です。
      • ワークロードに最大 20,000 個のファイルが含まれる場合は、デフォルト値の 32Mi を使用します。ワークロードのファイルが 20,000 ファイルを超える場合は、6,000 ファイルを追加するごとにサイズを 10 MiB ずつ増やします(ファイルあたり平均約 1,500 バイト)。
    • デフォルト値: 32Mi

  • metadataTypeCacheCapacity

    • 説明: タイプ キャッシュで使用できるディレクトリあたりの最大サイズ。タイプ キャッシュは常にメモリ内に保持されます。このボリューム属性は、構成ファイルの metadata-cache:type-cache-max-size-mb フィールドに変換されます。

    • 有効な値:

      • 数量値(例: 500Mi1Gi)。
      • 「-1」: タイプ キャッシュが必要なだけメモリを使用できるようにします。
      • 「0」: タイプ キャッシュは無効です。
      • マウントするバケットの 1 つのディレクトリ内にあるファイルの最大数が 20,000 以下の場合は、デフォルト値の 4Mi を使用します。マウントする 1 つのディレクトリ内のファイルの最大数が 20,000 を超える場合は、5,000 ファイルごとにサイズを 1 MiB 増やします(ファイルあたり平均約 200 バイト)。
    • デフォルト値: 4Mi

  • metadataCacheTTLSeconds

    • 説明: キャッシュに保存されたメタデータ エントリの有効期間(TTL)を秒単位で指定します。stat-cache-ttl または type-cache-ttl マウント オプションをすでに使用している場合、その値は引き続き有効で、この新しい構成に適切に変換されます。このボリューム属性は、構成ファイルの metadata-cache:ttl-secs フィールドに変換されます。

    • 有効な値:

      • 文字列形式の整数値(例: 「600」)。
      • 「-1」: TTL の有効期限をバイパスし、キャッシュから利用可能な場合にファイルを配信します。
      • 「0」: 最新のファイルが読み取られるようにします。0 の値を使用すると、Get メタデータ呼び出しが行われ、キャッシュ内のファイルのオブジェクトの世代が Cloud Storage に保存されているものと一致するようにします。
    • デフォルト値:: 「60」

ボリューム属性は、次の方法で指定できます。

  • 静的プロビジョニングを使用する場合、PersistentVolume マニフェストの spec.csi.volumeAttributes フィールド。
  • CSI エフェメラル ボリュームを使用する場合、spec.volumes[n].csi.volumeAttributes フィールド。

考慮事項

マウントを構成する際は、次の点を考慮してください。

  • 次のフラグは使用できません: app-nametemp-dirforegroundlog-filelog-formatkey-filetoken-urlreuse-token-from-url
  • Cloud Storage FUSE では、デフォルトで暗黙のディレクトリは表示されません。これらのディレクトリを表示するには、implicit-dirs マウントフラグを有効にします。詳細については、Cloud Storage FUSE の GitHub ドキュメントのファイルとディレクトリをご覧ください。
  • Pod またはコンテナにセキュリティ コンテキストを使用する場合、またはコンテナ イメージが root 以外のユーザーまたはグループを使用する場合は、uidgid のマウントフラグを設定する必要があります。ファイル システムの権限を設定するには、file-mode マウントフラグと dir-mode マウントフラグも使用する必要があります。Cloud Storage FUSE ファイル システムに対して chmodchownchgrp コマンドを実行することはできません。したがって、uidgidfile-modedir-mode マウントフラグは、root 以外のユーザーまたはグループにアクセス権を付与するために必要です。
  • バケット全体ではなくバケット内のディレクトリのみをマウントする場合は、only-dir=relative/path/to/the/bucket/root フラグを使用してディレクトリの相対パスを渡します。
  • Cloud Storage FUSE のキャッシュ保存の動作を調整するには、ボリューム属性を構成します。詳細については、Cloud Storage FUSE のキャッシュ保存のドキュメントをご覧ください。
  • サーバーごとに許可される TCP 接続の最大数を指定する場合は、最大数を max-conns-per-host フラグに指定します。定義した TCP 接続の最大数は、--client-protocolhttp1 に設定されている場合に有効になります。デフォルト値は 0 で、TCP 接続に制限がないことを示します(ただし、マシンの仕様によって制限されます)。
  • Linux カーネルのマウント オプションを構成する必要がある場合は、o フラグを使用してオプションを渡すことができます。たとえば、マウントされたファイル システムでバイナリの直接実行を許可しない場合は、o=noexec フラグを設定します。 各オプションには、o=noexec,o=noatime などの個別のフラグが必要です。使用できるオプションは、execnoexecatimenoatimesyncasyncdirsync のみです。
  • Cloud Storage FUSE の問題のトラブルシューティングを行う場合は、debug_fusedebug_fsdebug_gcs の各フラグを設定します。3 つのオプションのいずれかを指定すると、gcsfuseLoggingSeverity ボリューム属性が自動的に trace に設定されます。
  • Cloud Storage FUSE CSI ドライバで、Cloud Storage FUSE 構成ファイルcache-dir フィールドを変更することはできません。ファイル キャッシュを有効または無効にするには、fileCacheCapacity ボリューム属性を使用します。ファイル キャッシュに対するデフォルトの emptyDir ボリュームを置き換えるには、サイドカー コンテナのカスタム キャッシュ ボリュームを構成します。

Cloud Storage FUSE の CSI ドライバを無効にする

Autopilot クラスタで Cloud Storage FUSE の CSI ドライバを無効にすることはできません。

既存の Standard クラスタで Cloud Storage FUSE の CSI ドライバを無効にするには、Google Cloud CLI を使用します。

gcloud container clusters update CLUSTER_NAME \
    --update-addons GcsFuseCsiDriver=DISABLED

CLUSTER_NAME は、使用するクラスタの名前に置き換えます。

トラブルシューティング

Cloud Storage FUSE の CSI ドライバの使用時に発生する問題のトラブルシューティングについては、GitHub プロジェクトのドキュメントのトラブルシューティング ガイドをご覧ください。

次のステップ