Skip to content

GKE Storage Guide

Complete guide to persistent storage in Google Kubernetes Engine (GKE), including PersistentVolumes, PersistentVolumeClaims, StorageClasses, and StatefulSets.

Storage Overview

Key Storage Concepts

ConceptDescription
PersistentVolume (PV)Storage resource provisioned in the cluster
PersistentVolumeClaim (PVC)Request for storage by a Pod
StorageClassTemplate for dynamic volume provisioning
CSI DriverContainer Storage Interface plugin
StatefulSetWorkload controller with stable storage

PersistentVolumes and Claims

How Dynamic Provisioning Works

Create a PersistentVolumeClaim

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 30Gi
  storageClassName: standard-rwo

Use PVC in a Pod

yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - mountPath: /data
      name: my-volume
  volumes:
  - name: my-volume
    persistentVolumeClaim:
      claimName: my-pvc

StorageClasses

Default StorageClasses in GKE

StorageClassDisk TypeUse Case
standard-rwopd-balancedGeneral purpose (default)
premium-rwopd-ssdHigh IOPS workloads
standardpd-standardCost-effective, sequential I/O

Custom StorageClass

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd
  csi.storage.k8s.io/fstype: ext4
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
allowVolumeExpansion: true

StorageClass Parameters

ParameterDescription
provisionerCSI driver (pd.csi.storage.gke.io)
typeDisk type (pd-balanced, pd-ssd, pd-standard)
fstypeFilesystem type (ext4, xfs)
volumeBindingModeWhen to provision (Immediate, WaitForFirstConsumer)
reclaimPolicyWhat happens on PVC delete (Delete, Retain)
allowVolumeExpansionAllow online volume resize

Access Modes

Access ModeDescriptionSupported By
ReadWriteOnce (RWO)Single node read-writePersistent Disk
ReadOnlyMany (ROX)Multi-node read-onlyPersistent Disk
ReadWriteMany (RWX)Multi-node read-writeFilestore, Cloud Storage FUSE
ReadWriteOncePod (RWOP)Single Pod read-writePersistent Disk

Regional Persistent Disks

High availability storage with synchronous replication across two zones.

Regional PD StorageClass

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: regional-pd
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd
  replication-type: regional-pd
volumeBindingMode: WaitForFirstConsumer

Regional PD Benefits

BenefitDescription
High AvailabilitySurvives single zone failure
Auto FailoverGKE reschedules Pods to healthy zone
RPO = 0Synchronous replication, no data loss

StatefulSets

StatefulSets are the recommended way to deploy stateful applications.

StatefulSet Example

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: web-headless
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: data
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: standard-rwo
      resources:
        requests:
          storage: 10Gi

StatefulSet vs Deployment

FeatureStatefulSetDeployment
Pod namingOrdered (pod-0, pod-1)Random suffix
StorageUnique PVC per PodShared PVC
ScalingOrdered (0,1,2...)Parallel
UpdatesRolling, orderedRolling, parallel
Use caseDatabases, queuesStateless apps

Reclaim Policies

What happens to storage when PVC is deleted.

PolicyBehavior
DeletePV and disk deleted with PVC (default)
RetainPV released, disk kept for manual recovery

Protect Important Data

yaml
# StorageClass with Retain policy
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: retain-storage
provisioner: pd.csi.storage.gke.io
reclaimPolicy: Retain  # Keep data after PVC deletion

Volume Expansion

Expand volumes without downtime.

Expand a Volume

bash
# Edit PVC to increase size
kubectl patch pvc my-pvc -p '{"spec":{"resources":{"requests":{"storage":"50Gi"}}}}'

Requirements:

  • StorageClass must have allowVolumeExpansion: true
  • Can only increase size, not decrease
  • Filesystem resize happens when Pod remounts

Filestore (NFS)

For ReadWriteMany access across multiple Pods.

Filestore StorageClass

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: filestore
provisioner: filestore.csi.storage.gke.io
parameters:
  tier: standard
  network: default
volumeBindingMode: Immediate
allowVolumeExpansion: true

Filestore PVC

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared-storage
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: filestore
  resources:
    requests:
      storage: 1Ti  # Minimum for standard tier

Volume Snapshots

Point-in-time backup of persistent volumes.

Create a Snapshot

yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: my-snapshot
spec:
  volumeSnapshotClassName: csi-pd-snapshot-class
  source:
    persistentVolumeClaimName: my-pvc

Restore from Snapshot

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: restored-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard-rwo
  resources:
    requests:
      storage: 30Gi
  dataSource:
    name: my-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io

Best Practices

Storage Selection Guide

RecommendationDescription
Use WaitForFirstConsumerProvision in same zone as Pod
Set resource requestsAlways specify storage size
Use StatefulSetsFor stateful applications
Enable volume expansionAllow growth without recreation
Use Retain for productionPrevent accidental data loss
Backup with snapshotsRegular point-in-time backups

Quick Reference

Common Commands

bash
# List storage classes
kubectl get storageclass

# List PVCs
kubectl get pvc -A

# List PVs
kubectl get pv

# Describe PVC
kubectl describe pvc my-pvc

# Check volume attachment
kubectl get volumeattachment

Troubleshooting

IssueSolution
PVC PendingCheck StorageClass exists, quota available
Pod stuck ContainerCreatingPVC not bound, check events
Mount failedCheck node zone matches disk zone
Resize not workingStorageClass needs allowVolumeExpansion

Last updated: December 2025

Built with VitePress & Mermaid diagrams