Appearance
GKE Storage Guide
Complete guide to persistent storage in Google Kubernetes Engine (GKE), including PersistentVolumes, PersistentVolumeClaims, StorageClasses, and StatefulSets.
Storage Overview
Key Storage Concepts
| Concept | Description |
|---|---|
| PersistentVolume (PV) | Storage resource provisioned in the cluster |
| PersistentVolumeClaim (PVC) | Request for storage by a Pod |
| StorageClass | Template for dynamic volume provisioning |
| CSI Driver | Container Storage Interface plugin |
| StatefulSet | Workload 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-rwoUse 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-pvcStorageClasses
Default StorageClasses in GKE
| StorageClass | Disk Type | Use Case |
|---|---|---|
| standard-rwo | pd-balanced | General purpose (default) |
| premium-rwo | pd-ssd | High IOPS workloads |
| standard | pd-standard | Cost-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: trueStorageClass Parameters
| Parameter | Description |
|---|---|
| provisioner | CSI driver (pd.csi.storage.gke.io) |
| type | Disk type (pd-balanced, pd-ssd, pd-standard) |
| fstype | Filesystem type (ext4, xfs) |
| volumeBindingMode | When to provision (Immediate, WaitForFirstConsumer) |
| reclaimPolicy | What happens on PVC delete (Delete, Retain) |
| allowVolumeExpansion | Allow online volume resize |
Access Modes
| Access Mode | Description | Supported By |
|---|---|---|
| ReadWriteOnce (RWO) | Single node read-write | Persistent Disk |
| ReadOnlyMany (ROX) | Multi-node read-only | Persistent Disk |
| ReadWriteMany (RWX) | Multi-node read-write | Filestore, Cloud Storage FUSE |
| ReadWriteOncePod (RWOP) | Single Pod read-write | Persistent 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: WaitForFirstConsumerRegional PD Benefits
| Benefit | Description |
|---|---|
| High Availability | Survives single zone failure |
| Auto Failover | GKE reschedules Pods to healthy zone |
| RPO = 0 | Synchronous 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: 10GiStatefulSet vs Deployment
| Feature | StatefulSet | Deployment |
|---|---|---|
| Pod naming | Ordered (pod-0, pod-1) | Random suffix |
| Storage | Unique PVC per Pod | Shared PVC |
| Scaling | Ordered (0,1,2...) | Parallel |
| Updates | Rolling, ordered | Rolling, parallel |
| Use case | Databases, queues | Stateless apps |
Reclaim Policies
What happens to storage when PVC is deleted.
| Policy | Behavior |
|---|---|
| Delete | PV and disk deleted with PVC (default) |
| Retain | PV 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 deletionVolume 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: trueFilestore PVC
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-storage
spec:
accessModes:
- ReadWriteMany
storageClassName: filestore
resources:
requests:
storage: 1Ti # Minimum for standard tierVolume 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-pvcRestore 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.ioBest Practices
Storage Selection Guide
| Recommendation | Description |
|---|---|
| Use WaitForFirstConsumer | Provision in same zone as Pod |
| Set resource requests | Always specify storage size |
| Use StatefulSets | For stateful applications |
| Enable volume expansion | Allow growth without recreation |
| Use Retain for production | Prevent accidental data loss |
| Backup with snapshots | Regular 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 volumeattachmentTroubleshooting
| Issue | Solution |
|---|---|
| PVC Pending | Check StorageClass exists, quota available |
| Pod stuck ContainerCreating | PVC not bound, check events |
| Mount failed | Check node zone matches disk zone |
| Resize not working | StorageClass needs allowVolumeExpansion |
Last updated: December 2025