动态存储与 StorageClass 详解

动态存储与 StorageClass 详解

动态存储概述

动态存储自动化了存储卷的创建、配置和销毁过程,无需管理员手动管理 PV。

静态 vs 动态存储

┌─────────────────────────────────────────────────────────┐
│              静态存储供给 (Static Provisioning)          │
└─────────────────────────────────────────────────────────┘

管理员                  用户                   Kubernetes
   │                     │                         │
   │ 1. 创建 PV          │                         │
   ├────────────────────────────────────────────────>│
   │                     │                         │
   │                     │ 2. 创建 PVC             │
   │                     ├─────────────────────────>│
   │                     │                         │
   │                     │    3. 绑定 PVC 和 PV    │
   │                     │<─────────────────────────┤
   │                     │                         │
   │                     │ 4. Pod 使用 PVC         │
   │                     ├─────────────────────────>│
   │                     │                         │

缺点:
- 需要手动创建大量 PV
- 难以预估所需容量
- 容量可能浪费或不足
- 管理开销大

┌─────────────────────────────────────────────────────────┐
│              动态存储供给 (Dynamic Provisioning)          │
└─────────────────────────────────────────────────────────┘

管理员                  用户                   Kubernetes         Provisioner
   │                     │                         │                   │
   │ 1. 创建 StorageClass│                         │                   │
   ├────────────────────────────────────────────────>│                   │
   │                     │                         │                   │
   │                     │ 2. 创建 PVC             │                   │
   │                     │    (指定 StorageClass)  │                   │
   │                     ├─────────────────────────>│                   │
   │                     │                         │                   │
   │                     │                         │ 3. 调用 Provisioner│
   │                     │                         ├───────────────────>│
   │                     │                         │                   │
   │                     │                         │ 4. 创建卷         │
   │                     │                         │<───────────────────┤
   │                     │                         │                   │
   │                     │                         │ 5. 创建 PV 并绑定 │
   │                     │<─────────────────────────┤                   │
   │                     │                         │                   │
   │                     │ 6. Pod 使用 PVC         │                   │
   │                     ├─────────────────────────>│                   │

优点:
✅ 按需自动创建存储
✅ 无需预先分配
✅ 减少管理开销
✅ 提高资源利用率

StorageClass 详解

StorageClass 是动态存储的核心,定义了如何动态创建 PV。

完整配置

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"  # 默认 StorageClass
  labels:
    tier: gold
    performance: high

# Provisioner - 存储提供者
provisioner: ebs.csi.aws.com

# Parameters - 传递给 Provisioner 的参数
parameters:
  type: gp3              # AWS EBS 卷类型
  iops: "3000"           # IOPS
  throughput: "125"      # 吞吐量 (MiB/s)
  encrypted: "true"      # 加密
  kmsKeyId: "arn:aws:kms:us-east-1:xxx:key/xxx"
  fsType: ext4           # 文件系统类型

# VolumeBindingMode - 卷绑定模式
volumeBindingMode: WaitForFirstConsumer  # Immediate / WaitForFirstConsumer

# ReclaimPolicy - 回收策略
reclaimPolicy: Delete  # Delete / Retain

# AllowVolumeExpansion - 是否允许扩容
allowVolumeExpansion: true

# MountOptions - 挂载选项
mountOptions:
  - discard     # 支持 TRIM
  - noatime     # 不更新访问时间

# AllowedTopologies - 允许的拓扑
allowedTopologies:
- matchLabelExpressions:
  - key: topology.kubernetes.io/zone
    values:
    - us-east-1a
    - us-east-1b

# VolumeLifecycleModes - 卷生命周期模式(CSI)
# - Persistent: 持久卷
# - Ephemeral: 临时卷

Provisioner 类型

内置 Provisioner(In-Tree,逐步废弃)

# AWS EBS
provisioner: kubernetes.io/aws-ebs

# GCE PD
provisioner: kubernetes.io/gce-pd

# Azure Disk
provisioner: kubernetes.io/azure-disk

# Azure File
provisioner: kubernetes.io/azure-file

CSI Provisioner(推荐)

# AWS EBS CSI
provisioner: ebs.csi.aws.com

# GCE PD CSI
provisioner: pd.csi.storage.gke.io

# Azure Disk CSI
provisioner: disk.csi.azure.com

# Ceph RBD CSI
provisioner: rbd.csi.ceph.com

# NFS CSI
provisioner: nfs.csi.k8s.io

VolumeBindingMode

控制何时创建和绑定 PV。

Immediate(立即绑定)

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: immediate-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: Immediate  # 默认值
parameters:
  type: gp3

# 行为:
# 1. 用户创建 PVC
# 2. 立即调用 Provisioner 创建卷
# 3. 立即创建 PV 并绑定
# 4. Pod 创建时,卷已经存在

# 问题:
# - 卷可能创建在错误的可用区
# - Pod 无法调度到能访问该卷的节点
# - 需要重新创建 PVC

WaitForFirstConsumer(延迟绑定,推荐)

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: wait-for-consumer-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: gp3

# 行为:
# 1. 用户创建 PVC(状态:Pending)
# 2. 用户创建使用该 PVC 的 Pod
# 3. 调度器确定 Pod 运行的节点
# 4. 在该节点所在的拓扑位置创建卷
# 5. 创建 PV 并绑定
# 6. Pod 启动成功

# 优点:
# ✅ 确保卷在正确的位置创建
# ✅ 避免跨可用区访问
# ✅ 提高调度成功率
# ✅ 降低网络延迟和成本

示例对比

# 场景:三个可用区的集群
# us-east-1a, us-east-1b, us-east-1c

# 使用 Immediate 模式
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: immediate-ebs
provisioner: ebs.csi.aws.com
volumeBindingMode: Immediate

# 问题:
# 1. PVC 创建,卷在 us-east-1a 创建
# 2. Pod 调度到 us-east-1c 的节点
# 3. 结果:Pod 无法启动(EBS 卷不能跨 AZ)

# 使用 WaitForFirstConsumer 模式
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: wait-ebs
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer

# 解决:
# 1. PVC 创建,状态 Pending
# 2. Pod 创建,调度器选择 us-east-1c 的节点
# 3. 在 us-east-1c 创建 EBS 卷
# 4. 绑定成功,Pod 启动

Parameters

传递给 Provisioner 的配置参数,不同存储后端参数不同。

AWS EBS Parameters

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: aws-ebs-gp3
provisioner: ebs.csi.aws.com
parameters:
  # 卷类型
  type: gp3                    # gp2, gp3, io1, io2, st1, sc1
  
  # GP3 特定参数
  iops: "3000"                 # IOPS(100-16000)
  throughput: "125"            # 吞吐量 MiB/s(125-1000)
  
  # IO1/IO2 特定参数
  # iopsPerGB: "50"            # 每 GB 的 IOPS
  
  # 加密
  encrypted: "true"
  kmsKeyId: "arn:aws:kms:us-east-1:123456789:key/xxx"
  
  # 文件系统
  fsType: ext4                 # ext4, xfs
  
  # 标签
  tagSpecification_1: "Name=my-volume"
  tagSpecification_2: "Environment=production"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

GCE PD Parameters

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gce-pd-ssd
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd                 # pd-standard, pd-ssd, pd-balanced
  replication-type: regional-pd # none, regional-pd
  fstype: ext4
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

Azure Disk Parameters

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: azure-disk-premium
provisioner: disk.csi.azure.com
parameters:
  skuName: Premium_LRS        # Standard_LRS, Premium_LRS, StandardSSD_LRS, UltraSSD_LRS
  kind: Managed               # Managed, Shared
  fsType: ext4
  cachingMode: ReadOnly       # None, ReadOnly, ReadWrite
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

Ceph RBD Parameters

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd
provisioner: rbd.csi.ceph.com
parameters:
  clusterID: ceph-cluster-id
  pool: kubernetes
  imageFeatures: layering
  csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
  csi.storage.k8s.io/provisioner-secret-namespace: default
  csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
  csi.storage.k8s.io/controller-expand-secret-namespace: default
  csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
  csi.storage.k8s.io/node-stage-secret-namespace: default
  csi.storage.k8s.io/fstype: ext4
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Delete

NFS Parameters

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs
provisioner: nfs.csi.k8s.io
parameters:
  server: nfs-server.example.com
  share: /exported/path
  mountPermissions: "0755"
  # NFS 特定选项
  mountOptions:
    - hard
    - nfsvers=4.1
    - timeo=600
    - retrans=2
volumeBindingMode: Immediate
reclaimPolicy: Delete

AllowVolumeExpansion

控制是否允许扩容 PVC。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: expandable-sc
provisioner: ebs.csi.aws.com
allowVolumeExpansion: true  # 允许扩容
parameters:
  type: gp3

---
# 使用该 StorageClass 的 PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: expandable-pvc
spec:
  storageClassName: expandable-sc
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

# 扩容操作
# kubectl edit pvc expandable-pvc
# 将 storage: 10Gi 改为 storage: 20Gi

# 扩容流程:
# 1. 编辑 PVC,增加容量
# 2. External Resizer 检测到变化
# 3. 调用 CSI ControllerExpandVolume(扩容存储后端)
# 4. Kubelet 调用 CSI NodeExpandVolume(扩容文件系统)
# 5. PVC.status.capacity 更新为新容量

支持在线扩容的存储

  • AWS EBS: ✅
  • GCE PD: ✅
  • Azure Disk: ✅
  • Ceph RBD: ✅
  • NFS: ❌(网络存储通常不需要)

AllowedTopologies

限制卷可以创建的拓扑位置。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: topology-aware-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
  - key: topology.kubernetes.io/zone
    values:
    - us-east-1a
    - us-east-1b
  - key: topology.kubernetes.io/region
    values:
    - us-east-1

# 效果:
# - 卷只能在 us-east-1a 或 us-east-1b 创建
# - Pod 也只能调度到这两个可用区

拓扑标签

# 查看节点拓扑标签
kubectl get nodes --show-labels

# 常见标签:
topology.kubernetes.io/region=us-east-1
topology.kubernetes.io/zone=us-east-1a
node.kubernetes.io/instance-type=m5.large

默认 StorageClass

设置默认 StorageClass,PVC 不指定 storageClassName 时使用。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"  # 设为默认
provisioner: ebs.csi.aws.com
parameters:
  type: gp3

---
# PVC 不指定 storageClassName
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: default-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  # storageClassName 留空,使用默认 StorageClass

管理默认 StorageClass

# 查看默认 StorageClass
kubectl get storageclass
NAME            PROVISIONER       RECLAIMPOLICY   VOLUMEBINDINGMODE
standard (default)   ebs.csi.aws.com   Delete          WaitForFirstConsumer

# 设置默认
kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

# 取消默认
kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'

# 注意:集群中只能有一个默认 StorageClass

动态存储工作流程

完整流程

┌──────────────────────────────────────────────────────────────────┐
│ 1. 管理员创建 StorageClass                                        │
│    kubectl apply -f storageclass.yaml                            │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 2. 用户创建 PVC                                                   │
│    spec:                                                         │
│      storageClassName: fast-ssd                                  │
│      resources:                                                  │
│        requests:                                                 │
│          storage: 10Gi                                           │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 3. PVC 状态变为 Pending                                           │
│    (如果 volumeBindingMode 是 WaitForFirstConsumer)             │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 4. 用户创建使用该 PVC 的 Pod                                      │
│    volumes:                                                      │
│    - name: data                                                  │
│      persistentVolumeClaim:                                      │
│        claimName: my-pvc                                         │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 5. Scheduler 调度 Pod                                             │
│    - 评估节点资源                                                 │
│    - 评估节点拓扑(可用区)                                       │
│    - 选择最优节点                                                 │
│    - 设置 PVC annotation: volume.kubernetes.io/selected-node     │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 6. PV Controller 检测到 PVC 需要绑定                              │
│    - 检查 selected-node annotation                               │
│    - 获取节点拓扑信息                                             │
│    - 调用 External Provisioner                                   │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 7. External Provisioner 工作                                      │
│    a. 读取 StorageClass parameters                               │
│    b. 调用 CSI CreateVolume RPC                                  │
│       - volume_name                                              │
│       - capacity_range                                           │
│       - volume_capabilities                                      │
│       - parameters                                               │
│       - accessibility_requirements (拓扑信息)                     │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 8. CSI Driver Controller Service                                 │
│    a. 连接存储后端 API                                            │
│    b. 创建卷(例如:AWS EBS、Ceph RBD)                          │
│    c. 返回 volume_id 和 volume_context                           │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 9. External Provisioner 创建 PV 对象                              │
│    apiVersion: v1                                                │
│    kind: PersistentVolume                                        │
│    spec:                                                         │
│      capacity:                                                   │
│        storage: 10Gi                                             │
│      csi:                                                        │
│        driver: ebs.csi.aws.com                                   │
│        volumeHandle: vol-xxxxx  # volume_id                      │
│      claimRef:                                                   │
│        name: my-pvc                                              │
│        namespace: default                                        │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 10. PV Controller 绑定 PVC 和 PV                                  │
│     - PVC.spec.volumeName = PV.name                              │
│     - PVC.status.phase = Bound                                   │
│     - PV.status.phase = Bound                                    │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 11. Kubelet 挂载卷到 Pod                                          │
│     a. AttachDetach Controller 挂载卷到节点(块存储)             │
│     b. Kubelet 调用 CSI NodeStageVolume(格式化、挂载)           │
│     c. Kubelet 调用 CSI NodePublishVolume(Bind mount 到 Pod)   │
└────────────────┬─────────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────────────────────────┐
│ 12. Pod 运行,卷可用                                              │
│     容器可以读写 /data 目录                                       │
└──────────────────────────────────────────────────────────────────┘

使用示例

示例 1:AWS EBS 动态存储

# 1. 创建 StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-gp3
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  encrypted: "true"
  fsType: ext4

---
# 2. 创建 PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: webapp-pvc
spec:
  storageClassName: ebs-gp3
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

---
# 3. Deployment 使用 PVC
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: nginx
        volumeMounts:
        - name: data
          mountPath: /data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: webapp-pvc

示例 2:StatefulSet 使用动态存储

# 1. 创建 StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
parameters:
  type: gp3
  iops: "5000"
  encrypted: "true"

---
# 2. StatefulSet 使用 volumeClaimTemplates
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
  # VolumeClaimTemplates:为每个 Pod 自动创建 PVC
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      storageClassName: fast-ssd
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 50Gi

# 结果:
# - 自动创建 PVC: data-mysql-0, data-mysql-1, data-mysql-2
# - 每个 PVC 都会动态创建一个 PV
# - 每个 Pod 都有独立的持久化存储

示例 3:多层存储策略

# 高性能 SSD 存储
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: performance
  labels:
    tier: gold
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
parameters:
  type: io2
  iops: "10000"
  encrypted: "true"
reclaimPolicy: Retain  # 重要数据,手动删除

---
# 标准 SSD 存储
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
  labels:
    tier: silver
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
parameters:
  type: gp3
  iops: "3000"
  encrypted: "true"

---
# 经济型 HDD 存储
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: economy
  labels:
    tier: bronze
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
parameters:
  type: sc1  # Cold HDD
  encrypted: "false"

---
# 数据库使用高性能存储
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: database-pvc
spec:
  storageClassName: performance
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi

---
# 日志使用经济型存储
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: logs-pvc
spec:
  storageClassName: economy
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Gi

监控和管理

查看 StorageClass

# 列出所有 StorageClass
kubectl get storageclass
kubectl get sc  # 简写

# 详细信息
kubectl describe storageclass fast-ssd

# YAML 格式
kubectl get sc fast-ssd -o yaml

# 查看默认 StorageClass
kubectl get sc | grep "(default)"

查看动态创建的 PV

# 列出所有 PV
kubectl get pv

# 查看特定 StorageClass 的 PV
kubectl get pv -l storage.kubernetes.io/storageclass=fast-ssd

# 查看 PV 详情
kubectl describe pv pvc-xxxxx

监控动态存储

# 查看 Provisioner Pod
kubectl get pods -n kube-system | grep csi

# 查看 External Provisioner 日志
kubectl logs -n kube-system csi-provisioner-xxxxx

# 查看 CSI Controller 日志
kubectl logs -n kube-system csi-controller-xxxxx

故障排查

PVC 一直 Pending

# 检查 PVC 状态
kubectl describe pvc my-pvc

# 常见原因 1:StorageClass 不存在
Events:
  Warning  ProvisioningFailed  1m  persistentvolume-controller  
  storageclass.storage.k8s.io "fast-ssd" not found

# 解决:创建 StorageClass
kubectl apply -f storageclass.yaml

# 常见原因 2:Provisioner 未运行
Events:
  Warning  ProvisioningFailed  1m  persistentvolume-controller  
  Failed to provision volume: timeout waiting for provisioner

# 解决:检查 CSI Driver
kubectl get csidrivers
kubectl get pods -n kube-system | grep csi

# 常见原因 3:资源配额超限
Events:
  Warning  ProvisioningFailed  1m  persistentvolume-controller  
  exceeded quota: storage-quota

# 解决:增加配额或删除不用的 PVC
kubectl get resourcequota -n default

卷创建失败

# 检查 External Provisioner 日志
kubectl logs -n kube-system -l app=csi-provisioner

# 常见错误:权限不足
# AWS: 检查 IAM 角色权限
# GCP: 检查服务账号权限
# Azure: 检查 Service Principal 权限

# 常见错误:参数错误
# 检查 StorageClass parameters
kubectl get sc my-sc -o yaml

最佳实践

1. 使用延迟绑定

# ✅ 推荐
volumeBindingMode: WaitForFirstConsumer

# ❌ 不推荐(除非特殊需求)
volumeBindingMode: Immediate

2. 设置合理的回收策略

# 生产环境:重要数据使用 Retain
reclaimPolicy: Retain

# 开发/测试环境:使用 Delete
reclaimPolicy: Delete

3. 启用卷扩容

# 允许未来扩容
allowVolumeExpansion: true

4. 使用拓扑感知

# 限制卷创建位置,提高性能和可用性
allowedTopologies:
- matchLabelExpressions:
  - key: topology.kubernetes.io/zone
    values:
    - us-east-1a
    - us-east-1b

5. 设置默认 StorageClass

# 为集群设置一个合理的默认 StorageClass
annotations:
  storageclass.kubernetes.io/is-default-class: "true"

6. 使用标签分类

# 为不同性能等级的 StorageClass 添加标签
labels:
  tier: gold  # or silver, bronze
  performance: high  # or medium, low

7. 监控存储成本

# 定期检查 PV 使用情况
kubectl get pv --sort-by=.spec.capacity.storage

# 删除未使用的 PVC
kubectl get pvc --all-namespaces | grep -v Bound

总结

动态存储通过 StorageClass 实现了存储的自动化管理:

  • 自动创建:按需创建 PV,无需手动管理
  • 拓扑感知:在正确的位置创建卷
  • 灵活配置:通过 parameters 定制存储
  • 扩展支持:支持在线扩容
  • 多层策略:不同场景使用不同存储等级

掌握 StorageClass 是管理 Kubernetes 存储的关键。