Storage Infrastructure¶
Storage architecture for Tower Fleet homelab, covering ZFS on Proxmox, NAS file sharing, and Kubernetes distributed storage.
Overview¶
Storage Layers:
1. Host Storage: ZFS on Proxmox (rpool)
2. File Storage: NFS share from NAS (LXC 101 at /vault)
3. Distributed Storage: Longhorn in Kubernetes cluster
ZFS Storage (Proxmox Host)¶
Pool: rpool
Location: Local storage on Proxmox hypervisor
Container/VM Storage¶
Each LXC container and VM gets a ZFS dataset:
# List ZFS datasets
zfs list
# Container filesystems
//rpool/data/subvol-<ID>-disk-0/
# Example
//rpool/data/subvol-150-disk-0/ # money-tracker container
//rpool/data/subvol-160-disk-0/ # home-portal container
Direct Filesystem Access¶
From Proxmox host, you can access container filesystems directly:
# Read files from money-tracker container
ls //rpool/data/subvol-150-disk-0/app
# Read config from home-portal
cat //rpool/data/subvol-160-disk-0/app/.env.local
Use Cases: - Reading logs without entering container - Backup operations - Debugging file permissions
Caution: Avoid writing directly to container filesystems while containers are running.
Storage Management¶
# Check storage usage
pvesm status
# ZFS pool status
zpool status
# Dataset usage
zfs list -o name,used,avail,refer
# Check specific container storage
zfs list | grep subvol-150
NAS File Storage (LXC 101)¶
Container: LXC 101 (NAS)
Mount Point: /vault
Protocol: NFS
IP: 10.89.97.101
Storage Structure¶
/vault/
├── media/
│ ├── tv/ # TV shows (for Plex/Jellyfin)
│ ├── movies/ # Movies
│ ├── music/ # Music library
│ └── torrents/ # Download staging
├── backups/ # Backup storage
├── documents/ # Shared documents
└── projects/ # Project files
Mounting NAS Storage¶
In LXC Containers:
Containers with NAS access have mount points configured via Proxmox:
# View container mount points
pct config 150
# Look for: mp0: /vault/subvol-101-disk-0/share,mp=/vault
# Access from container
ls /vault/media
In VMs:
VMs (like arr-stack) mount via NFS:
# arr-stack VM mounts NAS at /mnt
ssh root@10.89.97.50
df -h | grep mnt
# Shows: 10.89.97.101:/export/media on /mnt
In Kubernetes Pods:
Kubernetes doesn't currently mount NAS directly. Use Longhorn for persistent storage.
NAS Operations¶
# Check NFS exports (from Proxmox or NAS container)
pct exec 101 -- exportfs -v
# Check NAS storage usage
pct exec 101 -- df -h
# Test NFS mount from Proxmox host
showmount -e 10.89.97.101
Kubernetes Longhorn Storage¶
Purpose: Distributed block storage for Kubernetes StatefulSets Nodes: Runs on all 3 k3s nodes (201, 202, 203) Replicas: Typically 3 (for high availability)
Architecture¶
Longhorn creates replicas of volumes across cluster nodes:
Volume: postgres-data-0 (10GB)
├─ Replica 1 on k3s-master (VM 201)
├─ Replica 2 on k3s-worker-1 (VM 202)
└─ Replica 3 on k3s-worker-2 (VM 203)
If one node fails, data remains available from other replicas.
Storage Classes¶
# List storage classes
kubectl get storageclass
# Default class: longhorn
NAME PROVISIONER RECLAIMPOLICY
longhorn (default) driver.longhorn.io Delete
Persistent Volumes¶
# List all persistent volumes
kubectl get pv
# List persistent volume claims
kubectl get pvc -A
# Example: Supabase PostgreSQL
kubectl get pvc -n supabase
# Shows: postgres-data-postgres-0 Bound 10Gi longhorn
Longhorn UI¶
Access Longhorn dashboard:
# Port-forward to access UI
kubectl port-forward -n longhorn-system svc/longhorn-frontend 8080:80
# Access at: http://localhost:8080
From UI you can: - View volume health and replicas - Monitor storage usage per node - Create backups - Manage snapshots
Volume Operations¶
Create PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-app-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 5Gi
Check volume status:
# Volume details
kubectl describe pvc my-app-data
# Longhorn volume status
kubectl get volumes.longhorn.io -n longhorn-system
Backup volume:
Use Longhorn UI or create snapshot:
Storage Quotas and Limits¶
ZFS Quotas¶
# Set quota on dataset
zfs set quota=50G rpool/data/subvol-150-disk-0
# Check quota
zfs get quota rpool/data/subvol-150-disk-0
Kubernetes Resource Limits¶
Limit storage per namespace:
apiVersion: v1
kind: ResourceQuota
metadata:
name: storage-quota
namespace: my-app
spec:
hard:
persistentvolumeclaims: "5"
requests.storage: "100Gi"
Backup Strategy¶
Container Backups (LXC)¶
# Manual backup
vzdump 150 --dumpdir /var/lib/vz/dump --mode snapshot
# Restore from backup
pct restore 150 /var/lib/vz/dump/vzdump-lxc-150-*.tar.zst
NAS Backups¶
NAS data should be backed up externally (to USB drive, cloud storage, etc.)
Kubernetes Backups¶
Longhorn: Built-in backup to S3-compatible storage (optional) Velero: Backup entire namespaces/clusters (future enhancement)
# Example: Backup Supabase namespace
# (Requires Velero installation)
velero backup create supabase-backup --include-namespaces supabase
Storage Monitoring¶
Check Usage¶
# ZFS usage
zfs list -o name,used,avail,refer
# NAS usage
pct exec 101 -- df -h
# Kubernetes storage
kubectl get pv
kubectl top nodes # Includes disk usage
Alerts¶
Configure alerts for: - ZFS pool >80% full - NAS storage >90% full - Longhorn volume degraded (missing replicas)
See Observability Standards for alert configuration.
Expanding Storage¶
Add Disk to ZFS Pool¶
See Expanding Storage Guide for detailed steps.
Increase Container Storage¶
# Resize container disk (replace <CT_ID> with container ID)
pct resize <CT_ID> 0 +10G
# Verify new size
pct exec <CT_ID> -- df -h
Expand Kubernetes PVC¶
Longhorn supports volume expansion:
# Edit PVC to increase size
kubectl edit pvc my-app-data -n my-namespace
# Change: storage: 5Gi → storage: 10Gi
# Longhorn automatically expands volume
Troubleshooting¶
ZFS Issues¶
# Check pool health
zpool status
# Scrub pool (check for errors)
zpool scrub rpool
# Check scrub progress
zpool status
NFS Mount Issues¶
# From client, test NFS server
showmount -e 10.89.97.101
# Check NFS service on NAS
pct exec 101 -- systemctl status nfs-server
# Remount
umount /vault
mount -t nfs 10.89.97.101:/export/media /vault
Longhorn Volume Degraded¶
# Check Longhorn status
kubectl get volumes.longhorn.io -n longhorn-system
# Check events
kubectl get events -n longhorn-system --sort-by='.lastTimestamp'
# Restart Longhorn manager if needed
kubectl rollout restart deployment longhorn-manager -n longhorn-system
Related Documentation: - Infrastructure Overview - Expanding Storage - Storage Verification - Disaster Recovery