16.5.3 StorageClass与动态供给
StorageClass用于定义存储类型与动态供给策略,配合PVC实现按需创建PV,避免手工管理存储资源。其核心价值在于将“存储能力”抽象为类,并通过存储驱动自动完成卷创建、删除与扩容。
原理草图(动态供给流程):
动态供给流程要点:
- 用户创建PVC并指定storageClassName
- 控制器匹配StorageClass并调用对应Provisioner
- Provisioner创建底层存储并生成PV
- PVC与PV自动绑定,Pod挂载使用
- 资源回收策略根据reclaimPolicy执行
关键字段说明(含命令解释要点):
- provisioner:存储驱动标识,如nfs.csi.k8s.io、rbd.csi.ceph.com
- parameters:驱动参数(存储池、性能级别、文件系统类型等)
- reclaimPolicy:Delete或Retain,决定PVC删除后的PV处理
- volumeBindingMode:Immediate或WaitForFirstConsumer,影响绑定时机
- allowVolumeExpansion:是否允许在线扩容
- mountOptions:挂载参数,如noatime、vers=4.1
安装与准备(以NFS CSI为例):
1) 安装NFS CSI驱动(示例使用官方repo)
# 1) 部署NFS CSI驱动
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/deploy/install-driver.sh
# 2) 查看驱动组件状态
kubectl -n kube-system get pods -l app=csi-nfs-controller
kubectl -n kube-system get pods -l app=csi-nfs-node
预期效果:controller与node插件均为Running。
2) 准备NFS服务器(示例路径)
# 在NFS服务器上
sudo mkdir -p /srv/nfs/k8s
echo "/srv/nfs/k8s *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
sudo exportfs -rav
StorageClass与PVC完整示例(含挂载验证):
# 文件: sc-nfs.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: sc-nfs
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: nfs.csi.k8s.io
parameters:
server: 10.0.0.10
share: /srv/nfs/k8s
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
mountOptions:
- vers=4.1
- noatime
# 文件: pvc-nfs.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs-demo
spec:
accessModes: ["ReadWriteMany"]
storageClassName: sc-nfs
resources:
requests:
storage: 5Gi
# 文件: pod-nfs.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-nfs-demo
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh","-c","echo hello > /data/hello.txt; sleep 3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: pvc-nfs-demo
# 应用配置
kubectl apply -f sc-nfs.yaml
kubectl apply -f pvc-nfs.yaml
kubectl apply -f pod-nfs.yaml
# 验证PVC与PV绑定
kubectl get pvc pvc-nfs-demo
kubectl get pv
# 验证Pod写入数据
kubectl exec pod-nfs-demo -- cat /data/hello.txt
预期效果:PVC状态为Bound,Pod内输出hello。
扩容示例(含命令解释):
# 1) 扩容PVC
kubectl patch pvc pvc-nfs-demo -p '{"spec":{"resources":{"requests":{"storage":"10Gi"}}}}'
# 2) 查看扩容状态
kubectl get pvc pvc-nfs-demo
kubectl describe pvc pvc-nfs-demo | grep -E "FileSystemResizePending|Capacity"
说明:
- 若显示FileSystemResizePending,需在Pod内执行文件系统扩容(不同FS命令不同)。
- 对ext4通常在容器/节点执行:resize2fs;对xfs执行:xfs_growfs。
运维与生产注意事项(含命令检查):
- 为不同性能等级创建多个StorageClass并标注默认类
bash
kubectl get sc
kubectl patch sc sc-nfs -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
- 设置volumeBindingMode=WaitForFirstConsumer以避免跨可用区绑定问题
- 明确reclaimPolicy,防止删除PVC导致数据丢失
bash
kubectl get pv -o wide
- 启用allowVolumeExpansion并配合文件系统扩容流程
- 对CSI驱动进行版本管理与兼容性验证
bash
kubectl -n kube-system get pods -l app=csi-nfs-controller -o wide
常见问题与排查(含命令解释):
1) PVC长期Pending
# 检查StorageClass是否存在
kubectl get sc
# 查看PVC事件
kubectl describe pvc pvc-nfs-demo
# 检查CSI控制器日志
kubectl -n kube-system logs -l app=csi-nfs-controller --tail=100
2) PV创建失败
# 查看控制器日志和事件
kubectl -n kube-system logs -l app=csi-nfs-controller --tail=200
kubectl get events --sort-by=.lastTimestamp | tail -n 20
3) 绑定到错误可用区
# 确认volumeBindingMode设置
kubectl get sc sc-nfs -o yaml | grep volumeBindingMode -n
# 查看节点拓扑标签
kubectl get nodes -L topology.kubernetes.io/zone
4) 扩容不生效
# 确认驱动支持
kubectl describe sc sc-nfs | grep allowVolumeExpansion
# 查看PVC条件
kubectl describe pvc pvc-nfs-demo | grep -E "Resize|FileSystem"
5) 回收异常
# 检查reclaimPolicy与PV状态
kubectl get pv -o wide
练习(动手验证):
1) 创建两个StorageClass:sc-nfs-fast与sc-nfs-standard,分别设置不同mountOptions并对比Pod中IO延迟。
2) 将reclaimPolicy从Retain改为Delete,删除PVC后观察PV与底层目录是否保留。
3) 使用WaitForFirstConsumer创建PVC,在Pod调度后确认PV绑定的节点与zone一致。
4) 扩容PVC至10Gi,并在Pod内完成文件系统扩容,验证df -h结果。