动态供给
学习目标
理解动态供给的工作原理
掌握动态供给的配置方法
对比静态供给和动态供给的优劣
核心概念
静态 vs 动态供给
静态供给(手动):
┌───────────┐ ┌───────────┐ ┌───────────┐
│ 管理员 │ │ PVC │ │ Pod │
│ 创建 PV │───►│ 绑定 PV │───►│ 使用 PVC │
└───────────┘ └───────────┘ └───────────┘
工作量大,需要管理员预先规划存储
动态供给(自动):
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ Storage │ │ PVC │ │ Provisioner│ │ Pod │
│ Class │◄───│ 引用 SC │───►│ 创建 PV │───►│ 使用 PVC │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
自动化,按需创建
动态供给流程
1. 管理员创建 StorageClass
┌────────────────────────────┐
│ StorageClass: fast │
│ provisioner: ebs.csi.aws.com│
│ parameters: type: gp3 │
└────────────────────────────┘
2. 用户创建 PVC(指定 StorageClass)
┌────────────────────────────┐
│ PVC: my-pvc │
│ storageClassName: fast │
│ storage: 10Gi │
└────────────────────────────┘
3. Provisioner 自动创建 PV
┌────────────────────────────┐
│ PV: pvc-xxxx(自动生成) │
│ capacity: 10Gi │
│ 调用云 API 创建磁盘 │
└────────────────────────────┘
4. PV 与 PVC 自动绑定
5. Pod 使用 PVC
完整示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: ebs.csi.aws.com
parameters:
type: gp3
fsType: ext4
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- mountPath: /data
name: my-storage
volumes:
- name: my-storage
persistentVolumeClaim:
claimName: my-pvc
复制 + 追加到编辑器
动态供给的优势
方面 静态供给 动态供给 管理员工作 手动创建 PV 只需定义 StorageClass 响应速度 需要等待 自动创建 规模 需要预规划 按需扩展 错误风险 可能配错 由 Provisioner 保证 适用场景 特殊需求 大多数场景
WaitForFirstConsumer 模式
为什么需要 WaitForFirstConsumer?
问题(Immediate 模式):
PVC 创建 → PV 在 Zone A 创建
│
▼
Pod 调度到 Zone B → 无法访问 Zone A 的 PV ❌
解决(WaitForFirstConsumer 模式):
PVC 创建 → 等待
│
▼
Pod 调度到 Zone A → PV 在 Zone A 创建 → 绑定成功 ✓
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: regional
provisioner: kubernetes.io/aws-ebs
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
复制 + 追加到编辑器
多 StorageClass 场景
不同应用需要不同存储:
StorageClass: ssd-fast
├── provisioner: ebs.csi.aws.com
├── parameters: type: io2
└── 适用:数据库、高 IOPS 应用
StorageClass: hdd-standard
├── provisioner: ebs.csi.aws.com
├── parameters: type: st1
└── 适用:日志、归档数据
StorageClass: shared-fs
├── provisioner: efs.csi.aws.com
└── 适用:多 Pod 共享文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-pvc
spec:
storageClassName: ssd-fast
resources:
requests:
storage: 100Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: log-pvc
spec:
storageClassName: hdd-standard
resources:
requests:
storage: 500Gi
复制 + 追加到编辑器
常用 CSI Driver
Driver 说明 存储类型 ebs.csi.aws.com AWS EBS 块存储 RWO efs.csi.aws.com AWS EFS 文件存储 RWX pd.csi.storage.gke.io GCP Persistent Disk RWO file.csi.azure.com Azure Files RWX disk.csi.azure.com Azure Disk RWO cephfs.csi.ceph.com CephFS RWX rbd.csi.ceph.com Ceph RBD RWO
实践练习
练习 1:查看集群的 StorageClass
kubectl get sc
kubectl describe sc
kubectl get sc -o json | jq '.items[] | select(.metadata.annotations["storageclass.kubernetes.io/is-default-class"]=="true")'
复制 + 追加到编辑器
练习 2:动态创建存储
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
EOF
kubectl get pv,pvc -w
复制 + 追加到编辑器
练习 3:对比静态和动态
kubectl apply -f static-pv.yaml
kubectl apply -f static-pvc.yaml
kubectl apply -f dynamic-pvc.yaml
kubectl get pv
复制 + 追加到编辑器
常见误解
1. 动态供给不需要 StorageClass
错误:PVC 不指定 StorageClass 就能动态创建
正确:必须有 StorageClass 才能动态供给
不指定 storageClassName 会使用默认 StorageClass(如果存在)
2. 动态创建的 PV 可以手动删除
动态创建的 PV 由 Provisioner 管理
手动删除 PV 可能导致底层存储未清理
应该通过删除 PVC 来触发清理
小结
要点 说明 动态供给 PV 由系统自动创建 前提 需要 StorageClass 和 Provisioner 流程 PVC → StorageClass → Provisioner → PV 绑定模式 WaitForFirstConsumer 避免跨区问题 最佳实践 生产环境优先使用动态供给