ToolkitX
知识库工具箱

存储管理

PV, PVC, StorageClass

25min·高级

01. 存储的基本概念——PV、PVC、StorageClass

K8s 的存储体系有三层抽象: PV(PersistentVolume)——一块实际的存储资源。就像一块硬盘,管理员预先创建好,等着 Pod 来用。 PVC(PersistentVolumeClaim)——Pod 的存储请求。就像 Pod 说「我要 10GB 的存储空间」,K8s 找一个合适的 PV 给它绑定。 StorageClass——存储的模板。管理员定义了不同级别的存储(SSD 快盘、HDD 慢盘、云盘),用户创建 PVC 时指定用哪个 StorageClass,K8s 自动创建 PV。 这个三层设计的本质是职责分离:管理员管存储资源(PV/StorageClass),用户只要声明需求(PVC),不用关心后端存储是什么。
yaml
# PV 示例(管理员创建或 StorageClass 自动创建)
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data/my-pv

# PVC 示例(用户创建)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

02. AccessMode——读写模式

PV 和 PVC 有三种访问模式: ReadWriteOnce (RWO)——读写,但只能被单个 Node 上的 Pod 挂载。最常见的模式,适合数据库单实例。 ReadOnlyMany (ROX)——只读,可以被多个 Node 上的 Pod 挂载。适合共享配置文件、静态资源。 ReadWriteMany (RWX)——读写,可以被多个 Node 上的 Pod 挂载。NFS、CephFS、GlusterFS 这类共享文件系统支持。 不是所有存储后端都支持所有模式。云厂商的块存储(AWS EBS、GCE PD)只支持 RWO,文件存储(EFS、NFS)才支持 RWX。 选择 AccessMode 取决于你的应用的架构——单副本用 RWO 够了;多副本需要共享存储用 RWX。
yaml
# Pod 使用 PVC
spec:
  containers:
  - name: db
    image: mysql:8
    volumeMounts:
    - name: mysql-data
      mountPath: /var/lib/mysql
  volumes:
  - name: mysql-data
    persistentVolumeClaim:
      claimName: my-pvc
PVC 可以动态创建 PV(通过 StorageClass)也可以绑定管理员预先创建的 PV。生产环境一般用 StorageClass 动态创建。

03. StorageClass——动态创建 PV

没有 StorageClass 时,管理员要手动创建 PV,用户创建 PVC 绑定手动 PV。PV 不够了管理员又得手动加。有了 StorageClass,用户创建 PVC 时 K8s 自动根据 StorageClass 的定义创建 PV。 StorageClass 通过 provisioner(供应器)跟后端存储交互。云厂商的 K8s 服务自带 provisioner(直接创建云盘),自建集群可以用 NFS provisioner 或 Ceph provisioner。 关键参数:provisioner(供应器名称)、parameters(传给供应器的参数,如磁盘类型 SSD)、reclaimPolicy(PVC 删除后 PV 怎么处理——Delete 删数据、Retain 保留数据)。 可以在 StorageClass 里设置 allowVolumeExpansion: true,允许 PVC 扩容。在有状态应用(数据库)里这个功能很重要。
yaml
# StorageClass 示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
reclaimPolicy: Delete
allowVolumeExpansion: true

# PVC 引用 StorageClass
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: db-data
spec:
  storageClassName: fast-ssd
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
allowVolumeExpansion 需要在 StorageClass 里显式开启。然后直接改 PVC 的 storage 大小就能自动扩容。

04. StatefulSet——有状态应用的 Pod 管理器

Deployment 适合无状态应用(Web 服务器、API),StatefulSet 适合有状态应用(数据库、消息队列、分布式存储)。StatefulSet 的每个 Pod 有固定的身份标识和存储。 StatefulSet 跟 Deployment 的关键区别: 1. Pod 名字固定——不是随机后缀,而是 myapp-0、myapp-1、myapp-2。Pod 重启后名字不变。 2. 有序启停——启动时按 0→1→2 顺序,停止时按 2→1→0 逆序。升级也按序。 3. 独立存储——每个 Pod 有自己独立的 PVC,Pod 重建后绑定回同一个 PVC,数据不丢。 4. 稳定的网络标识——每个 Pod 有固定的 DNS 名(myapp-0.myapp-svc),适合发现集群里的各个成员。 典型场景:MySQL 主从、Redis 集群、Elasticsearch、Kafka——这些需要持久化存储和固定网络标识的服务。
yaml
# StatefulSet 示例
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql-svc
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: fast-ssd
      resources:
        requests:
          storage: 100Gi
volumeClaimTemplates 是 StatefulSet 的关键——它为每个 Pod 自动创建一个独立的 PVC。StatefulSet 删了 PVC 不会自动删。

05. PV 回收策略与数据保护

PV 的 reclaimPolicy 决定 PVC 删除后 PV 怎么处理: Delete——PV 和数据一起删掉。默认策略,适合自动创建的 PV。 Retain——PV 保留,数据还在。管理员需要手动清理(删除 PV 并清理存储后端的数据)。适合重要的数据。 Recycle——废弃了,别用,它会执行 rm -rf 清空 PV 再给别人用,不安全。 数据保护的最佳实践: 1. 重要数据的 PVC 用 Retain 策略,不会被误删 2. 配合 VolumeSnapshot 做快照备份 3. 定期把数据备份到外部存储(S3、NAS) 4. PVC 的 finalizer 可以防止误删 PVC
yaml
# PV 设置 Retain 策略
spec:
  persistentVolumeReclaimPolicy: Retain

# VolumeSnapshot(需要先安装 snapshot controller)
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: my-snapshot
spec:
  volumeSnapshotClassName: csi-snapclass
  source:
    persistentVolumeClaimName: my-pvc
Delete 策略意味着删 PVC 就会删数据,没有确认对话框!重要数据务必用 Retain 或配合 VolumeSnapshot 做备份。

知识测验

1/5正确 0

PV 和 PVC 的关系是什么?

下一节

监控与日志

下一节