# Storage Advanced

> 🔥 **Deep Dive Storage**: Panduan lengkap storage Kubernetes yang kompleks, CSI, dan advanced storage management.

***

## 📋 **Daftar Isi**

### **💾 Persistent Storage Concepts**

* [Storage Architecture Overview](#storage-architecture-overview)
* [Volume Types Comparison](#volume-types-comparison)
* [Storage Classes Deep Dive](#storage-classes-deep-dive)
* [PV/PVC Lifecycle](#pvpvc-lifecycle)
* [Storage Performance](#storage-performance)

### **🔧 Container Storage Interface (CSI)**

* [CSI Architecture](#csi-architecture)
* [Popular CSI Drivers](#popular-csi-drivers)
* [CSI Driver Installation](#csi-driver-installation)
* [CSI Configuration](#csi-configuration)
* [CSI Troubleshooting](#csi-troubleshooting)

### **🗄️ Database Storage**

* [Database Storage Best Practices](#database-storage-best-practices)
* [Performance Optimization](#performance-optimization)
* [Backup and Recovery](#backup-and-recovery)
* [High Availability](#high-availability)
* [Multi-AZ Deployments](#multi-az-deployments)

### **📊 Stateful Applications**

* [StatefulSet Deep Dive](#statefulset-deep-dive)
* [Stateful Applications Patterns](#stateful-applications-patterns)
* [Data Consistency](#data-consistency)
* [Replication Strategies](#replication-strategies)
* [Migration Techniques](#migration-techniques)

### **🚀 Storage Optimization**

* [Performance Tuning](#performance-tuning)
* [Cost Optimization](#cost-optimization)
* [Capacity Planning](#capacity-planning)
* [Monitoring and Metrics](#monitoring-and-metrics)
* [Troubleshooting Storage](#troubleshooting-storage)

***

## 💾 **Persistent Storage Concepts**

### Storage Architecture Overview

**📖 Kubernetes Storage Architecture**

```
┌─────────────────────────────────────────────────────────────┐
│                    Kubernetes Storage Architecture               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Application Pod                                             │
│  ├─ Container 1 ───┐                                      │
│  ├─ Container 2 ──┐│    VolumeMount                        │
│  └─ Volume       ──┘        │                            │
│         │                │   Volume                    │
│         ▼                ▼     │                            │
│  ┌─────────────────────────────────────────────┐           │
│  │             Persistent Volume             │           │
│  │            ┌─────────────────────┐         │           │
│  │            │  │  Storage Class   │         │           │
│  │            │  └─────────────────────┘         │           │
│  │            └─────────────────────────────┘         │
│  │                       │                           │
│  │                       ▼                           │
│  │            ┌─────────────────────┐         │
│  │            │   Storage Driver    │         │
│  │            │  (CSI/In-tree)       │         │
│  │            └─────────────────────┘         │
│  │                       │                           │
│  │                       ▼                           │
│  │            ┌─────────────────────┐         │
│  │            │  Physical Storage   │         │
│  │            │  (SAN/NAS/Cloud)     │         │
│  │            └─────────────────────┘         │
│  └─────────────────────────────────────────────────────┘
```

### Volume Types Comparison

**📋 Kubernetes Volume Types**

| Volume Type              | Use Case          | Persistence  | Performance | Dynamic Provisioning |
| ------------------------ | ----------------- | ------------ | ----------- | -------------------- |
| **hostPath**             | Local development | Node-level   | Limited     | Manual               |
| **emptyDir**             | Temporary storage | Pod-lifetime | Limited     | Manual               |
| **nfs**                  | File sharing      | Persistent   | Moderate    | Manual               |
| **iSCSI**                | Block storage     | Persistent   | Good        | Manual               |
| **cephFS**               | Distributed       | Persistent   | Good        | Manual               |
| **glusterfs**            | Distributed       | Persistent   | Good        | Manual               |
| **awsElasticBlockStore** | AWS EBS           | Persistent   | Good        | Dynamic              |
| **gcePersistentDisk**    | GCP PD            | Persistent   | Good        | Dynamic              |
| **azureDisk**            | Azure Disk        | Persistent   | Good        | Dynamic              |
| **csi:** **Custom**      | Custom            | Varies       | Varies      | Dynamic              |

### Storage Classes Deep Dive

**🔧 Storage Class Configuration**

**High-Performance Storage Class**

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: high-performance-ssd
  annotations:
    storageclass.kubernetes.io/is-default-class: "false"
    description: "High-performance SSD storage for production workloads"
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  fsType: ext4
  encrypted: "true"
  kmsKeyId: "arn:aws:kms:us-west-2:123456789012:key/12345678-1234-1234-1234-123456789012"
allowVolumeExpansion: true
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
mountOptions:
- debug
- noatime
```

**Cost-Optimized Storage Class**

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: cost-optimized-hdd
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
    description: "Cost-effective HDD storage for non-critical workloads"
provisioner: kubernetes.io/aws-ebs
parameters:
  type: sc1
  fsType: ext4
  encrypted: "true"
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate
mountOptions:
- noatime
```

**Multi-AZ Storage Class**

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: multi-az-storage
  annotations:
    description: "Multi-AZ storage for high availability workloads"
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  fsType: ext4
  encrypted: "true"
  availabilityZone: us-west-2a,us-west-2b,us-west-2c
  volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Retain
```

### PV/PVC Lifecycle

**🔄 Persistent Volume Lifecycle**

```yaml
# PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
  name: high-perf-pv
  labels:
    type: amazon-ebs
    performance: high
spec:
  capacity:
    storage: 100Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: high-performance-ssd
  awsElasticBlockStore:
    volumeID: vol-1234567890abcdef0
    fsType: ext4
    encrypted: true
    kmsKeyID: arn:aws:kms:us-west-2:123456789012:key/12345678-1234-1234-1234-123456789012

# PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: high-perf-pvc
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: high-performance-ssd
  resources:
    requests:
      storage: 50Gi
  selector:
    matchLabels:
      type: amazon-ebs
      performance: high
```

### Storage Performance

**📊 Storage Performance Metrics**

```yaml
# Performance-optimized application
apiVersion: v1
kind: Pod
metadata:
  name: storage-perf-test
spec:
  containers:
  - name: fio-test
    image: linode/fio:latest
    command:
    - /bin/sh
    - -c
    - |
      fio --name=seqwrite --filename=/data/testfile --size=1G --rw=write --bs=64K --direct=1 --numjobs=4 --runtime=60 --output-format=json --output=/data/fio-results.json
    volumeMounts:
    - name: data-volume
      mountPath: /data
  volumes:
  - name: data-volume
    persistentVolumeClaim:
      claimName: high-perf-pvc
  resources:
    requests:
      cpu: 2
      memory: 4Gi
```

***

## 🔧 **Container Storage Interface (CSI)**

### CSI Architecture

**📖 CSI Architecture Overview**

```
┌─────────────────────────────────────────────────────────────┐
│                    CSI Architecture                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Kubernetes Components                                         │
│  ├─ API Server ──┐                                         │
│  ├─ Controller Manager ──┐                                   │
│  └─ Kubelet ───────────────────────────────┐                  │
│                      │                     │                  │
│                      ▼                     │                  │
│         ┌─────────────────────────────┐    │                  │
│         │      CSI Sidecar            │    │                  │
│         │  ┌─────────────────────────┐ │    │                  │
│         │  │    CSI Driver           │ │    │                  │
│         │  │ ┌─────────────────────┐ │ │    │                  │
│         │  │ │   Storage Plugin   │ │ │    │                  │
│         │  │ │ (CSI Spec)        │ │ │    │                  │
│         │  │ └─────────────────────┘ │ │    │                  │
│         │  └─────────────────────────┘ │    │                  │
│         └─────────────────────────────┘    │                  │
│                      │                     │                  │
│                      ▼                     ▼                  │
│           ┌─────────────────────────────────┐ │                  │
│           │     Storage Backend           │ │                  │
│           │  (SAN/NAS/Cloud/Local)        │ │                  │
│           └─────────────────────────────────┘ │                  │
│                                                             │
│  CSI Components:                                             │
│  ├─ Identity Service                                     │
│  ├─ Node Service                                         │
│  ├─ Driver Registrar                                     │
│  └─ External Attacher                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

### Popular CSI Drivers

**🚀 Common CSI Drivers**

| Provider            | CSI Driver                      | Storage Types     | Use Case            |
| ------------------- | ------------------------------- | ----------------- | ------------------- |
| **AWS**             | ebs.csi.aws.com                 | EBS volumes       | AWS EKS             |
| **Google Cloud**    | pd.csi.storage.gke.io           | Persistent Disks  | GKE                 |
| **Microsoft Azure** | disk.csi.azure.com              | Azure Disk        | AKS                 |
| **Ceph**            | rbd.csi.ceph.com                | RBD volumes       | On-premises         |
| **Portworx**        | pwx.csi.portworx.com            | Portworx volumes  | On-premises         |
| **Longhorn**        | longhorn.csi.driver.longhorn.io | Longhorn volumes  | On-premises         |
| **NFS**             | nfs.csi.k8s.io                  | NFS shares        | File sharing        |
| **GlusterFS**       | glusterfs.csi.k8s.io            | GlusterFS volumes | Distributed storage |

### CSI Driver Installation

**🔧 AWS EBS CSI Installation**

```bash
# Install AWS EBS CSI driver
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/v1.14.0/docs/install-aws-ebs-csi-driver.yaml

# Apply the driver
kubectl apply -f install-aws-ebs-csi-driver.yaml

# Verify installation
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver
kubectl get csinodes
kubectl get csidrivers
```

**🔧 Custom CSI Driver Installation**

```yaml
# Custom CSI driver installation
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: custom-csi-storage
provisioner: custom-csi-driver.example.com
parameters:
  param1: "value1"
  param2: "value2"
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

---
# CSI driver configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-csi-config
  namespace: kube-system
data:
  driver-config.yaml: |
    driver:
      name: "custom-csi-driver.example.com"
      version: "v1.0.0"
    storage:
      type: "block"
      replication: "3"
      encryption: "true"
```

### CSI Configuration

**⚙️ Advanced CSI Configuration**

**Performance-Optimized CSI Configuration**

```yaml
# Storage class with performance tuning
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: high-perf-csi
  annotations:
    storageclass.kubernetes.io/is-default-class: "false"
provisioner: ebs.csi.aws.com
parameters:
  type: io2
  iops: "5000"
  throughput: "1000"
  encrypted: "true"
  fsType: ext4
  volumeBindingMode: WaitForFirstConsumer
  # Custom parameters for CSI driver
  storage.k8s.io/csi-provisioner-secret-name: "csi-secret"
  storage.k8s.io/csi-provisioner-secret-namespace: "kube-system"
allowVolumeExpansion: true
  mountOptions:
  - discard
  - noatime
  - barrier
  - data=ordered
reclaimPolicy: Retain
```

**Multi-Replica Storage Configuration**

```yaml
# Storage class with replication
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: replicated-csi
provisioner: ceph.rbd.csi.ceph.com
parameters:
  clusterID: "ceph-cluster"
  pool: "replicated-pool"
  imageFeatures: layering
  imageFormat: "2"
  adminId: "csi-rbd-node"
  adminSecretName: "ceph-secret"
  adminSecretNamespace: "kube-system"
  monitors: "10.0.0.1:6789,10.0.0.2:6789,10.0.0.3:6789"
  replication: "3"
  crdPool: "k8s-pool"
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate
```

### CSI Troubleshooting

**🔧 CSI Troubleshooting Commands**

```bash
# Check CSI driver status
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-controller

# Check CSI nodes
kubectl get csinodes
kubectl describe csinode <node-name>

# Check CSI drivers
kubectl get csidrivers
kubectl describe csidriver <driver-name>

# Check volume attachment
kubectl get volumeattachments
kubectl describe volumeattachment <attachment-name>

# Check CSI volumes
kubectl get pv -o wide
kubectl get pvc -o wide

# Debug CSI issues
kubectl describe pod <pod-with-csi-volume>
kubectl get events --field-selector type=Warning
```

***

## 🗄️ **Database Storage**

### Database Storage Best Practices

**🔧 PostgreSQL Storage Configuration**

```yaml
# PostgreSQL StatefulSet with optimized storage
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: postgres-cluster
  namespace: production
spec:
  instances: 3
  primaryUpdateStrategy: unsupervised
  postgresql:
    parameters:
      shared_buffers: "256MB"
      effective_cache_size: "768MB"
      work_mem: "4MB"
      maintenance_work_mem: "64MB"
      max_connections: "200"
      checkpoint_completion_target: "0.9"
      wal_buffers: "16MB"
      checkpoint_timeout: "15min"
      wal_compression: "on"
      default_statistics_target: "100"
      logging_collector: "pg_stat_statements"
      logging_collector_address: "/var/run/postgresql/pg_stat_statements"
      track_activities: "on"
      track_activity_query_size: "2048"
      track_counts: "on"
      track_io_timing: "on"
      track_functions: "all"
      track_functions_plans: "on"
      track_timing: "on"
      log_min_duration_statement: "1000"
      log_checkpoints: "on"
      log_connections: "on"
      log_disconnections: "on"
      log_lock_waits: "on"
      log_temp_files: "on"
      log_autovacuum_min_duration: "10s"
      autovacuum_max_workers: "3"
      autovacuum_naptime: "1min"
  bootstrap:
    initdb:
      database: production_db
      owner: production_user
      secret:
        name: postgres-credentials
  storage:
    size: 1Ti
    storageClass: high-performance-ssd
    resizeInUseVolumes: true
    pvcTemplate:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 100Gi
        limits:
          storage: 1Ti
      storageClassName: high-performance-ssd
      volumeMode: Filesystem
  monitoring:
    enabled: true
  externalClusters:
  - name: replica-cluster
    connectionParameters:
      host: replica-cluster.production.svc.cluster.local
      user: streaming_replica
      dbname: production_db
      password:
        name: postgres-replica-credentials
        key: password
```

**🔧 MySQL Storage Configuration**

```yaml
# MySQL deployment with optimized storage
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: production
spec:
  serviceName: mysql
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0.32
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        - name: MYSQL_DATABASE
          value: production_db
        - name: MYSQL_USER
          value: production_user
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        - name: MYSQL_INNODB_BUFFER_POOL_SIZE
          value: "256M"
        - name: MYSQL_INNODB_LOG_FILE_SIZE
          value: "256M"
        - name: MYSQL_INNODB_LOG_BUFFER_SIZE
          value: "16M"
        - name: MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT
          value: "2"
        - name: MYSQL_INNODB_FLUSH_METHOD
          value: "O_DIRECT"
        - name: MYSQL_INNODB_FILE_PER_TABLE
          value: "1"
        - name: MYSQL_INNODB_FILE_PER_TABLE_MAX
          value: "1"
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
        - name: mysql-config
          mountPath: /etc/mysql/conf.d
        - name: mysql-logs
          mountPath: /var/log/mysql
        livenessProbe:
          exec:
            command:
            - mysqladmin
            - ping
            - -h
            - localhost
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command:
            - mysql
            - -h
            - localhost
            - -e
            - "SELECT 1"
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: 2000m
            memory: 4Gi
      volumes:
      - name: mysql-config
        configMap:
          name: mysql-config
      - name: mysql-logs
        emptyDir: {}
  volumeClaimTemplates:
  - metadata:
      name: mysql-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: high-performance-ssd
      resources:
        requests:
          storage: 100Gi
        limits:
          storage: 1Ti
      volumeMode: Filesystem
```

### Performance Optimization

**📊 Database Performance Tuning**

**PostgreSQL Performance Metrics**

```yaml
# Prometheus rules for PostgreSQL performance
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: postgres-performance
  namespace: monitoring
spec:
  groups:
  - name: postgres-performance
    rules:
    - alert: PostgresHighCPUUsage
      expr: process_cpu_seconds_total / sum(process_start_time_seconds_total) * 100 > 80
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "PostgreSQL high CPU usage"
        description: "PostgreSQL instance {{ $labels.instance }} CPU usage is above 80%"

    - alert: PostgresHighMemoryUsage
      expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 90
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "PostgreSQL high memory usage"
        description: "PostgreSQL instance {{ $labels.instance }} memory usage is above 90%"

    - alert: PostgresSlowQueries
      expr: rate(pg_stat_statements_mean_exec_time_ms{datname="production_db"}[5m]) > 1000
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "PostgreSQL slow queries detected"
        description: "PostgreSQL slow queries detected on instance {{ $labels.instance }}"

    - alert: PostgresConnectionLimit
      expr: pg_stat_activity_count / 200 * 100 > 80
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "PostgreSQL connection limit reached"
        description: "PostgreSQL connection usage is above 80% on instance {{ $labels.instance }}"
```

### Backup and Recovery

**🔧 Database Backup Strategy**

**PostgreSQL Backup Configuration**

```yaml
# CronJob for PostgreSQL backup
apiVersion: batch/v1
kind: CronJob
metadata:
  name: postgres-backup
  namespace: production
spec:
  schedule: "0 2 * * *"  # Daily at 2 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: pgbackup
            image: postgres:13.4
            command:
            - /bin/bash
            - -c
            - |
              # Create backup directory
              mkdir -p /backup/$(date +%Y-%m-%d)

              # Run backup
              pg_dump -h localhost -U postgres production_db > /backup/$(date +%Y-%m-%d)/production_db_backup.sql

              # Compress backup
              gzip /backup/$(date +%Y-%m-%d)/production_db_backup.sql

              # Clean old backups (keep last 7 days)
              find /backup -name "*.gz" -mtime +7 -delete

              echo "Backup completed: $(date)"
            env:
            - name: PGPASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: password
            volumeMounts:
            - name: mysql-data
              mountPath: /var/lib/mysql
            - name: backup-storage
              mountPath: /backup
          volumes:
          - name: mysql-data
            persistentVolumeClaim:
              claimName: mysql-data
          - name: backup-storage
            persistentVolumeClaim:
              claimName: postgres-backup-pvc
          restartPolicy: OnFailure

# PVC for backups
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-backup-pvc
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: backup-storage
  resources:
    requests:
      storage: 100Gi
```

### High Availability

**🔄 HA Database Configuration**

**PostgreSQL Streaming Replication**

```yaml
# PostgreSQL with streaming replication
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: postgres-ha
  namespace: production
spec:
  instances: 3
  primaryUpdateStrategy: unsupervised
  postgresql:
    parameters:
      max_connections: "200"
      shared_buffers: "256MB"
      effective_cache_size: "768MB"
      wal_level: "replica"
      wal_keep_segments: "32"
      max_wal_senders: "10"
      max_replication_slots: "10"
      hot_standby = "on"
      wal_log_hints = "on"
      max_parallel_workers_per_gather = "4"
  bootstrap:
    initdb:
      database: production_db
      owner: production_user
      secret:
        name: postgres-credentials
  externalClusters:
  - name: replica-cluster
    connectionParameters:
      host: postgres-replica.production.svc.cluster.local
      user: streaming_replica
      dbname: production_db
      password:
        name: postgres-replica-credentials
        key: password
    postgresql:
      parameters:
        max_connections: "200"
        hot_standby = "on"
        wal_level: "replica"
  monitoring:
    enabled: true
  backup:
      retentionPolicy: "30d"
      barmanObjectStore:
        destinationPath: "s3://postgres-backups/production"
        s3Credentials:
          accessKeyId:
            name: backup-credentials
            key: ACCESS_KEY_ID
          secretAccessKey:
            name: backup-credentials
            key: SECRET_ACCESS_KEY
        wal:
          compression: "gzip"
          encryption: "AES256"
        data:
          compression: "gzip"
          encryption: "AES256"
          jobs: 2
```

### Multi-AZ Deployments

**🌐 Multi-AZ Storage Configuration**

```yaml
# StorageClass for multi-AZ deployment
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: multi-az-storage
  annotations:
    description: "Multi-AZ storage for high availability"
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io2
  iops: "3000"
  throughput: "125"
  fsType: ext4
  encrypted: "true"
  availabilityZone: us-west-2a,us-west-2b,us-west-2c
  volumeBindingMode: WaitForFirstConsumer
  allowVolumeExpansion: true
  allowedTopologies:
  - zone: us-west-2a
  - zone: us-west-2b
  - zone: us-west-2c
reclaimPolicy: Retain

---
# StatefulSet with anti-affinity
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres-multi-az
  namespace: production
spec:
  serviceName: postgres-multi-az
  replicas: 3
  template:
    metadata:
      labels:
        app: postgres
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - postgres
              topologyKey: "kubernetes.io/hostname"
          - weight: 50
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - postgres
              topologyKey: "topology.kubernetes.io/zone"
      containers:
      - name: postgres
        image: postgres:13.4
        ports:
        - containerPort: 5432
          name: postgres
        env:
        - name: POSTGRES_DB
          value: production_db
        - name: POSTGRES_USER
          value: postgres
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgres-secret
              key: password
        volumeMounts:
        - name: postgres-storage
          mountPath: /var/lib/postgresql
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: 2000m
            memory: 4Gi
  volumeClaimTemplates:
  - metadata:
      name: postgres-storage
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: multi-az-storage
      resources:
        requests:
          storage: 100Gi
      volumeMode: Filesystem
```

***

## 📊 **Stateful Applications**

### StatefulSet Deep Dive

**🔧 Advanced StatefulSet Configuration**

```yaml
# StatefulSet with advanced features
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: advanced-statefulset
  namespace: production
spec:
  serviceName: "advanced-statefulset"
  replicas: 3
  selector:
    matchLabels:
      app: advanced-statefulset
  template:
    metadata:
      labels:
        app: advanced-statefulset
    spec:
      terminationGracePeriodSeconds: 30
      containers:
      - name: app
        image: my-stateful-app:latest
        ports:
        - containerPort: 8080
          name: http
        - containerPort: 9090
          name: metrics
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: STATEFULSET_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['statefulset.kubernetes.io/name']
        volumeMounts:
        - name: data-volume
          mountPath: /app/data
        - name: config-volume
          mountPath: /app/config
        - name: logs-volume
          mountPath: /app/logs
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
        startupProbe:
          httpGet:
            path: /startup
            port: 8080
          failureThreshold: 30
          periodSeconds: 10
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "echo 'Shutting down gracefully...'; sleep 30"]
        resources:
          requests:
            cpu: 200m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
      - name: sidecar
        image: busybox:1.35
        command: ["/bin/sh", "-c", "while true; do echo 'Heartbeat from sidecar'; sleep 30; done"]
        volumeMounts:
        - name: data-volume
          mountPath: /app/data
      volumes:
      - name: config-volume
        configMap:
          name: app-config
      - name: logs-volume
        emptyDir: {}
  volumeClaimTemplates:
  - metadata:
      name: data-volume
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: high-performance-ssd
      resources:
        requests:
          storage: 10Gi
      volumeMode: Filesystem
  podManagementPolicy:
    orderedReady: true
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 0
  revisionHistoryLimit: 10
```

### Stateful Applications Patterns

**🔧 Common Stateful Application Patterns**

**Distributed Cache (Redis Cluster)**

```yaml
# Redis Cluster StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-cluster
  namespace: production
spec:
  serviceName: redis-cluster
  replicas: 6
  selector:
    matchLabels:
      app: redis-cluster
  template:
    metadata:
      labels:
        app: redis-cluster
    spec:
      containers:
      - name: redis
        image: redis:7-alpine
        command:
        - redis-server
        - /etc/redis/redis.conf
        - --protected-mode
        - --port 6379
        - --cluster-enabled
        - --cluster-config-file /etc/redis/cluster.conf
        - --cluster-node-timeout 5000
        - --appendonly yes
        - --replica-announce-ip $(POD_IP)
        - --replica-announce-port 6379
        - --replica-announce-bus-port 16379
        ports:
        - containerPort: 6379
          name: redis
        - containerPort: 16379
          name: gossip
        volumeMounts:
        - name: conf
          mountPath: /etc/redis
        - name: data
          mountPath: /data
        - name: logs
          mountPath: /var/log/redis
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 1Gi
      volumes:
      - name: conf
        configMap:
          name: redis-cluster-config
      - name: logs
        emptyDir: {}
      volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          accessModes: ["ReadWriteOnce"]
          storageClassName: high-performance-ssd
          resources:
            requests:
              storage: 2Gi
          volumeMode: Filesystem

# Redis Cluster ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-cluster-config
  namespace: production
data:
  redis.conf: |
    cluster-enabled yes
    cluster-config-file /etc/redis/cluster.conf
    cluster-node-timeout 5000
    appendonly yes
    save 900 1
    save 300 10
    save 60 10000
```

**Message Queue (RabbitMQ)**

```yaml
# RabbitMQ Cluster
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: rabbitmq-cluster
  namespace: production
spec:
  serviceName: rabbitmq-cluster
  replicas: 3
  selector:
    matchLabels:
      app: rabbitmq
  template:
    metadata:
      labels:
        app: rabbitmq
    spec:
      containers:
      - name: rabbitmq
        image: rabbitmq:3.9-management
        ports:
        - containerPort: 5672
          name: amqp
        - containerPort: 15672
          name: management
        env:
        - name: RABBITMQ_DEFAULT_USER
          value: admin
        - name: RABBITMQ_DEFAULT_PASS
          valueFrom:
            secretKeyRef:
              name: rabbitmq-secret
              key: password
        - name: RABBITMQ_ERLANG_COOKIE
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['app.kubernetes.io/name']
        - name: RABBITMQ_DEFAULT_VHOST
          value: /
        - name: RABBITMQ_CLUSTER_PARTITION_HANDLING_AUTO_BALANCE
          value: "true"
        - name: RABBITMQ_CLUSTER_KEEP_ALIVE_INTERVAL
          value: "60000"
        volumeMounts:
        - name: data
          mountPath: /var/lib/rabbitmq
        - name: config
          mountPath: /etc/rabbitmq
        - name: logs
          mountPath: /var/log/rabbitmq
        livenessProbe:
          exec:
            command:
            - rabbitmqctl
            - status
          initialDelaySeconds: 60
          periodSeconds: 30
        readinessProbe:
          exec:
            command:
            - rabbitmqctl
            - status
          initialDelaySeconds: 20
          periodSeconds: 10
        resources:
          requests:
            cpu: 200m
            memory: 512Mi
          limits:
            cpu: 1000m
            memory: 2Gi
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: rabbitmq-data
      - name: config
        configMap:
          name: rabbitmq-config
      - name: logs
        emptyDir: {}
  volumeClaimTemplates:
  - metadata:
      name: rabbitmq-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: high-performance-ssd
      resources:
        requests:
          storage: 10Gi
      volumeMode: Filesystem
```

### Data Consistency

**🔧 Data Consistency Strategies**

**Strong Consistency Pattern**

```yaml
# StatefulSet with leader election
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: consensus-app
  namespace: production
spec:
  serviceName: consensus-app
  replicas: 3
  template:
    metadata:
      labels:
        app: consensus-app
    spec:
      containers:
      - name: app
        image: consensus-app:latest
        ports:
        - containerPort: 8080
          name: http
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_ORDINAL
          valueFrom:
            fieldRef:
              fieldPath: metadata.annotations['apps.kubernetes.io/pod-index']
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: STATEFULSET_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['statefulset.kubernetes.io/name']
        - name: REPLICAS
          value: "3"
        volumeMounts:
        - name: data
          mountPath: /data
        - name: config
          mountPath: /app/config
        # Leader election logic in application
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "echo 'Graceful shutdown...'; /app/shutdown.sh"]
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
      volumes:
      - name: config
        configMap:
          name: consensus-config
      volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          accessModes: ["ReadWriteOnce"]
          storageClassName: high-performance-ssd
          resources:
            requests:
              storage: 5Gi
          volumeMode: Filesystem
```

### Replication Strategies

**🔄 Data Replication Configuration**

**Master-Slave Replication**

```yaml
# Master-Slave Database Configuration
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: master-slave-db
  namespace: production
spec:
  serviceName: master-slave-db
  replicas: 4
  template:
    metadata:
      labels:
        app: master-slave-db
        role: master
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  app: master-slave-db
                  role: master
              topologyKey: kubernetes.io/hostname
          - weight: 50
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  app: master-slave-db
                  role: slave
              topologyKey: kubernetes.io/hostname
      containers:
      - name: mysql
        image: mysql:8.0.32
        ports:
        - containerPort: 3306
          name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        - name: MYSQL_DATABASE
          value: production_db
        - name: MYSQL_REPLICATION_MODE
          value: "master"
        - name: MYSQL_SERVER_ID
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MYSQL_ROOT_HOST
          value: "mysql-master"
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
        - name: config
          mountPath: /etc/mysql/conf.d
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: 2000m
            memory: 4Gi
      volumes:
      - name: config
        configMap:
          name: mysql-master-config
      volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          accessModes: ["ReadWriteOnce"]
          storageClassName: high-performance-ssd
          resources:
            requests:
              storage: 20Gi
          volumeMode: Filesystem

# Slave configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-master-config
  namespace: production
data:
  master.cnf: |
    [mysqld]
    server-id = 1
    log-bin = mysql-bin
    binlog-format = ROW
    binlog-do-db = 1
    gtid-mode = ON
    enforce-gtid-consistency = ON

    # Master replication settings
    max_connections = 200
    read-only = OFF

    [mysqld_safe]
    max_allowed_packet = 64M
    innodb_buffer_pool_size = 256M
    innodb_flush_log_at_trx_commit = 1
    sync_binlog = 1

    [replication]
    # Master configuration
    server-id = 1
    log-bin = mysql-bin
    binlog-do-db = 1
    gtid-mode = ON
    enforce-gtid-consistency = ON
```

### Migration Techniques

**🔄 Data Migration Strategies**

**Blue-Green Migration**

```yaml
# Migration job for data transfer
apiVersion: batch/v1
kind: Job
metadata:
  name: data-migration
  namespace: production
spec:
  template:
    spec:
      containers:
      - name: migration-tool
        image: migration-tool:latest
        command:
        - /bin/sh
        - -c
        - |
          echo "Starting data migration..."

          # Export data from old storage
          pg_dump -h old-storage.production.svc.cluster.local -U postgres production_db > /tmp/backup.sql

          # Compress backup
          gzip /tmp/backup.sql

          # Import to new storage
          gunzip -c /tmp/backup.sql | psql -h new-storage.production.svc.cluster.local -U postgres production_db

          echo "Migration completed successfully"
        env:
        - name: PGPASSWORD
          valueFrom:
            secretKeyRef:
              name: postgres-secret
              key: password
        volumeMounts:
        - name: backup-storage
          mountPath: /tmp
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: 2000m
            memory: 4Gi
      volumes:
      - name: backup-storage
        persistentVolumeClaim:
          claimName: migration-backup-pvc
      restartPolicy: OnFailure

# PVC for migration backup
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: migration-backup-pvc
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: backup-storage
  resources:
    requests:
      storage: 50Gi
```

***

## 🚀 **Storage Optimization**

### Performance Tuning

**⚡ Storage Performance Optimization**

**I/O Optimization Settings**

```yaml
# Performance-optimized pod
apiVersion: v1
kind: Pod
metadata:
  name: performance-optimized
  namespace: production
spec:
  containers:
  - name: app
    image: my-app:latest
    resources:
      requests:
        cpu: 200m
        memory: 256Mi
      limits:
        cpu: 1000m
        memory: 512Mi
    env:
    - name: JAVA_OPTS
      value: "-Xms256m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UseStringDeduplication"
    volumeMounts:
    - name: data-volume
      mountPath: /data
    # I/O optimization settings
    securityContext:
      runAsUser: 1000
      runAsGroup: 1000
      fsGroup: 1000
    # Performance tuning
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh", "-c", "sync"]
  volumes:
  - name: data-volume
    persistentVolumeClaim:
      claimName: optimized-pvc

# Optimized PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: optimized-pvc
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: high-performance-ssd
  resources:
      requests:
        cpu: "100m"
        memory: "128Mi"
      limits:
        cpu: "500m"
        memory: "256Mi"
  volumeMode: Filesystem
```

### Cost Optimization

**💰 Cost-Effective Storage Strategies**

**Cost-Optimized Storage Classes**

```yaml
# Tiered storage classes
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: cold-storage
  annotations:
    description: "Cost-effective cold storage for infrequently accessed data"
provisioner: kubernetes.io/no-provisioner
parameters:
  type: sc1
  fsType: ext4
  encrypted: "true"
reclaimPolicy: Retain
volumeBindingMode: Immediate

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: warm-storage
  annotations:
    description: "Balanced cost/performance storage"
provisioner: kubernetes.io/aws-ebs
parameters:
  type: st1
  fsType: ext4
  encrypted: "true"
reclaimPolicy: Retain
volumeBindingMode: Immediate

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: hot-storage
  annotations:
    description: "High-performance storage for frequently accessed data"
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  fsType: ext4
  encrypted: "true"
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
```

### Capacity Planning

**📊 Capacity Planning Tools**

```yaml
# Storage monitoring dashboard
apiVersion: v1
kind: ConfigMap
metadata:
  name: storage-dashboard
  namespace: monitoring
data:
  dashboard.json: |
    {
      "dashboard": {
        "title": "Storage Capacity Planning",
        "panels": [
          {
            "title": "Storage Usage",
            "type": "stat",
            "targets": [
              {
                "expr": "kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes * 100",
                "legendFormat": "{{instance}} - {{label}}"
              }
            ]
          },
          {
            "title": "PV Utilization",
            "type": "graph",
            "targets": [
              {
                "expr": "kubelet_volume_stats_used_bytes",
                "legendFormat": "{{instance}} - {{label}}"
              }
            ]
          },
          {
            "title": "Storage Class Distribution",
            "type": "piechart",
            "targets": [
              {
                "expr": "kube_persistentvolume_info_capacity_bytes",
                "legendFormat": "{{storageclass}} - {{size}}"
              }
            ]
          }
        ]
      }
    }
```

### Monitoring and Metrics

**📊 Storage Monitoring Configuration**

**Prometheus Storage Metrics**

```yaml
# Storage monitoring ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: storage-metrics
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: storage-exporter
  endpoints:
  - port: 9100
    interval: 30s
    path: /metrics

---
# Storage exporter DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: storage-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      name: storage-exporter
  template:
    metadata:
      labels:
        name: storage-exporter
    spec:
      containers:
      - name: storage-exporter
        image: prom/node-exporter:v1.6.0
        args:
        - --path.rootfs=/host/rootfs
        - --path.sysfs=/host/sys
        - --path.proc=/host/proc
        - --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host)($|/)
        - --collector.filesystem.ignored-mount-points=^/(proc|sys|dev|host)($|/)
        - --collector.diskstats.ignored-mount-points=^/(proc|sys|dev|host)($|/)
        ports:
        - containerPort: 9100
          name: metrics
        volumeMounts:
        - name: rootfs
          mountPath: /host/rootfs
        - name: sys
          mountPath: /host/sys
        - name: proc
          mountPath: /host/proc
        hostNetwork: true
        hostPID: true
        securityContext:
          privileged: true
      hostNetwork: true
      hostPID: true
      volumes:
      - name: rootfs
        hostPath: /
      - name: sys
        hostPath: /sys
      - name: proc
        hostPath: /proc
```

### Troubleshooting Storage

**🔧 Storage Troubleshooting**

**Common Storage Issues and Solutions**

```bash
# Check storage class status
kubectl get storageclass

# Check PV/PVC status
kubectl get pv
kubectl get pvc --all-namespaces

# Check volume attachment
kubectl get volumeattachments
kubectl describe volumeattachment <attachment-name>

# Check CSI driver status
kubectl get pods -n kube-system -l app.kubernetes.io/name=csi-driver
kubectl get csinodes
kubectl describe csinode <node-name>

# Check storage metrics
kubectl describe node <node-name> | grep -A 10 "Allocated resources"

# Check Pod volume mounts
kubectl describe pod <pod-name> | grep -A 20 "Mounts"

# Test storage I/O
kubectl exec -it <pod-name> -- dd if=/dev/zero of=/tmp/testfile bs=1M count=1000

# Check storage performance
kubectl exec -it <pod-name> -- fio --name=test --filename=/data/test --size=1G --bs=4K --direct=1 --numjobs=4 --runtime=30 --output-format=json
```

***

## 🎯 **Best Practices**

### **🔧 Storage Best Practices**

1. **Planning**
   * Understand I/O requirements
   * Plan capacity growth
   * Choose appropriate storage classes
   * Consider multi-AZ requirements
2. **Performance**
   * Use appropriate storage classes
   * Monitor storage metrics
   * Optimize I/O patterns
   * Implement proper caching
3. **Backup & Recovery**
   * Implement regular backups
   * Test restore procedures
   * Use versioning for data
   * Plan for disaster recovery
4. **Security**
   * Encrypt sensitive data
   * Use appropriate access controls
   * Monitor storage access
   * Implement audit logging

### **📊 Performance Best Practices**

1. **I/O Optimization**
   * Use high-performance storage classes
   * Optimize application I/O patterns
   * Implement proper caching
   * Monitor I/O metrics
2. **Resource Management**
   * Set appropriate requests and limits
   * Use local storage for temporary data
   * Implement proper cleanup
   * Monitor resource usage
3. **Monitoring**
   * Set up comprehensive monitoring
   * Alert on storage issues
   * Track performance metrics
   * Implement log aggregation

### **🔒 Security Best Practices**

1. **Data Protection**
   * Encrypt all sensitive data
   * Use RBAC for storage access
   * Implement network policies
   * Regular security audits
2. **Backup Security**
   * Secure backup storage
   * Use encryption for backups
   * Implement access controls
   * Test restore procedures

***

## 🔗 **Referensi**

### **📚 Dokumentasi Resmi**

* [Kubernetes Storage](https://kubernetes.io/docs/concepts/storage/)
* [Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)
* [Storage Classes](https://kubernetes.io/docs/concepts/storage/storage-classes/)
* [CSI Specification](https://github.com/container-storage-interface/spec)

### **🛠️ Storage Tools**

* [Portworx](https://portworx.io/)
* [Longhorn](https://longhorn.io/)
* [Ceph](https://ceph.io/)
* [NFS Ganesha](https://github.com/kubernetes-sigs/nfs-ganesha)

### **📖 Learning Resources**

* [Kubernetes Storage Deep Dive](https://kubernetes.io/docs/concepts/storage/storage-classes/)
* [CSI Architecture](https://github.com/container-storage-interface/spec/blob/master/spec.md)
* [Database on Kubernetes](https://kubernetes.io/docs/concepts/storage/volumes/#database-storage)

***

\*💾 \**Advanced storage management is critical for production workloads requiring persistence and high availability*
