609 lines
30 KiB
Markdown
609 lines
30 KiB
Markdown
|
|
# 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 <pvc-name>
|
||
|
|
|
||
|
|
# Check storage classes
|
||
|
|
kubectl get storageclass
|
||
|
|
|
||
|
|
# Monitor disk usage in pods
|
||
|
|
kubectl exec <pod-name> -- 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 <pvc-name>
|
||
|
|
```
|
||
|
|
|
||
|
|
2. **Check storage usage**:
|
||
|
|
```bash
|
||
|
|
kubectl exec -it <pod-name> -- 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
|