# PVC Deep Dive Guide: Understanding Persistent Storage in Kubernetes ## 🎯 **Overview** This guide explains **Persistent Volume Claims (PVCs)** in detail, why they're essential, and how your current Kubernetes setup uses them. PVCs are crucial for applications that need to store data that survives pod restarts, crashes, or migrations. --- ## πŸ“Š **How PVCs Work: Visual Explanation** ### **πŸ”„ PVC Lifecycle Flow** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PVC LIFECYCLE β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ DEVELOPER β”‚ β”‚ PVC β”‚ β”‚ PV β”‚ β”‚ STORAGE β”‚ β”‚ β”‚ β”‚ Creates β”‚ β”‚ Requests β”‚ β”‚ Provides β”‚ β”‚ Backend β”‚ β”‚ β”‚ β”‚ PVC β”‚ β”‚ Storage β”‚ β”‚ Storage β”‚ β”‚ (Azure) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ 1. Create PVC β”‚ β”‚ β”‚ β”‚ β”‚ │───────────────▢│ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ 2. Find PV β”‚ β”‚ β”‚ β”‚ β”‚ │───────────────▢│ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ 3. Provision β”‚ β”‚ β”‚ β”‚ β”‚ │───────────────▢│ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ 4. Create Disk β”‚ β”‚ β”‚ β”‚ β”‚ │◀───────────────│ β”‚ β”‚ β”‚ β”‚ 5. Bind PV β”‚ β”‚ β”‚ β”‚ β”‚ │◀───────────────│ β”‚ β”‚ β”‚ β”‚ 6. Bind PVC β”‚ β”‚ β”‚ β”‚ β”‚ │◀───────────────│ β”‚ β”‚ β”‚ β”‚ 7. Ready β”‚ β”‚ β”‚ β”‚ β”‚ │◀───────────────│ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### **πŸ—οΈ Storage Architecture** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ STORAGE ARCHITECTURE β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ KUBERNETES CLUSTER β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ POD 1 β”‚ β”‚ POD 2 β”‚ β”‚ POD 3 β”‚ β”‚ POD 4 β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Volume β”‚ β”‚ β”‚ β”‚ Volume β”‚ β”‚ β”‚ β”‚ Volume β”‚ β”‚ β”‚ β”‚ Volume β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Mount β”‚ β”‚ β”‚ β”‚ Mount β”‚ β”‚ β”‚ β”‚ Mount β”‚ β”‚ β”‚ β”‚ Mount β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ PVCs β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ PVC: gitea β”‚ β”‚ PVC: mongo β”‚ β”‚ PVC: logs β”‚ β”‚ PVC: jenkinsβ”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ 15Gi β”‚ β”‚ 8Gi β”‚ β”‚ 1Gi β”‚ β”‚ 50Gi β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ RWO β”‚ β”‚ RWO β”‚ β”‚ RWO β”‚ β”‚ RWO β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ PVs β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ PV: gitea β”‚ β”‚ PV: mongo β”‚ β”‚ PV: logs β”‚ β”‚ PV: jenkins β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ 15Gi β”‚ β”‚ 8Gi β”‚ β”‚ 1Gi β”‚ β”‚ 50Gi β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ azure-disk β”‚ β”‚ azure-disk β”‚ β”‚ azure-disk β”‚ β”‚ azure-disk β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ AZURE STORAGE BACKEND β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ Managed Diskβ”‚ β”‚ Managed Diskβ”‚ β”‚ Managed Diskβ”‚ β”‚ Managed Diskβ”‚ β”‚ β”‚ β”‚ β”‚ β”‚ 15Gi SSD β”‚ β”‚ 8Gi SSD β”‚ β”‚ 1Gi SSD β”‚ β”‚ 50Gi SSD β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Premium β”‚ β”‚ Premium β”‚ β”‚ Standard β”‚ β”‚ Standard β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- ## πŸ€” **Why Each Pod Needs PVC: The Data Persistence Problem** ### **❌ Without PVC: Data Loss Scenario** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ WITHOUT PVC (BAD) β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ POD 1 β”‚ β”‚ POD 2 β”‚ β”‚ POD 3 β”‚ β”‚ POD 4 β”‚ β”‚ β”‚ β”‚ nginx:latestβ”‚ β”‚ nginx:latestβ”‚ β”‚ nginx:latestβ”‚ β”‚ nginx:latestβ”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ /tmp β”‚ β”‚ β”‚ β”‚ /tmp β”‚ β”‚ β”‚ β”‚ /tmp β”‚ β”‚ β”‚ β”‚ /tmp β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ (temp) β”‚ β”‚ β”‚ β”‚ (temp) β”‚ β”‚ β”‚ β”‚ (temp) β”‚ β”‚ β”‚ β”‚ (temp) β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ πŸ”„ Pod Restart/Delete β†’ ❌ ALL DATA LOST β”‚ β”‚ β”‚ β”‚ ❌ User uploads gone β”‚ β”‚ ❌ Database files gone β”‚ β”‚ ❌ Configuration gone β”‚ β”‚ ❌ Logs gone β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### **βœ… With PVC: Data Persistence** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ WITH PVC (GOOD) β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ POD 1 β”‚ β”‚ POD 2 β”‚ β”‚ POD 3 β”‚ β”‚ POD 4 β”‚ β”‚ β”‚ β”‚ nginx:latestβ”‚ β”‚ nginx:latestβ”‚ β”‚ nginx:latestβ”‚ β”‚ nginx:latestβ”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ /data β”‚ β”‚ β”‚ β”‚ /data β”‚ β”‚ β”‚ β”‚ /data β”‚ β”‚ β”‚ β”‚ /data β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ (PVC) β”‚ β”‚ β”‚ β”‚ (PVC) β”‚ β”‚ β”‚ β”‚ (PVC) β”‚ β”‚ β”‚ β”‚ (PVC) β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ SHARED STORAGE β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ πŸ“ /data β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ πŸ“„ user-uploads/ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ πŸ“„ database/ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ πŸ“„ config/ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── πŸ“„ logs/ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ πŸ”„ Pod Restart/Delete β†’ βœ… DATA PERSISTS β”‚ β”‚ β”‚ β”‚ βœ… User uploads preserved β”‚ β”‚ βœ… Database files preserved β”‚ β”‚ βœ… Configuration preserved β”‚ β”‚ βœ… Logs preserved β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- ## 🏭 **Your Current Kubernetes Setup: PVC Analysis** ### **πŸ“Š Your Actual PVC Usage** Based on your codebase analysis, here's how PVCs are currently used: #### **1. Gitea (Git Repository)** ```yaml # 🏭 ACTUAL CONFIGURATION FROM YOUR CODEBASE # freeleaps-ops/freeleaps/helm-pkg/3rd/gitea/values.prod.yaml persistence: enabled: true create: true mount: true claimName: gitea-shared-storage size: 15Gi accessModes: - ReadWriteOnce storageClass: azure-disk-std-lrs annotations: helm.sh/resource-policy: keep ``` **What this means:** - βœ… **Gitea uses PVC** for storing repositories, user data, and configuration - βœ… **15GB storage** allocated for Git repositories and user data - βœ… **Azure Standard Disk** (cost-effective for this use case) - βœ… **ReadWriteOnce** - only one pod can access at a time - βœ… **Data persists** when Gitea pod restarts #### **2. MongoDB (Database)** ```yaml # 🏭 ACTUAL CONFIGURATION FROM YOUR CODEBASE # freeleaps-ops/freeleaps/helm-pkg/3rd/mongo/values.yaml persistence: enabled: true size: 8Gi accessModes: - ReadWriteOnce storageClass: "" # Uses default Azure storage class ``` **What this means:** - βœ… **MongoDB uses PVC** for database files - βœ… **8GB storage** for database data - βœ… **Data persists** when MongoDB pod restarts - βœ… **Critical for data integrity** #### **3. Jenkins (CI/CD)** ```yaml # 🏭 ACTUAL CONFIGURATION FROM YOUR CODEBASE # freeleaps-ops/cluster/manifests/freeleaps-devops-system/jenkins/values.yaml persistence: enabled: true storageClass: azure-blob-fuse-2-std-lrs accessMode: "ReadWriteOnce" size: "50Gi" ``` **What this means:** - βœ… **Jenkins uses PVC** for build artifacts, workspace data - βœ… **50GB storage** for build history and artifacts - βœ… **Azure Blob Storage** (cost-effective for large files) - βœ… **Build history preserved** across pod restarts #### **4. Central Storage (Logs)** ```yaml # 🏭 ACTUAL CONFIGURATION FROM YOUR CODEBASE # freeleaps-ops/freeleaps/helm-pkg/centralStorage/templates/central-storage/pvc.yaml persistence: enabled: true size: 1Gi accessModes: - ReadWriteOnce ``` **What this means:** - βœ… **Central storage uses PVC** for log ingestion - βœ… **1GB storage** for log processing - βœ… **Logs preserved** during processing ### **πŸ“‹ PVC Usage Summary** | Application | PVC Name | Size | Storage Class | Purpose | Critical? | |-------------|----------|------|---------------|---------|-----------| | **Gitea** | `gitea-shared-storage` | 15Gi | `azure-disk-std-lrs` | Git repositories, user data | πŸ”΄ **Critical** | | **MongoDB** | `mongodb-datadir` | 8Gi | Default | Database files | πŸ”΄ **Critical** | | **Jenkins** | `jenkins-pvc` | 50Gi | `azure-blob-fuse-2-std-lrs` | Build artifacts, workspace | 🟑 **Important** | | **Central Storage** | `central-storage-logs-pvc` | 1Gi | Default | Log processing | 🟒 **Nice to have** | --- ## πŸ€·β€β™‚οΈ **Does Each Pod Need PVC? NO!** ### **❌ Common Misconception** **"Every pod needs a PVC"** - This is **WRONG**! ### **βœ… Reality: PVCs Are Optional** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PVC DECISION TREE β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ DOES YOUR APP NEED PERSISTENT DATA? β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ YES β”‚ β”‚ NO β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ USE β”‚ β”‚ β”‚ β”‚ DON'T β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ PVC β”‚ β”‚ β”‚ β”‚ USE β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ PVC β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Examples: β”‚ β”‚ β”‚ β”‚ β€’ Databases (PostgreSQL, MongoDB) β”‚ β”‚ β”‚ β”‚ β€’ File storage (Gitea, Jenkins) β”‚ β”‚ β”‚ β”‚ β€’ Application data (user uploads) β”‚ β”‚ β”‚ β”‚ β€’ Logs (if you want to keep them) β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Examples: β”‚ β”‚ β”‚ β”‚ β€’ Web servers (nginx, static content) β”‚ β”‚ β”‚ β”‚ β€’ API servers (stateless applications) β”‚ β”‚ β”‚ β”‚ β€’ Cache servers (Redis, Memcached) β”‚ β”‚ β”‚ β”‚ β€’ Load balancers β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### **πŸ“Š Your Current Setup Analysis** Looking at your applications: #### **βœ… Applications WITH PVCs (Need Persistent Data)** - **Gitea**: Git repositories, user data, configuration - **MongoDB**: Database files - **Jenkins**: Build artifacts, workspace data - **Central Storage**: Log processing #### **❌ Applications WITHOUT PVCs (Stateless)** - **Nginx Ingress Controller**: Stateless routing - **ArgoCD**: GitOps configuration (stored in Git) - **Cert-manager**: Certificate management (stateless) - **Prometheus/Grafana**: Metrics (can use PVC for data retention) --- ## 🎯 **PVC Considerations: When to Use Them** ### **βœ… Use PVCs When:** #### **1. Database Applications** ```yaml # Database needs persistent storage apiVersion: apps/v1 kind: Deployment metadata: name: postgres spec: template: spec: containers: - name: postgres image: postgres:13 volumeMounts: - name: db-storage mountPath: /var/lib/postgresql/data volumes: - name: db-storage persistentVolumeClaim: claimName: postgres-pvc ``` #### **2. File Storage Applications** ```yaml # File server needs persistent storage apiVersion: apps/v1 kind: Deployment metadata: name: file-server spec: template: spec: containers: - name: file-server image: nginx:latest volumeMounts: - name: file-storage mountPath: /var/www/html volumes: - name: file-storage persistentVolumeClaim: claimName: file-storage-pvc ``` #### **3. Application Data** ```yaml # Application needs to store user data apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: template: spec: containers: - name: my-app image: my-app:latest volumeMounts: - name: app-data mountPath: /app/data volumes: - name: app-data persistentVolumeClaim: claimName: app-data-pvc ``` ### **❌ Don't Use PVCs When:** #### **1. Stateless Web Servers** ```yaml # Web server doesn't need persistent storage apiVersion: apps/v1 kind: Deployment metadata: name: web-server spec: template: spec: containers: - name: web-server image: nginx:latest # No volumeMounts needed - stateless ``` #### **2. API Servers** ```yaml # API server doesn't need persistent storage apiVersion: apps/v1 kind: Deployment metadata: name: api-server spec: template: spec: containers: - name: api-server image: my-api:latest # No volumeMounts needed - stateless ``` #### **3. Cache Servers** ```yaml # Cache server doesn't need persistent storage apiVersion: apps/v1 kind: Deployment metadata: name: redis-cache spec: template: spec: containers: - name: redis image: redis:latest # No volumeMounts needed - cache is temporary ``` --- ## πŸ”§ **PVC Configuration Options** ### **1. Access Modes** ```yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: - ReadWriteOnce # Single node read/write (most common) - ReadOnlyMany # Multiple nodes read-only - ReadWriteMany # Multiple nodes read/write (rare) resources: requests: storage: 10Gi ``` ### **2. Storage Classes** ```yaml # Azure Storage Classes Available storageClass: azure-disk-std-lrs # Standard HDD (cheapest) storageClass: azure-disk-premium-lrs # Premium SSD (fastest) storageClass: azure-blob-fuse-2-std-lrs # Blob storage (for large files) ``` ### **3. Size Considerations** ```yaml # Size your PVCs appropriately resources: requests: storage: 1Gi # Small: logs, config storage: 10Gi # Medium: databases storage: 100Gi # Large: file storage, backups ``` --- ## 🚨 **Common PVC Mistakes** ### **❌ Mistake 1: Using PVC for Everything** ```yaml # ❌ DON'T DO THIS apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: template: spec: containers: - name: nginx image: nginx:latest volumeMounts: - name: temp-storage # ❌ Unnecessary PVC mountPath: /tmp volumes: - name: temp-storage persistentVolumeClaim: claimName: temp-pvc # ❌ Waste of resources ``` ### **❌ Mistake 2: Not Setting Resource Limits** ```yaml # ❌ DON'T DO THIS apiVersion: v1 kind: PersistentVolumeClaim metadata: name: unlimited-pvc spec: accessModes: - ReadWriteOnce # ❌ No size limit - could consume all storage ``` ### **βœ… Correct Approach** ```yaml # βœ… DO THIS apiVersion: v1 kind: PersistentVolumeClaim metadata: name: limited-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi # βœ… Set appropriate size ``` --- ## πŸ“š **Best Practices** ### **1. Size Appropriately** - Start small and scale up - Monitor actual usage - Use storage quotas ### **2. Choose Right Storage Class** - **Standard HDD**: Cost-effective for backups, logs - **Premium SSD**: Performance-critical databases - **Blob Storage**: Large files, archives ### **3. Use Labels and Annotations** ```yaml metadata: name: my-pvc labels: app: my-app environment: production storage-type: database annotations: helm.sh/resource-policy: keep # Don't delete on helm uninstall ``` ### **4. Monitor Usage** ```bash # Check PVC usage kubectl get pvc kubectl describe pvc # Check storage classes kubectl get storageclass # Monitor disk usage in pods kubectl exec -- df -h ``` --- ## πŸ” **Your Setup Recommendations** ### **Current State: Good!** Your current setup uses PVCs appropriately: - βœ… **Gitea**: 15Gi for repositories (appropriate) - βœ… **MongoDB**: 8Gi for database (appropriate) - βœ… **Jenkins**: 50Gi for builds (appropriate) - βœ… **Central Storage**: 1Gi for logs (appropriate) ### **Potential Improvements** 1. **Monitor usage**: Check actual disk usage in these PVCs 2. **Consider backups**: Implement PVC backup strategy 3. **Storage quotas**: Set namespace storage limits 4. **Performance tuning**: Use Premium SSD for databases if needed --- ## πŸ“– **Next Steps** 1. **Monitor your current PVCs**: ```bash kubectl get pvc --all-namespaces kubectl describe pvc ``` 2. **Check storage usage**: ```bash kubectl exec -it -- df -h ``` 3. **Learn about backup strategies**: - Azure Backup for PVCs - Velero for Kubernetes backups 4. **Consider storage optimization**: - Right-size PVCs based on actual usage - Use appropriate storage classes for cost optimization --- **Last Updated**: September 3, 2025 **Version**: 1.0 **Maintainer**: Infrastructure Team