StorageClass 动态存储
想象一个场景:你需要为 100 个开发人员每人创建一个持久化存储。
手动创建 PV?不可能。 预先创建大量 PV?浪费资源。
StorageClass 的动态卷供应机制,让这一切变得简单。
为什么需要 StorageClass?
传统存储管理的问题
在没有 StorageClass 的时代,存储管理需要:
- 管理员手动创建 PV:每个存储请求都需要管理员介入
- 预先准备大量 PV:无法预测用户需要多少存储
- 存储与 Pod 耦合:Pod 必须知道具体的 PV 名称
StorageClass 的解决方案
StorageClass 实现了动态卷供应:
- 用户创建 PVC 指定 StorageClass
- StorageClass 的 Provisioner 自动创建 PV
- PVC 与 PV 自动绑定
StorageClass 详解
基本结构
storageclass-basic.yaml
核心字段
云存储 StorageClass
AWS EBS
storageclass-aws.yaml
GCE Persistent Disk
storageclass-gce.yaml
Azure Disk
storageclass-azure.yaml
网络存储 StorageClass
NFS
storageclass-nfs.yaml
CephFS (CSI)
storageclass-cephfs.yaml
MinIO / Longhorn (本地存储)
storageclass-longhorn.yaml
默认 StorageClass
设置默认 StorageClass
使用默认 StorageClass
创建 PVC 时可以不指定 storageClassName,会使用默认的:
pvc-default-sc.yaml
Tip
建议明确指定 storageClassName,而不是依赖默认 StorageClass。明确的配置更容易维护和迁移。
回收策略
Delete vs Retain
storageclass-retain.yaml
Retain 后的数据恢复
卷扩展
启用扩展
在线扩展
从 Kubernetes 1.24 开始,支持在线扩展(不需要重启 Pod):
CSI 卷扩展限制
某些 CSI 驱动可能不支持在线扩展或某些文件系统:
拓扑感知调度
WaitForFirstConsumer
WaitForFirstConsumer 模式会延迟 PV 的绑定,直到 Pod 被调度:
Tip
WaitForFirstConsumer 避免了跨可用区存储带来的延迟和成本。建议生产环境使用此模式。
拓扑限制
某些存储只能在特定拓扑中使用:
storageclass-topology.yaml
存储配额
资源配额
storage-quota.yaml
常见问题
StorageClass 创建失败
检查 Provisioner 是否正确安装:
PVC 无法绑定
常见原因:
- 没有匹配的 StorageClass
- 拓扑限制不满足(节点不在允许的可用区)
- 存储配额不足
- PVC 请求的容量超过 PV 可用容量
卷扩展失败
最佳实践
生产环境建议
- 使用
WaitForFirstConsumer:避免跨可用区访问 - 启用卷扩展:方便后期扩容
- 使用
Retain策略:重要数据不要自动删除 - 明确指定 StorageClass:不要依赖默认
- 配置合适的副本数:根据数据重要性选择
多环境配置
storageclass-prod.yaml
延伸思考
StorageClass 将存储管理从手动操作变成了自动化流程:
- 按需供应:用户无需等待管理员创建存储
- 资源优化:只创建实际需要的存储
- 环境一致性:不同环境可以使用相同的配置
但 StorageClass 也带来了一些挑战:
- 存储选型复杂:需要根据业务需求选择合适的存储类型
- 成本管理:动态供应可能导致存储快速增长
- 数据安全:删除 PVC 时数据是否真的被删除?
建议生产环境建立存储监控和成本控制机制,避免存储资源的无序增长。
延伸阅读
- Volume 与 PVC/PV:存储基础概念
- StatefulSet 有状态应用:有状态应用的存储管理
- CSI 插件对比:不同 CSI 驱动的特点