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

  1. Native GKE Integration: Unlike open-source gcsfuse hacks that required privileged containers and manual /dev/fuse device mounting, the GKE GCS FUSE CSI driver is managed by Google SREs, fully compliant with GKE Autopilot, and runs without root privileges.
  2. ReadWriteMany (RWX) Semantics: Thousands of pods across distinct nodes and availability zones can simultaneously mount the exact same GCS bucket with read/write access.
  3. 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 .pt or 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() or fsync() 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-prod

2. 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.com

4. 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-training

4. Quotas, Performance, and Configuration Limits

Parameter / DimensionLimit / Performance CharacteristicEngineering Guidance
Max Concurrent ReadersPractically unlimitedScales to thousands of pods reading simultaneously
Sequential Read ThroughputUp to 10+ Gbps per nodeDepends on node VM network bandwidth
File Cache CapacityBounded by node disk / memoryUse attached Local NVMe SSD for multi-TB caches
Max Single File Size5 TiB (GCS platform limit)Supports massive model checkpoints
Directory Listing LatencyHigh for 100k+ flat filesOrganize datasets into hierarchical subdirectories
Autopilot SupportFully supported out-of-the-boxZero manual /dev/fuse setup required

5. Official References & Documentation


6. Realistic Pricing Scenarios

Pricing components:

  1. GCS FUSE CSI Driver: $0.00 platform charge.
  2. Cloud Storage Standard: $0.020 per GB-month.
  3. Cloud Storage API Calls: Class A (Writes/Lists): 0.004 per 10,000 ops.
  4. 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.
  • 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

  1. The Million Small Files Metadata Storm: If your dataset consists of millions of individual 10 KB JPEG images in a single flat directory, querying ls or 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.
  2. Missing gke-gcsfuse/volumes: "true" Annotation Fails Silently: The GCS FUSE CSI driver relies on a mutating admission webhook to inject the gcsfuse-sidecar container into your pod. If you configure the volume in your pod spec but forget to add the annotation gke-gcsfuse/volumes: "true" under metadata.annotations, the sidecar will not be injected, and the pod will fail to mount the directory with MountVolume.SetUp failed for volume: connection refused.
  3. Cross-Region Network Egress Invoices: If your GKE cluster resides in us-central1 and your GCS bucket resides in us-east1 or multi-region us, 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.
  4. 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.
  5. 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 with Operation not supported. Do not attempt to run relational databases directly on top of GCS FUSE.
  6. 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