StorageClass 与动态存储
CKA 考试 Domain 4 — StorageClass 定义、动态 PV 供给、CSI 驱动、默认 StorageClass
← 返回 CKA 练习目录 StorageClass 为管理员提供了一种描述存储"类"的方法,实现动态 PV 供给,避免管理员手动预置 PV。
1. StorageClass 定义与 provisioner
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
encrypted: "true"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: Immediate
核心字段:
| 字段 | 说明 |
|---|---|
provisioner | 存储后端驱动名称 |
parameters | 传递给 provisioner 的参数 |
reclaimPolicy | 动态 PV 的回收策略(Delete 或 Retain) |
allowVolumeExpansion | 是否允许 PVC 扩容 |
volumeBindingMode | 绑定模式(Immediate 或 WaitForFirstConsumer) |
mountOptions | 挂载选项 |
2. 动态 PV 供给原理
- 用户创建 PVC(指定
storageClassName: fast) - Kubernetes 控制平面找到对应的 StorageClass
- 调用 StorageClass 的 provisioner 创建存储资源
- 自动创建 PV 并绑定到 PVC
- Pod 使用 PVC 挂载存储
User (PVC) ──► StorageClass ──► Provisioner ──► 实际存储 ──► PV
3. 默认 StorageClass
设置默认 StorageClass 后,创建 PVC 时不指定 storageClassName 会自动使用默认 StorageClass。
# 查看当前默认 StorageClass
kubectl get storageclass
# 将某个 StorageClass 设为默认
kubectl patch storageclass standard -p \
'{"metadata": {"annotations": {"storageclass.kubernetes.io/is-default-class": "true"}}}'
metadata:
annotations:
storageclass.kubernetes.io/is-default-class: "true"
注意:PVC 中
storageClassName: ""表示不使用默认 StorageClass,而是使用静态 PV。
4. 常用 Provisioner
AWS EBS
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: aws-ebs-gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3
fsType: ext4
encrypted: "true"
iopsPerGB: "10"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
GCE PD
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gce-pd-ssd
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-ssd
replication-type: none
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
Azure Disk
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azure-disk
provisioner: disk.csi.azure.com
parameters:
skuname: Premium_LRS
cachingMode: ReadOnly
reclaimPolicy: Delete
allowVolumeExpansion: true
NFS(通过 CSI)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:
server: nfs-server.example.com
share: /exports
reclaimPolicy: Delete
volumeBindingMode: Immediate
mountOptions:
- hard
- nfsvers=4.1
5. volumeBindingMode
| 模式 | 说明 |
|---|---|
Immediate | 创建 PVC 后立即创建 PV 并绑定 |
WaitForFirstConsumer | 等到第一个 Pod 使用 PVC 时才创建 PV(可感知 Pod 调度节点的 AZ) |
WaitForFirstConsumer 常用于多云/多可用区环境,确保 PV 创建在与 Pod 相同的可用区。
6. volumeBindingMode 绑定模式对比
# 延迟绑定:PV 会创建在 Pod 调度到的节点所在 AZ
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: regional-ssd
provisioner: pd.csi.storage.gke.io
volumeBindingMode: WaitForFirstConsumer
7. CSI 驱动的概念与使用
CSI(Container Storage Interface)是 Kubernetes 推荐的存储插件机制。
优势:
- 插件无需编译进 Kubernetes 二进制文件
- 通过 DaemonSet 部署,热插拔
- 支持快照、扩容、克隆等高级功能
# 查看已安装的 CSI 驱动
kubectl get csidriver
# 查看 CSI 节点状态
kubectl get csinodes
8. 实用命令
# 查看所有 StorageClass
kubectl get sc
kubectl get storageclass
# 查看 StorageClass 详情
kubectl describe sc <storage-class-name>
# 创建 StorageClass(X YAML)
kubectl create -f sc.yaml
# 删除 StorageClass
kubectl delete sc <storage-class-name>
# 检查默认 StorageClass
kubectl get sc -o jsonpath='{.items[*].metadata.annotations.storageclass\.kubernetes\.io/is-default-class}'
9. 考试要点
- PVC 不指定
storageClassName= 使用默认 StorageClass - PVC 指定
storageClassName: ""= 使用静态 PV(手动创建) WaitForFirstConsumer在拓扑感知环境中非常重要- 动态 PV 的
reclaimPolicy默认为Delete - CSI 是目前官方推荐的存储扩展方式
🧪 完整操作实例:使用 StorageClass 动态创建 PV
场景描述
定义一个 StorageClass 并使用其自动创建 PV,观察动态供给的完整流程以及回收策略(Delete)的效果。
前置条件
- 集群中需要有 CSI 驱动的 provisioner(如
ebs.csi.aws.com、pd.csi.storage.gke.io等) - 如果使用 minikube,启用
standardStorageClass 即可;以下示例使用本地standard作为模拟
操作步骤
Step 1: 查看集群中已有的 StorageClass
kubectl get sc
# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
# standard (default) k8s.io/minikube-hostpath Delete Immediate false 15d
Step 2: 创建自定义 StorageClass
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-storage
provisioner: k8s.io/minikube-hostpath
parameters:
type: pd-ssd
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
EOF
kubectl get sc
# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
# fast-storage k8s.io/minikube-hostpath Delete Immediate true 5s
# standard (default) k8s.io/minikube-hostpath Delete Immediate false 15d
Step 3: 创建 PVC 引用该 StorageClass
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: fast-storage
EOF
Step 4: 观察 PV 被动态创建
kubectl get pvc
# NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
# dynamic-pvc Bound pvc-8f3b2c1d-... 1Gi RWO fast-storage 10s
kubectl get pv
# NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS AGE
# pvc-8f3b2c1d-... 1Gi RWO Delete Bound default/dynamic-pvc fast-storage 10s
PV 的名称是动态生成的 UUID 格式,RECLAIM POLICY 自动继承 StorageClass 的 Delete。
Step 5: 查看动态 PV 的详细信息
kubectl describe pv pvc-8f3b2c1d-...
# ...
# Source:
# Type: HostPath (bare host directory volume)
# Path: /data/hostpath-provisioner/default/dynamic-pvc
# ...
# Reclaim Policy: Delete
# StorageClass: fast-storage
Step 6: 删除 PVC 观察 PV 自动删除
kubectl delete pvc dynamic-pvc
kubectl get pvc
# No resources found in default namespace.
kubectl get pv
# (之前动态创建的 PV 已被自动删除,不显示)
由于 reclaimPolicy: Delete,PVC 删除后关联的 PV 会被自动删除,无需手动干预。
验证结果
# 验证 StorageClass 是否成功创建
kubectl get sc fast-storage -o jsonpath='{.provisioner}'
# k8s.io/minikube-hostpath
# 验证 PVC 引用的是正确的 StorageClass
kubectl get pvc dynamic-pvc -o jsonpath='{.spec.storageClassName}'
# fast-storage
# 验证动态 PV 的回收策略
kubectl get pv -o jsonpath='{.items[0].spec.persistentVolumeReclaimPolicy}'
# Delete
考试提示
- PVC 不指定
storageClassName会使用集群默认的 StorageClass - PVC 指定
storageClassName: ""表示使用静态 PV,不启用动态供给 - 动态 PV 的回收策略默认为
Delete,如果希望保留数据应改为Retain WaitForFirstConsumer模式下 PVC 创建后 STATUS 仍为Pending,直到第一个 Pod 使用它- 考试中如果出现动态供给场景,记得检查
StorageClass的 provisioner 是否匹配