在K8S中,PV 生命周期内的有哪些阶段?

在 Kubernetes 中,PersistentVolume (PV) 的生命周期独立于 Pod,其状态流转由 PVC (PersistentVolumeClaim) 的使用情况和回收策略共同决定。以下是 PV 从创建到销毁的完整阶段详解:


PV 生命周期全阶段图解

graph TD A[创建] --> B[可用 Available] B -->|被 PVC 绑定| C[已绑定 Bound] C -->|PVC 删除| D{回收策略} D -->|Retain| E[已释放 Released] D -->|Delete| F[删除中 Deleting] D -->|Recycle| G[回收中 Recycling] E -->|手动清理| H[失效 Failed] F -->|删除成功| I[已删除] G -->|回收完成| B H -->|管理员修复| B

详细阶段解析

1. 创建(Creation)

  • 触发方式
    • 静态供应:管理员手动创建 PV 对象
      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: static-pv
      spec:
        capacity: {storage: 10Gi}
        accessModes: [ReadWriteOnce]
        persistentVolumeReclaimPolicy: Retain  # 关键回收策略
        storageClassName: ""                  # 显式标识为静态 PV
        nfs:
          server: 10.0.0.100
          path: "/data"
      
    • 动态供应:StorageClass 的 Provisioner 自动创建 PV
  • 初始状态Available

2. 可用(Available)

  • 特征
    • PV 已就绪,尚未被任何 PVC 绑定
    • 可被匹配的 PVC 申领
  • 匹配条件:PVC 的 storageClassNameaccessModes容量 等与 PV 一致

3. 已绑定(Bound)

  • 触发条件:PVC 成功绑定 PV
    # PVC 绑定示例
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: app-pvc
    spec:
      storageClassName: ""  # 匹配静态 PV
      accessModes: [ReadWriteOnce]
      resources:
        requests: {storage: 10Gi}
    
  • 特征
    • PV 与 PVC 建立一对一绑定关系
    • PV 状态变为 Bound
    • 绑定后 PV 不可被其他 PVC 使用

4. 已释放(Released)

  • 触发条件:PVC 被删除,且 PV 的 persistentVolumeReclaimPolicyRetain
  • 特征
    • PV 解除与 PVC 的绑定
    • 存储卷上的数据保留(需手动清理)
    • PV 状态变为 Released
  • 后续操作
    • 手动回收:管理员删除 PV 并重新创建
      kubectl delete pv static-pv  # 删除 PV 对象
      # 在存储系统上清理数据
      kubectl apply -f static-pv.yaml  # 重建 PV
      
    • 直接重用:修复 PV 状态(K8s v1.15+)
      # 1. 移除 PV 的 claimRef(解除旧 PVC 关联)
      kubectl patch pv static-pv --type json \
        -p '[{"op": "remove", "path": "/spec/claimRef"}]'
      
      # 2. 状态自动变回 Available
      

5. 删除中(Deleting)

  • 触发条件:PVC 被删除,且 PV 的回收策略为 Delete
  • 特征
    • PV 状态变为 Deleting
    • 自动触发底层存储卷删除(通过 CSI 驱动)
  • 依赖:需要 StorageClass 的 Provisioner 实现删除接口

6. 回收中(Recycling)

  • 历史遗留模式Kubernetes 1.15+ 已弃用
  • 原理:PV 被释放后自动执行 rm -rf /volume/* 清理数据
  • 替代方案:使用动态供应或手动管理

7. 失效(Failed)

  • 触发条件
    • 自动回收过程出错(如存储系统故障)
    • 手动操作失误
  • 特征
    • PV 状态变为 Failed
    • 数据可能仍存在于存储后端
  • 恢复步骤
    1. 检查存储系统状态
    2. 修复问题后手动删除 PV 重建
      kubectl delete pv failed-pv
      kubectl apply -f fixed-pv.yaml
      

回收策略对比

策略 操作 数据安全性 自动化程度 适用场景
Retain 保留数据,需手动清理 ★★★★★ ❌ 低 生产数据库、关键数据
Delete 自动删除存储卷 ★☆☆☆☆ ✅ 高 临时环境、测试数据
Recycle (弃用) 擦除数据后重新可用 ★★☆☆☆ ⚠️ 中 已淘汰

最佳实践:生产环境优先使用 Retain 策略防止误删,配合备份方案(如 Velero)。


状态查询命令

kubectl get pv -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\t"}{.spec.claimRef.name}{"\n"}{end}'

# 输出示例
static-pv   Bound   app-pvc
dynamic-pv  Available   ""

生命周期事件监控

kubectl get events --sort-by='.metadata.creationTimestamp' \
  -o custom-columns="TIME:.metadata.creationTimestamp,NAME:.involvedObject.name,TYPE:.type,REASON:.reason,MESSAGE:.message" \
  | grep PersistentVolume

高级控制技巧

1. 防止 PV 被错误回收

apiVersion: v1
kind: PersistentVolume
metadata:
  name: critical-data-pv
  annotations:
    # 即使 PVC 被删也保留 PV(部分 CSI 驱动支持)
    csi.storage.k8s.io/skip-delete: "true"
spec:
  persistentVolumeReclaimPolicy: Retain
  ...

2. 跨命名空间共享 PV

  • 方案:使用 ReadWriteMany 访问模式的存储(如 NFS)
  • 限制:单个 PV 只能被一个 PVC 绑定,但可通过多个 Pod 挂载同一 PVC 实现共享

3. 本地存储生命周期管理

  • 挑战:节点宕机时本地 PV 无法访问
  • 方案:结合 volumeBindingMode: WaitForFirstConsumernodeAffinity
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: local-pv
    spec:
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values: ["node-01"]  # 绑定特定节点
      ...
    

总结

PV 的生命周期由创建 → 绑定 → 释放 → 回收构成,其核心控制点在于:

  • 回收策略Retain/Delete)决定数据存留
  • 存储供应模式(静态/动态)影响创建方式
  • 状态机流转需结合运维操作介入(尤其 Released 状态)

理解各阶段的触发条件和恢复方法,是保障 Kubernetes 持久化存储可靠性的关键。

posted @ 2025-08-15 14:00  天道酬勤zjh  阅读(22)  评论(0)    收藏  举报