1. Introduction to StorageClass
1.1 What is StorageClass
StorageClass is a resource object in Kubernetes used to describe storage types and policies. It provides administrators with a way to describe "classes" of storage they offer. Different classes may map to different quality-of-service levels, backup policies, or arbitrary policies set by the cluster admin.
1.2 Core Functions of StorageClass
- Dynamic Volume Provisioning: Automatically creates PVs, no need for manual pre-provisioning
- Storage Abstraction: Provides users with a unified storage access interface, hiding backend details
- Policy Management: Defines reclaim policies, mount options, etc.
- Multi-backend Support: Supports different storage systems (NFS, cloud storage, local storage, etc.)
1.3 Relationship with PV/PVC
User creates PVC → specifies StorageClass → Provisioner dynamically creates PV → PVC binds PV → Pod uses storage2. Core Components of StorageClass
2.1 Provisioner
The Provisioner is responsible for dynamically creating PVs. Common types include:
Built-in Provisioners:
kubernetes.io/aws-ebs(AWS EBS)kubernetes.io/gce-pd(Google Cloud Persistent Disk)kubernetes.io/azure-disk(Azure Disk)
External Provisioners:
k8s-sigs.io/nfs-subdir-external-provisioner(NFS)csi.driver.name(CSI driver)
2.2 Parameters
Defines specific configuration parameters for storage. Supported parameters vary by provisioner.
2.3 ReclaimPolicy
Delete: Default. PV and backend storage are deleted when PVC is deletedRetain: PV and data are retained, manual cleanup required
2.4 VolumeBindingMode
Immediate: Bind immediately (default)WaitForFirstConsumer: Wait until the first consumer (Pod) is scheduled before binding
3. NFS StorageClass Lab Environment Setup
3.1 Prerequisites
This lab requires:
- Kubernetes cluster (v1.18+)
- NFS server (IP: 10.128.0.5)
- NFS shared directory:
/nfs/share
3.2 NFS Server Configuration
On the NFS server, run:
dnf install nfs-utils rpcbind
mkdir -p /nfs/share
chown nobody:nobody /nfs/share
chmod 755 /nfs/share
echo "/nfs/share *(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
systemctl enable --now rpcbind
systemctl enable --now nfs-server
exportfs -ra
showmount -e localhost3.3 Kubernetes Node Configuration
On all Kubernetes nodes, install the NFS client:
dnf install nfs-utils
apt-get update && apt-get install -y nfs-common
showmount -e 10.128.0.54. Deploy NFS External Provisioner
4.1 Create Namespace
kubectl create namespace nfs-storageclass4.2 Deploy RBAC Permissions
Create serviceAccount.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: nfs-storageclass
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: nfs-storageclass
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: nfs-storageclass
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: nfs-storageclass
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: nfs-storageclass
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io4.3 Deploy NFS Provisioner
Create nfs-client.yaml:
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
namespace: nfs-storageclass
spec:
replicas: 1
selector:
matchLabels:
app: nfs-client-provisioner
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: k8s.dockerproxy.com/sig-storage/nfs-subdir-external-provisioner:v4.0.2
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 10.140.0.8 # NFS server IP
- name: NFS_PATH
value: /nfs/share # NFS share path
volumes:
- name: nfs-client-root
nfs:
server: 10.140.0.8
path: /nfs/share4.4 Create StorageClass
Create storageClass.yaml:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
namespace: nfs-storageclass
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
pathPattern: ${.PVC.namespace}/${.PVC.name}
onDelete: deleteParameter Explanation:
pathPattern: Defines the directory path pattern created on the NFS server${.PVC.namespace}: PVC’s namespace${.PVC.name}: PVC’s name
onDelete: Behavior when PVC is deleteddelete: Delete the corresponding NFS directoryretain: Retain the NFS directory
5. Lab Operations
5.1 Deploy All Components
kubectl apply -f serviceAccount.yaml
kubectl apply -f nfs-client.yaml
kubectl apply -f storageClass.yaml
kubectl get pods -n nfs-storageclass
kubectl get storageclass5.2 Create Test PVC and Pod
Create pod.yaml:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim
spec:
accessModes:
- ReadWriteMany # Multi-node read/write
resources:
requests:
storage: 1Mi # Request 1MB storage
storageClassName: nfs-client # Specify StorageClass
---
kind: Pod
apiVersion: v1
metadata:
name: test-pod
spec:
containers:
- name: test-pod
image: wangyanglinux/myapp:v1.0 # Nginx image
volumeMounts:
- name: nfs-pvc
mountPath: "/usr/share/nginx/html" # Mount to Nginx web root
restartPolicy: "Never"
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-claim5.3 Run the Test
kubectl apply -f pod.yaml
kubectl get pvc test-claim
kubectl get pv
kubectl get pods test-pod -o wide
ls -la /nfs/share/default/test-claim/5.4 Verify Storage Functionality
POD_IP=$(kubectl get pod test-pod -o jsonpath='{.status.podIP}')
curl $POD_IP
kubectl exec -it test-pod -- /bin/bash
echo "Hello from NFS StorageClass!" > /usr/share/nginx/html/index.html
exit
curl $POD_IP
cat /nfs/share/default/test-claim/index.html6. Advanced Features
6.1 Set Default StorageClass
kubectl patch storageclass nfs-client -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
kubectl get storageclass6.2 Volume Binding Mode
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client-wait
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
volumeBindingMode: WaitForFirstConsumer # Wait for first consumer
parameters:
pathPattern: ${.PVC.namespace}/${.PVC.name}
onDelete: delete6.3 Mount Options
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client-custom
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
mountOptions:
- hard # Hard mount
- nfsvers=4 # Use NFSv4
- timeo=600 # Timeout
parameters:
pathPattern: ${.PVC.namespace}/${.PVC.name}
onDelete: retain # Retain data7. Troubleshooting and Maintenance
7.1 Common Issue Diagnosis
kubectl logs -n nfs-storageclass deployment/nfs-client-provisioner
kubectl describe pvc test-claim
kubectl describe storageclass nfs-client
kubectl exec -it test-pod -- df -h
journalctl -u nfs-server -f7.2 Performance Optimization Suggestions
NFS Mount Option Optimization:
yamlmountOptions: - vers=4.1 - rsize=1048576 - wsize=1048576 - hard - timeo=600 - retrans=2Network Optimization:
- Use gigabit or 10-gigabit networks
- Configure dedicated NFS network
- Adjust MTU size
Storage Optimization:
- Use SSD storage
- Configure RAID
- Regularly back up important data
7.3 Clean Up Resources
kubectl delete -f pod.yaml
kubectl delete -f storageClass.yaml
kubectl delete -f nfs-client.yaml
kubectl delete -f serviceAccount.yaml
kubectl delete namespace nfs-storageclass8. Lab Summary
Through this lab, we learned:
- Basic concepts of StorageClass: Understanding its role and core components
- Dynamic volume provisioning: How to automatically create PVs via StorageClass
- NFS integration: How to integrate NFS storage into Kubernetes
- Practical application: Validated the StorageClass workflow through a complete lab
Key Points
- StorageClass simplifies storage management and enables dynamic provisioning
- The Provisioner is the core of StorageClass, responsible for actual storage creation
- Different storage backends require different provisioners and parameter configs
- Proper storage policy configuration is critical for production
Production Advice
- Security: Configure proper RBAC and network policies
- High Availability: Deploy multiple Provisioner replicas, configure storage HA
- Monitoring: Set up comprehensive storage monitoring and alerting
- Backup: Develop data backup and recovery strategies
- Testing: Regularly perform disaster recovery tests