GKE Cloud Storage FUSE CSI Driver — AI/ML Object Storage as a File System 🪣📂
Training machine learning models and serving large AI inference checkpoints in Kubernetes often requires accessing petabytes of training images, audio files, and model weights. Provisioning massive Persistent Disks or NFS filestores for terabytes of static data is prohibitively expensive. The Google Cloud Storage (GCS) FUSE CSI Driver for GKE mounts Cloud Storage buckets directly into Kubernetes Pods as a POSIX-compliant file system. Powered by Google’s optimized gcsfuse binary, the driver enables pods to stream, read, and write object data using standard file system calls (open(), read(), write()) at high throughput with zero upfront disk provisioning.
1. Architecture & The gcsfuse User-Space Engine
The GCS FUSE CSI driver injects a lightweight user-space file system daemon alongside the container via Kubernetes mutating admission webhooks.
KUBERNETES APPLICATION POD (PyTorch / TensorFlow)
│
▼ POSIX File I/O: `open('/data/train.parquet')`
┌────────────────────────────────────────────────────────────────────────┐
│ LINUX KERNEL VIRTUAL FILE SYSTEM (VFS) │
│ │
│ - Forwards file system operations to the FUSE kernel module (/dev/fuse)
└───────────────────────────────────┬────────────────────────────────────┘
│ Kernel Context Switch
▼
┌────────────────────────────────────────────────────────────────────────┐
│ GCSFUSE SIDECAR CONTAINER (gke-gcsfuse-sidecar) │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ LOCAL IN-MEMORY & LOCAL SSD CACHE │ │
│ │ - Stat cache (metadata lookups) & Type cache (TTL: 60s) │ │
│ │ - File cache (streams hot dataset chunks from local NVMe) │ │
│ └──────────────────────────────────┬───────────────────────────────┘ │
│ │ Cloud Storage REST / gRPC APIs │
│ ┌──────────────────────────────────▼───────────────────────────────┐ │
│ │ WORKLOAD IDENTITY TOKEN MANAGER │ │
│ │ - Dynamic OAuth2 access tokens via pod's ServiceAccount │ │
│ └──────────────────────────────────┬───────────────────────────────┘ │
└─────────────────────────────────────┼──────────────────────────────────┘
│ Parallel Multipart HTTP/2 Streams
══════════════════════════════════════╪═══════════════════════════════════
GOOGLE CLUSTER NETWORK (High-Bandwidth Internal Backbone) │
▼
┌────────────────────────────────────────────────────────────────────────┐
│ GOOGLE CLOUD STORAGE (GCS) BUCKET │
│ - Unlimited exabyte capacity; 99.999999999% (11 9s) durability │
│ - ReadWriteMany (RWX): 10,000+ pods reading the same bucket │
└────────────────────────────────────────────────────────────────────────┘
Core Architecture Constructs
- Native GKE Integration: Unlike open-source gcsfuse hacks that required privileged containers and manual
/dev/fusedevice mounting, the GKE GCS FUSE CSI driver is managed by Google SREs, fully compliant with GKE Autopilot, and runs without root privileges. - ReadWriteMany (RWX) Semantics: Thousands of pods across distinct nodes and availability zones can simultaneously mount the exact same GCS bucket with read/write access.
- Local File Caching: Modern GCS FUSE embeds high-speed local caching. Pods can allocate memory or local NVMe SSD storage as a fast read cache. When an AI training epoch repeatedly iterates over the same 500 GB dataset, subsequent epochs read directly from local NVMe cache at tens of gigabytes per second instead of re-fetching from GCS.
2. POSIX Compatibility Realities & Limitations
While GCS FUSE presents objects as files and folders, Cloud Storage remains an object store, not a block device:
- Fast Sequential Reads: Reading large continuous files (e.g., PyTorch
.ptor Safetensors model weights) approaches wire-speed line rate. - Append and Random Writes: Overwriting the middle of an existing file is not supported. Writing to a file uploads the object sequentially via multipart upload; changes only become visible when
close()orfsync()completes. - Directory Emulation: Object stores have flat key hierarchies. Folders are emulated using delimiter forward slashes (
/). Renaming a folder containing 100,000 objects is not an atomic operation—it issues 100,000 individual copy and delete API calls.
3. Production Deployment & CLI Operations (gcloud & kubectl)
1. Enable GCS FUSE CSI Driver on GKE Cluster
# Enable GCS FUSE CSI driver
gcloud container clusters update prod-regional-cluster \
--region=us-central1 \
--update-addons=GcsFuseCsiDriver=ENABLED \
--project=core-infrastructure-prod2. Configure Workload Identity IAM Binding for GCS Bucket
# Create dedicated GCP Service Account
gcloud iam service-accounts create gke-gcs-reader-sa \
--project=core-infrastructure-prod
# Grant read access to target AI dataset bucket
gcloud storage buckets add-iam-policy-binding gs://ai-training-datasets-prod \
--member="serviceAccount:gke-gcs-reader-sa@core-infrastructure-prod.iam.gserviceaccount.com" \
--role="roles/storage.objectViewer"
# Bind Kubernetes ServiceAccount to GCP ServiceAccount
gcloud iam service-accounts add-iam-policy-binding \
gke-gcs-reader-sa@core-infrastructure-prod.iam.gserviceaccount.com \
--role="roles/iam.workloadIdentityUser" \
--member="serviceAccount:core-infrastructure-prod.svc.id.goog[ai-training/model-training-ksa]"3. Deploy Kubernetes ServiceAccount and StorageClass
Create gcs-fuse-ksa.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: model-training-ksa
namespace: ai-training
annotations:
iam.gke.io/gcp-service-account: gke-gcs-reader-sa@core-infrastructure-prod.iam.gserviceaccount.com4. Deploy AI Training Pod with GCS FUSE Volume & Local SSD Caching
Create pytorch-training-job.yaml:
apiVersion: v1
kind: Pod
metadata:
name: pytorch-training-worker
namespace: ai-training
annotations:
# 1. Enable GCS FUSE sidecar injection
gke-gcsfuse/volumes: "true"
gke-gcsfuse/cpu-limit: "2"
gke-gcsfuse/memory-limit: "8Gi"
spec:
serviceAccountName: model-training-ksa
containers:
- name: trainer
image: us-central1-docker.pkg.dev/core-infrastructure-prod/ai/pytorch-trainer:v2.1
command: ["python3", "train.py", "--data-dir=/datasets/imagenet"]
resources:
requests:
cpu: "8"
memory: "32Gi"
volumeMounts:
- name: gcs-dataset-volume
mountPath: /datasets/imagenet
readOnly: true
volumes:
- name: gcs-dataset-volume
csi:
driver: gcsfuse.csi.storage.gke.io
readOnly: true
volumeAttributes:
bucketName: ai-training-datasets-prod
mountOptions: "implicit-dirs,file-cache:max-size-mb:50000,file-cache:cache-file-for-range-read:true,metadata-cache:stat-cache-max-size-mb:1000,metadata-cache:ttl-secs:3600"Apply manifest:
kubectl apply -f pytorch-training-job.yaml
# Verify sidecar injection and mount
kubectl get pod pytorch-training-worker -n ai-training4. Quotas, Performance, and Configuration Limits
| Parameter / Dimension | Limit / Performance Characteristic | Engineering Guidance |
|---|---|---|
| Max Concurrent Readers | Practically unlimited | Scales to thousands of pods reading simultaneously |
| Sequential Read Throughput | Up to 10+ Gbps per node | Depends on node VM network bandwidth |
| File Cache Capacity | Bounded by node disk / memory | Use attached Local NVMe SSD for multi-TB caches |
| Max Single File Size | 5 TiB (GCS platform limit) | Supports massive model checkpoints |
| Directory Listing Latency | High for 100k+ flat files | Organize datasets into hierarchical subdirectories |
| Autopilot Support | Fully supported out-of-the-box | Zero manual /dev/fuse setup required |
5. Official References & Documentation
- GKE Cloud Storage FUSE CSI Driver Overview
- How to Mount GCS Buckets using GCS FUSE CSI
- GCS FUSE Performance Optimization & Caching Guide
- Open Source gcsfuse Documentation
- Google Cloud Storage Pricing
6. Realistic Pricing Scenarios
Pricing components:
- GCS FUSE CSI Driver: $0.00 platform charge.
- Cloud Storage Standard: $0.020 per GB-month.
- Cloud Storage API Calls: Class A (Writes/Lists): 0.004 per 10,000 ops.
- Internal Network Transfer: Free within the same GCP region.
Scenario A: Distributed AI Training on ImageNet (10 TB Dataset)
- Architecture:
- 10 TB training dataset stored in a regional GCS bucket (
us-central1). - 16 GPU worker pods across 4 nodes training continuously for 5 days (120 hours).
- Local SSD caching enabled: Objects downloaded once, subsequent reads served from local cache.
- Class B Read Operations: 5,000,000 reads during initial epoch.
- 10 TB training dataset stored in a regional GCS bucket (
- Monthly Cost Calculation:
- Storage: 10,000 GB × 200.00**
- Class B API Operations: (5{,}000{,}000 / 10{,}000) \times \0.004 = \mathbf{$2.00}$
- Intra-Region Network Bandwidth: $0.00
- Total Monthly Cost: **1,700.00/month, yielding an 88% cost reduction)._
Scenario B: Massive Document OCR & NLP Pipeline (100 TB Cold Storage)
- Architecture:
- 100 TB PDF document archive stored in GCS Nearline ($0.010/GB-month).
- 50 batch processor pods running nightly OCR jobs reading 5 TB of new documents per month.
- Class B Read Operations: 20 million reads.
- Monthly Cost Calculation:
- Storage (Nearline): 100,000 GB × 1,000.00**
- Data Retrieval Fee (5 TB): 5,000 GB × 50.00**
- Class B API Operations: (20{,}000{,}000 / 10{,}000) \times \0.004 = \mathbf{$8.00}$
- Total Monthly Cost: $1,058.00 / month
7. Battle-Tested Nuggets & Production Gotchas
- The Million Small Files Metadata Storm: If your dataset consists of millions of individual 10 KB JPEG images in a single flat directory, querying
lsor opening files triggers a massive flood of GCS HTTP metadata list calls. In-cluster training throughput collapses to kilobytes per second. Always pack small training samples into structured container formats (such as TFRecord, WebDataset tar shards, or Parquet files of 100 MB - 1 GB each) before mounting via GCS FUSE. - Missing
gke-gcsfuse/volumes: "true"Annotation Fails Silently: The GCS FUSE CSI driver relies on a mutating admission webhook to inject thegcsfuse-sidecarcontainer into your pod. If you configure the volume in your pod spec but forget to add the annotationgke-gcsfuse/volumes: "true"undermetadata.annotations, the sidecar will not be injected, and the pod will fail to mount the directory withMountVolume.SetUp failed for volume: connection refused. - Cross-Region Network Egress Invoices: If your GKE cluster resides in
us-central1and your GCS bucket resides inus-east1or multi-regionus, every gigabyte of training data read by your pods will incur cross-region networking egress fees (0.04 per GB). A 50 TB training job across regions will add 2,000 in hidden networking charges. Always ensure the GCS bucket is strictly co-located in the exact same GCP region as your GKE cluster. - Local File Cache Eviction Thrashing: When enabling
file-cache:max-size-mb, if the cache capacity is smaller than the dataset being scanned in a single training epoch, the local cache continuously writes and purges blocks (cache thrashing), burning local SSD write endurance and increasing CPU usage. Size the local cache to be of the active working set, or rely on streaming sequential reads without local file caching. - No File Locking (
flock) Support: Cloud Storage does not support POSIX file advisory locks (fcntl/flock). Applications (such as SQLite or older file-based lock daemons) that require file-level concurrency locking will fail immediately withOperation not supported. Do not attempt to run relational databases directly on top of GCS FUSE. - Workload Identity Service Account Token Lifetime: GCS FUSE uses background token refreshers to maintain long-lived GCS access. If your pod’s ServiceAccount IAM binding is deleted or modified while an active 48-hour training job is executing, subsequent file reads will fail mid-run with
401 Unauthorized: token expired. Guard Workload Identity IAM policies against uncoordinated terraform applies.
Across the wiki
- Amazon S3 — object storage (AWS)
- Azure Blob Storage & Data Lake Storage Gen2 — object storage (Azure)
- Mountpoint for Amazon S3 CSI Driver — object storage (Kubernetes)