PV 与 PVC 持久化存储

上一章的 emptyDir、hostPath 要么随 Pod 消失、要么绑定节点,数据库等应用需要「Pod 没了数据还在」的存储。PV(PersistentVolume)与 PVC(PersistentVolumeClaim)把存储从 Pod 中抽象出来:管理员提供存储、应用声明需求,两者解耦后由系统自动绑定。

核心概念

  • PV:集群里的存储资源,由管理员预先创建,或由 StorageClass 动态生成,与具体节点无关。
  • PVC:应用提出的「存储申请」,声明容量与访问模式。
  • Pod 只引用 PVC,不关心背后是 NFS 还是云盘。

静态供给:先建 PV 再申请

PV/PVC/Pod 关系图 管理员先创建 PV,声明容量、访问模式与回收策略:

accessModes含义
ReadWriteOnce单节点读写
ReadOnlyMany多节点只读
ReadWriteMany多节点读写
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-10g
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain   # Retain/Delete
  nfs:
    server: 192.168.1.100
    path: /exports/pv1

回收策略决定 PVC 释放后 PV 的去向:Retain 保留数据待管理员处理,Delete 连底层存储一起删除(Recycle 已废弃)。对应的 PVC 声明容量与访问模式:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-claim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

PVC 会挑选容量足够、访问模式匹配的空闲 PV 并绑定。Pod 里通过 claimName 引用:

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
    - name: app
      image: myapp:1.0
      volumeMounts:
        - name: data
          mountPath: /var/lib/data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: data-claim

动态供给:StorageClass

静态供给每次都要手动建 PV,StorageClass 可让它自动化:定义 provisioner(存储插件),PVC 声明 storageClassName 后由插件自动创建 PV:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: cloud-fast
provisioner: kubernetes.io/aws-ebs   # 以云盘插件为例,可替换为 nfs 等其他插件

PVC 里加 storageClassName: cloud-fast 即可触发动态创建。

PV 状态机与排错

PV 生命周期:Available(空闲)→ Bound(已被 PVC 绑定)→ Released(PVC 删除后)。PVC 卡在 Pending 时按顺序排查:

kubectl get pvc              # STATUS=Pending
kubectl describe pvc xxx     # 事件会写明原因
kubectl get pv               # 有没有容量/访问模式匹配的空闲 PV
kubectl get sc               # 声明的 storageClass 是否存在

常见原因:声明的 storageClassName 不存在、静态供给下没有匹配的 PV、容量或访问模式不符。

小结:PV 是存储资源、PVC 是申请单、Pod 引用 PVC;静态供给手动建 PV,动态供给由 StorageClass 自动完成;PVC 一直 Pending 时优先核对 storageClass、PV 容量与访问模式。

笔记加载中…