このガイドでは、Cloud Storage バケットを基盤とする CSI エフェメラル ボリュームを使用して、Google Kubernetes Engine(GKE)で Kubernetes Pod または Job のストレージ リソースを自動的に管理する方法について説明します。CSI エフェメラル ボリュームは Pod または Job のライフサイクルに関連付けられているため、PersistentVolume オブジェクトと PersistentVolumeClaim オブジェクトを手動で処理する必要はありません。
このガイドは、GKE アプリケーションのストレージ管理を簡素化したいプラットフォーム管理者とオペレーターを対象としています。
このページを読む前に、CSI エフェメラル ボリューム、Kubernetes Pod と Job、Cloud Storage バケットについて理解しておいてください。
PersistentVolume に精通していて、このリソースタイプに依存する既存のデプロイメントとの整合性を維持したい場合は、Cloud Storage バケットを永続ボリュームとしてマウントするをご覧ください。
始める前に
次の前提条件を満たしていることを確認してください。
- Cloud Storage FUSE CSI ドライバの要件と制限事項を理解する。
- Cloud Storage バケットを作成する
- Cloud Storage FUSE の CSI ドライバを有効にする
- Cloud Storage バケットへのアクセスを構成する
Cloud Storage バケットの CSI エフェメラル ストレージの仕組み
CSI エフェメラル ボリュームを使用すると、GKE 上のアプリケーションのストレージ管理が簡素化されます。CSI エフェメラル ボリュームは、Pod または Job 仕様内で直接定義します。CSI エフェメラル ボリュームを使用すると、個別の PersistentVolume オブジェクトと PersistentVolumeClaim オブジェクトを必要としません。
CSI エフェメラル ボリュームを使用するには、次のオペレーションが必要です。
ストレージの定義: 使用する CSI ドライバや必要なパラメータなど、ストレージを Pod または Job の YAML ファイルで指定します。Cloud Storage FUSE CSI ドライバの場合は、バケット名とその他の関連情報を指定します。
必要に応じて、ファイル キャッシュ機能を使用して CSI ドライバのパフォーマンスを微調整できます。ファイル キャッシュを使用すると、頻繁にアクセスされる Cloud Storage ファイルを高速ディスクにキャッシュに保存することで、GKE アプリのパフォーマンスを向上させることができます。
また、並列ダウンロード機能を使用して、Cloud Storage からの大規模なファイルの読み取りを高速化し、マルチスレッド ダウンロードを実現できます。この機能を使用すると、特にサイズが 1 GB を超える読み取りでモデルの読み込み時間を短縮できます。
ドライバの呼び出し: Pod または Job を作成すると、GKE はエフェメラル ボリューム リクエストを検出し、Cloud Storage FUSE CSI ドライバを呼び出します。
ボリュームのマウントとアタッチメント: CSI ドライバは、CSI エフェメラル ボリューム(基盤となる Cloud Storage バケットを参照)をマウントし、Pod または Job で使用できるようにして、アプリケーションからアクセスできるようにします。ファイル システムでバケットのマウント方法を微調整するには、マウント オプションを使用します。ボリューム属性を使用して、Cloud Storage FUSE CSI ドライバの特定の動作を構成することもできます。
ライフサイクル管理: エフェメラル ボリュームは、Pod または Job の存続期間中のみ存在します。Pod が削除された場合、または Job が完了すると、CSI ドライバはクリーンアップと Volume のマウントを自動的に処理します。
CSI エフェメラル ボリュームをアタッチする
CSI エフェメラル ボリュームを Pod または Job に接続するかどうかに応じて、次の手順を行います。
Pod
Pod に CSI エフェメラル ボリュームをアタッチする手順は次のとおりです。
次の仕様で Pod 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"
次の値を置き換えます。
- NAMESPACE: Pod をデプロイする Kubernetes Namespace。
- KSA_NAME: Cloud Storage バケットへのアクセスを構成するときに指定した Kubernetes ServiceAccount の名前。
- BUCKET_NAME: Cloud Storage バケットへのアクセスを構成するときに指定した Cloud Storage バケット名。アンダースコア(
_
)を指定すると、Kubernetes ServiceAccount がアクセスできるすべてのバケットをマウントできます。詳細については、Cloud Storage FUSE ドキュメントの動的マウントをご覧ください。
次のマニフェストの例は、これらの必須設定を示しています。
metadata.annotations
: アノテーションgke-gcsfuse/volumes: "true"
は必須です。オプションのアノテーションについては、サイドカー コンテナを構成するをご覧ください。spec.volumes[n].csi.driver
: CSI ドライバ名としてgcsfuse.csi.storage.gke.io
を使用します。
必要に応じて、次の変数を調整できます。
spec.terminationGracePeriodSeconds
: デフォルトは 30 です。サイズの大きいファイルを Cloud Storage バケットに書き込む必要がある場合は、この値を引き上げて、Cloud Storage FUSE がアプリケーションの終了後にデータをフラッシュするのに十分な時間を確保します。詳細については、Kubernetes のベスト プラクティス: 猶予期間による終了をご覧ください。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 を指定します。
次のコマンドを実行して、マニフェストをクラスタに適用します。
kubectl apply -f FILE_PATH
FILE_PATH は、YAML ファイルのパスに置き換えます。
Pod(ファイル キャッシュ保存)
Pod にファイル キャッシュを使用して CSI エフェメラル ボリュームをアタッチする手順は次のとおりです。
ローカル SSD を基盤とするエフェメラル ストレージを備えたクラスタまたはノードプールを作成するの手順に沿って、ローカル SSD を基盤とするエフェメラル ストレージを備えたクラスタまたはノードプールを作成します。
次の仕様で Pod 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,file-cache:max-size-mb:-1"
次の値を置き換えます。
- NAMESPACE: Pod をデプロイする Kubernetes Namespace。
- KSA_NAME: Cloud Storage バケットへのアクセスを構成するときに指定した Kubernetes ServiceAccount の名前。
BUCKET_NAME: Cloud Storage バケットへのアクセスを構成するときに指定した Cloud Storage バケット名。アンダースコア(
_
)を指定すると、Kubernetes ServiceAccount がアクセスできるすべてのバケットをマウントできます。詳細については、Cloud Storage FUSE ドキュメントの動的マウントをご覧ください。マニフェストの例では、init コンテナのデータローダーは、サイズが 64 KiB のファイルを 1,000 個生成し、Cloud Storage バケットにアップロードします。メインコンテナ
data-validator
は、バケット内のすべてのファイルを 2 回読み取り、それにかかった期間をログに記録します。
次のコマンドを実行して、マニフェストをクラスタに適用します。
kubectl apply -f FILE_PATH
FILE_PATH は、YAML ファイルのパスに置き換えます。
ログ出力を表示するには、次のコマンドを実行します。
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 回目の読み取りよりもはるかに高速であることがわかります。
Pod(並列ダウンロード)
Pod で並列ダウンロードを使用して CSI エフェメラル ボリュームをアタッチする手順は次のとおりです。
次の仕様で Pod YAML マニフェストを作成します。
apiVersion: v1 kind: Pod metadata: name: gcs-fuse-csi-example-ephemeral namespace: NAMESPACE annotations: gke-gcsfuse/volumes: "true" gke-gcsfuse/ephemeral-storage-limit: "50Gi" spec: containers: ... volumes: - name: gcs-fuse-csi-ephemeral csi: driver: gcsfuse.csi.storage.gke.io volumeAttributes: bucketName: BUCKET_NAME mountOptions: "implicit-dirs,file-cache:enable-parallel-downloads:true,file-cache:max-size-mb:-1" fileCacheCapacity: "-1"
次の値を置き換えます。
- NAMESPACE: Pod をデプロイする Kubernetes Namespace。
- BUCKET_NAME: Cloud Storage バケットへのアクセスを構成するときに指定した Cloud Storage バケット名。アンダースコア(
_
)を指定すると、Kubernetes ServiceAccount がアクセスできるすべてのバケットをマウントできます。詳細については、Cloud Storage FUSE ドキュメントの動的マウントをご覧ください。
次のコマンドを実行して、マニフェストをクラスタに適用します。
kubectl apply -f FILE_PATH
FILE_PATH は、YAML ファイルのパスに置き換えます。
ジョブ
Job で CSI エフェメラル ボリュームをアタッチする手順は次のとおりです。
次の仕様で Job 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
次の値を置き換えます。
- NAMESPACE: Pod をデプロイする Kubernetes Namespace。
- KSA_NAME: Cloud Storage バケットへのアクセスを構成するときに指定した Kubernetes ServiceAccount の名前。
- BUCKET_NAME: Cloud Storage バケットへのアクセスを構成するときに指定した Cloud Storage バケット名。アンダースコア(
_
)を指定すると、Kubernetes ServiceAccount がアクセスできるすべてのバケットをマウントできます。詳細については、Cloud Storage FUSE ドキュメントの動的マウントをご覧ください。
次のマニフェストの例は、これらの必須設定を示しています。
metadata.annotations
: アノテーションgke-gcsfuse/volumes: "true"
は必須です。オプションのアノテーションについては、サイドカー コンテナを構成するをご覧ください。spec.volumes[n].csi.drive
r: CSI ドライバ名としてgcsfuse.csi.storage.gke.io
を使用します。
必要に応じて、次の変数を調整できます。
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 を指定します。
次のコマンドを実行して、マニフェストをクラスタに適用します。
kubectl apply -f FILE_PATH
FILE_PATH
は、YAML ファイルのパスに置き換えます。
問題のトラブルシューティング
Cloud Storage FUSE の問題のトラブルシューティングを行う場合は、log-severity
フラグを TRACE
に設定できます。このフラグは、Deployment YAML 内のドライバのコンテナ仕様の args
セクションで設定します。これにより、gcsfuseLoggingSeverity
ボリューム属性が自動的にトレース設定されます。
その他のトラブルシューティングのヒントについては、GitHub プロジェクトのドキュメントのトラブルシューティング ガイドをご覧ください。
次のステップ
- Cloud Storage FUSE CSI ドライバのパフォーマンスを最適化する方法について学習する。
- GitHub で CSI ドライバの使用に関する追加のサンプルを確認する。
- Cloud Storage Fuse の詳細を確認する。