65·存储进阶

动态供给

kubernetesstoragedynamic-provisioningstorage-class

动态供给

学习目标

  1. 理解动态供给的工作原理
  2. 掌握动态供给的配置方法
  3. 对比静态供给和动态供给的优劣

核心概念

静态 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

完整示例

# 1. StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  fsType: ext4
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

---
# 2. PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast
  resources:
    requests:
      storage: 10Gi

---
# 3. Pod
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 共享文件
# 数据库 PVC(使用 SSD)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: db-pvc
spec:
  storageClassName: ssd-fast
  resources:
    requests:
      storage: 100Gi

---
# 日志 PVC(使用 HDD)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: log-pvc
spec:
  storageClassName: hdd-standard
  resources:
    requests:
      storage: 500Gi

常用 CSI Driver

Driver说明存储类型
ebs.csi.aws.comAWS EBS 块存储RWO
efs.csi.aws.comAWS EFS 文件存储RWX
pd.csi.storage.gke.ioGCP Persistent DiskRWO
file.csi.azure.comAzure FilesRWX
disk.csi.azure.comAzure DiskRWO
cephfs.csi.ceph.comCephFSRWX
rbd.csi.ceph.comCeph RBDRWO

实践练习

练习 1:查看集群的 StorageClass

# 查看可用 StorageClass
kubectl get sc

# 查看详情(含 Provisioner 和参数)
kubectl describe sc

# 查看默认 StorageClass
kubectl get sc -o json | jq '.items[] | select(.metadata.annotations["storageclass.kubernetes.io/is-default-class"]=="true")'

练习 2:动态创建存储

# 创建 PVC(不预先创建 PV)
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dynamic-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
EOF

# 观察 PV 自动创建
kubectl get pv,pvc -w

练习 3:对比静态和动态

# 静态供给
# 1. 手动创建 PV
kubectl apply -f static-pv.yaml
# 2. 创建 PVC 绑定
kubectl apply -f static-pvc.yaml

# 动态供给
# 1. 直接创建 PVC(指定 StorageClass)
kubectl apply -f dynamic-pvc.yaml
# 2. 观察 PV 自动创建
kubectl get pv

常见误解

1. 动态供给不需要 StorageClass

错误:PVC 不指定 StorageClass 就能动态创建
正确:必须有 StorageClass 才能动态供给
      不指定 storageClassName 会使用默认 StorageClass(如果存在)

2. 动态创建的 PV 可以手动删除

动态创建的 PV 由 Provisioner 管理
手动删除 PV 可能导致底层存储未清理
应该通过删除 PVC 来触发清理

小结

要点说明
动态供给PV 由系统自动创建
前提需要 StorageClass 和 Provisioner
流程PVC → StorageClass → Provisioner → PV
绑定模式WaitForFirstConsumer 避免跨区问题
最佳实践生产环境优先使用动态供给

练习编辑器

bash
Loading...

继续学习

完成本课后,建议继续学习下一课「NFS 存储」 以巩固所学知识。