Storage Configuration

This guide covers storage configuration options for StackGres clusters, including volume sizing, storage classes, and advanced security settings.

Persistent Volume Configuration

Every SGCluster requires persistent storage for PostgreSQL data. Configure storage in the spec.pods.persistentVolume section:

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: my-cluster
spec:
  pods:
    persistentVolume:
      size: '50Gi'
      storageClass: 'fast-ssd'

Required Settings

Setting Description
size Volume size (e.g., 10Gi, 100Gi, 1Ti)

Optional Settings

Setting Description Default
storageClass Kubernetes StorageClass name Cluster default
fsGroupChangePolicy Volume permission policy OnRootMismatch

Storage Size

Specify volume size using Kubernetes quantity format:

spec:
  pods:
    persistentVolume:
      size: '100Gi'  # 100 Gibibytes

Supported units:

  • Mi - Mebibytes (1024 KiB)
  • Gi - Gibibytes (1024 MiB)
  • Ti - Tebibytes (1024 GiB)

Sizing Guidelines

Workload Recommended Size Notes
Development 10-50Gi Minimal testing
Small production 50-200Gi Light workloads
Medium production 200Gi-1Ti Standard workloads
Large production 1Ti+ Heavy workloads, analytics

Consider:

  • Current data size plus growth projections
  • WAL files (typically 10-20% of total)
  • Temporary files for operations
  • Backup staging area

Storage Class

The storage class determines the underlying storage technology:

spec:
  pods:
    persistentVolume:
      size: '100Gi'
      storageClass: 'premium-ssd'

Common Storage Classes

Cloud Providers:

# AWS EBS (gp3)
storageClass: 'gp3'

# GCP Persistent Disk (SSD)
storageClass: 'premium-rwo'

# Azure Managed Disk (Premium SSD)
storageClass: 'managed-premium'

On-premises:

# Local NVMe storage
storageClass: 'local-nvme'

# Ceph RBD
storageClass: 'rook-ceph-block'

# OpenEBS
storageClass: 'openebs-cstor-sparse'

Storage Class Requirements

For PostgreSQL workloads, storage classes should support:

  • ReadWriteOnce access mode
  • Volume expansion (for online resizing)
  • Snapshot capability (for backups)
  • High IOPS for transaction logs

fsGroupChangePolicy

The fsGroupChangePolicy setting controls how Kubernetes handles file ownership when mounting volumes. This affects pod startup time and security.

spec:
  pods:
    persistentVolume:
      size: '100Gi'
      fsGroupChangePolicy: 'OnRootMismatch'

Available Policies

Policy Description Use Case
OnRootMismatch Only change ownership if root directory permissions don’t match Recommended - Faster startup, minimal overhead
Always Always recursively change ownership on mount Strict security, slower startup

The default and recommended setting. Kubernetes only changes file ownership if the root directory of the volume has incorrect permissions:

fsGroupChangePolicy: 'OnRootMismatch'

Benefits:

  • Fast pod startup (no recursive permission scan)
  • Reduced I/O during mounting
  • Suitable for most production workloads

Always

Forces Kubernetes to recursively change ownership of all files every time the volume is mounted:

fsGroupChangePolicy: 'Always'

Use when:

  • Strict security compliance is required
  • Volume contents may have mixed ownership
  • After restoring data from external sources

Warning: With large data volumes, Always can significantly increase pod startup time.

Performance Impact

Volume Size OnRootMismatch Startup Always Startup
10Gi ~1 second 1-5 seconds
100Gi ~1 second 10-60 seconds
1Ti ~1 second 1-10 minutes

The difference becomes significant with large volumes or many small files.

Volume Expansion

If your storage class supports expansion, you can increase volume size:

Step 1: Update Cluster Spec

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: my-cluster
spec:
  pods:
    persistentVolume:
      size: '200Gi'  # Increased from 100Gi

Step 2: Apply and Wait

kubectl apply -f cluster.yaml

# Monitor PVC status
kubectl get pvc -l stackgres.io/cluster-name=my-cluster -w

Note: Volume expansion may require a pod restart depending on the storage provider.

Storage for Different Components

Data Volume

The primary data volume for PostgreSQL:

spec:
  pods:
    persistentVolume:
      size: '100Gi'

Distributed Logs Storage

Separate storage for distributed logs:

apiVersion: stackgres.io/v1
kind: SGDistributedLogs
metadata:
  name: logs-cluster
spec:
  persistentVolume:
    size: '50Gi'
    storageClass: 'standard'

Sharded Cluster Storage

Configure storage per shard type:

apiVersion: stackgres.io/v1
kind: SGShardedCluster
metadata:
  name: sharded-cluster
spec:
  coordinator:
    pods:
      persistentVolume:
        size: '50Gi'
  shards:
    pods:
      persistentVolume:
        size: '100Gi'  # Each shard gets this size

Example Configurations

Development Environment

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: dev-cluster
spec:
  instances: 1
  postgres:
    version: '16'
  pods:
    persistentVolume:
      size: '10Gi'

Production Environment

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: prod-cluster
spec:
  instances: 3
  postgres:
    version: '16'
  pods:
    persistentVolume:
      size: '500Gi'
      storageClass: 'premium-ssd'
      fsGroupChangePolicy: 'OnRootMismatch'

High-Security Environment

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: secure-cluster
spec:
  instances: 3
  postgres:
    version: '16'
  pods:
    persistentVolume:
      size: '200Gi'
      storageClass: 'encrypted-ssd'
      fsGroupChangePolicy: 'Always'  # Strict ownership enforcement