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结果。