# Configuring GKE Storage with PersistentVolumes and Cloud Storage: The Complete Guide

> Configure GKE storage using PersistentVolumes and Cloud Storage. Deploy the FUSE CSI driver, create a StorageClass and PV, then mount a PVC in your pods for GCS filesystem access.

- Repository: [Google/skills](https://github.com/google/skills)
- Tags: how-to-guide
- Published: 2026-08-09

---

**Configure GKE storage with PersistentVolumes and Cloud Storage by deploying the Cloud Storage FUSE CSI driver, creating a StorageClass and PV referencing your GCS bucket, then binding a PVC that pods mount for object storage-backed filesystem access.**

Configuring GKE storage with PersistentVolumes and Cloud Storage enables stateful workloads to leverage scalable object storage through standard Kubernetes interfaces. This approach, documented in the `google/skills` repository, uses the Cloud Storage FUSE CSI driver to present GCS buckets as filesystems without requiring block storage management. By combining **PersistentVolume (PV)** and **PersistentVolumeClaim (PVC)** resources with **Workload Identity**, you can mount Cloud Storage buckets directly into GKE pods using native Kubernetes storage semantics.

## Why Use PersistentVolumes with Cloud Storage?

When applications require data persistence across pod restarts but do not need block-level storage semantics, mounting **Google Cloud Storage (GCS)** via the **Cloud Storage FUSE CSI driver** offers significant advantages over traditional **Google Persistent Disk (PD)**. This configuration abstracts the underlying storage mechanism through a PV, allowing you to change storage providers without modifying application code while avoiding PD size limits and capacity planning constraints. According to the `google/skills` source code, the GCS FUSE driver presents buckets as regular filesystems, enabling standard file-I/O APIs with virtually unlimited scalability.

## Architecture Overview

The storage configuration relies on four core components working together within your GKE cluster. The **StorageClass** `gcsfuse-csi` tells the CSI driver how to provision volumes, while **PersistentVolume** objects reference specific GCS bucket names and storage parameters. A **PersistentVolumeClaim** binds to these PVs, and pods consume the storage through standard volume mounts. As detailed in [`/skills/cloud/gke-storage/SKILL.md`](https://github.com/google/skills/blob/main//skills/cloud/gke-storage/SKILL.md) lines 4-9, this architecture supports a flexible storage matrix that decouples workload specifications from underlying storage implementations.

## Prerequisites and Authentication

Before deploying storage resources, enable **Workload Identity** on your GKE cluster to allow pods to authenticate to Cloud Storage without static credentials. Configure your cluster's service account with the `storage.objectViewer` or appropriate IAM roles on the target bucket. The skill documentation in [`/skills/cloud/gke-storage/SKILL.md`](https://github.com/google/skills/blob/main//skills/cloud/gke-storage/SKILL.md) lines 71-73 emphasizes that this approach eliminates the need to manage service account keys within pod specifications.

## Implementation Steps

### Create the StorageClass

Define a StorageClass that references the GCS FUSE CSI provisioner to enable dynamic volume provisioning. The `google/skills` repository provides this definition in [`/skills/cloud/gke-storage/assets/gcsfuse-storageclass.yaml`](https://github.com/google/skills/blob/main//skills/cloud/gke-storage/assets/gcsfuse-storageclass.yaml):

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gcsfuse-csi
provisioner: gcsfuse.csi.google.com
reclaimPolicy: Delete
volumeBindingMode: Immediate

```

### Define the PersistentVolume

Create a PV that maps to your specific GCS bucket using the `csi` volume source. The template in `/skills/cloud/gke-storage/assets/storage-pv.yaml.tmpl` demonstrates the configuration:

```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: gcs-pv
spec:
  capacity:
    storage: 100Gi          # Size is nominal; actual capacity is the bucket size

  accessModes:
    - ReadWriteMany
  storageClassName: gcsfuse-csi
  csi:
    driver: gcsfuse.csi.google.com
    volumeHandle: my-gcs-bucket   # Replace with your bucket name

    volumeAttributes:
      bucketName: my-gcs-bucket

```

### Request Storage with a PersistentVolumeClaim

Applications request storage by creating a PVC that binds to the PV. Use the template from `/skills/cloud/gke-storage/assets/storage-pvc.yaml.tmpl`:

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gcs-pvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: gcsfuse-csi
  resources:
    requests:
      storage: 100Gi

```

### Mount the Volume in Your Pod

Reference the PVC in your pod specification to mount the Cloud Storage bucket as a local directory. The example in [`/skills/cloud/gke-storage/assets/pod-with-pvc.yaml`](https://github.com/google/skills/blob/main//skills/cloud/gke-storage/assets/pod-with-pvc.yaml) shows the implementation:

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-app
spec:
  serviceAccountName: gke-workload-identity-sa   # Ensure this SA has storage.objectViewer on the bucket

  containers:
  - name: app
    image: gcr.io/google-containers/busybox
    command: ["sleep","3600"]
    volumeMounts:
    - name: gcs-storage
      mountPath: /data
  volumes:
  - name: gcs-storage
    persistentVolumeClaim:
      claimName: gcs-pvc

```

### Configure Mount Options via Annotations

Fine-tune filesystem behavior using annotations on the pod metadata. According to [`/skills/cloud/google-cloud-storage-basics/references/gcsfuse.md`](https://github.com/google/skills/blob/main//skills/cloud/google-cloud-storage-basics/references/gcsfuse.md) lines 36-44, you can specify read-only mode, caching policies, and implicit directory handling:

```yaml
metadata:
  annotations:
    gcsfuse.cloud.google.com/mountOptions: "ro,implicit-dirs"

```

## Performance and Security Considerations

For production workloads, consider using **regional buckets** and **network-optimized node pools** to maximize throughput when using the Cloud Storage FUSE CSI driver. The driver provides high-throughput reads and writes suitable for most data processing workloads, though latency-sensitive applications may require different architectures. Always verify that your **Workload Identity** service account has the minimal necessary IAM permissions, granting only `storage.objectViewer` for read-only workloads or `storage.objectAdmin` for read-write scenarios.

## Summary

- **PersistentVolumes and Cloud Storage** combine to provide scalable, cost-effective storage for GKE stateful workloads through the Cloud Storage FUSE CSI driver.
- The configuration requires a **StorageClass** referencing `gcsfuse.csi.google.com`, a **PersistentVolume** pointing to a specific GCS bucket, and a **PersistentVolumeClaim** to bind storage to pods.
- **Workload Identity** eliminates credential management by allowing GKE service accounts to access Cloud Storage directly.
- Mount behavior is controlled through **annotations** on pod specifications, supporting options like read-only mode and implicit directories.
- All configuration templates are available in the `google/skills` repository under `/skills/cloud/gke-storage/assets/`.

## Frequently Asked Questions

### What is the difference between GKE Persistent Disk and Cloud Storage FUSE?

**Google Persistent Disk (PD)** provides block storage with consistent low latency but requires capacity planning and has size limits. **Cloud Storage FUSE** presents GCS buckets as filesystems through the CSI driver, offering virtually unlimited capacity and lower costs for large datasets, though with higher latency characteristics suitable for throughput-oriented workloads.

### How do I authenticate pods to access Cloud Storage buckets?

Configure **Workload Identity** on your GKE cluster and bind your pod's service account to a Google Cloud service account with appropriate Cloud Storage IAM roles. As implemented in the `google/skills` repository, this approach allows pods to access buckets without mounting service account keys as secrets.

### Can multiple pods access the same Cloud Storage bucket simultaneously?

Yes, by using the `ReadWriteMany` access mode in your PersistentVolume and PersistentVolumeClaim specifications, multiple pods across different nodes can mount and access the same GCS bucket concurrently. This enables shared storage scenarios for distributed processing workloads.

### What mount options are available for the GCS FUSE CSI driver?

The driver supports annotations such as `gcsfuse.cloud.google.com/mountOptions` to specify `ro` (read-only), `implicit-dirs` (automatically create directory structures), and various caching configurations. These options are documented in [`/skills/cloud/google-cloud-storage-basics/references/gcsfuse.md`](https://github.com/google/skills/blob/main//skills/cloud/google-cloud-storage-basics/references/gcsfuse.md) and allow fine-tuning of filesystem semantics for specific application requirements.