PV 与 PVC 状态迁移

一、概述

1、PV

定义:集群级别的资源。是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。与节点相绑定。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。

用途:PV 为应用提供持久化的存储空间,即使 Pod 被销毁或重新创建,数据仍然保留。

2、PVC

定义:命名空间(namespace)级别的资源。PVC 是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。 PVC 申领会请求特定的大小和访问模式

用途:PVC 允许用户请求特定大小和特性的存储空间,Kubernetes 自动将合适的 PV 与 PVC 匹配起来。

二、状态变化

操作 PV 状态 PVC 状态
创建 PV (单独) Available ---
创建 PVC (单独) --- Pending
等待绑定 Bound Bound
删除 PV(delete命令 --> 真正删除) Bound --> Terminating --> --- Bound --> Lost
重新创建 PV Available --> Bound Lost --> Bound
删除 PVC Released(Retain)/ Failed(Delete/Recycle)清理失败 ---
删除 PV 的 claimRef Released(Retain)--> Available ---
重建 PVC Available --> Bound Bound

三、实例

1、单独创建 PV

1.1、创建并应用 PV

kubectl apply -f task-pv.yaml
cat << EOF > task-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  local:
    path: /mnt/data/my-pv
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k8s-node1
EOF

1.2、查看刚创建的 PV 状态

Available(可用): 表示可用状态,PV 刚被创建出来还未被任何 PVC 绑定

kubectl get pv task-pv

2、单独创建 PVC

2.1、创建并应用 PV

kubectl apply -f task-pvc.yaml
cat << EOF > task-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: manual
EOF

2.2、查看刚创建的 PVC 状态

Pending (待定):当 PVC 被创建时,它会处于 Pending 状态,等待与合适的 PV 匹配。

kubectl get pvc task-pvc

3、等待绑定

PVC --- Bound (已绑定):当 PVC 成功与 PV 匹配并绑定时,PVC 的状态变为 Bound。这意味着 PVC 已经准备好被 Pod 使用。

PV --- Bound(已绑定): 表示 PV 已经被 PVC 绑定

kubectl get pv task-pv
kubectl get pvc task-pvc

4、删除 PV

当我们尝试删除正在绑定的 PV 时会发现 delete 操作会一直卡住

因为 Kubernetes 试图保持 PV 和 PVC 之间的绑定关系,直到 PVC 被删除或者 PV 的状态被显式地更改

kubectl delete pv task-pv

4.1、查看 PV,PVC 状态

PV 没有被真正删除时,PV 处于 Terminating 状态,对 PVC 无影响 还是 Bound 状态

kubectl get pvc task-pvc
kubectl get pv task-pv

4.2、真正删除 PV

想要真正删除 PV 需要修改 PV 中的 Finalizer 属性强制删除

kubectl edit pv task-pv
注释掉 finalizers: 及其值

4.3、查看PV PVC 状态

当编辑 PV 并删除 PV 中的 Finalizer 属性强制删除 PV 时 PVC 会变为 Lost 状态

kubectl get pvc task-pvc
kubectl get pv task-pv

5、重新创建 PV

5.1、重新创建之前与 PVC 绑定的 PV

PV 由 刚创建的 Available --> Bound 绑定状态

PVC 由之前的 Lost 状态 --> Bound 绑定状态

过一会,会发现 PVC 和 PV 都变为 Bound 状态

kubectl apply -f task-pv.yaml

kubectl get pv task-pv

kubectl get pvc task-pvc

6、删除 PVC

这个时候的 PV 状态由自己定义的 persistentVolumeReclaimPolicy字段来决定

6.1、persistentVolumeReclaimPolicy: Retain 时删除 PVC 查看 PV 状态

persistentVolumeReclaimPolicy: Retain 时删除 PVC 与其绑定的 PV 处于Released 状态

kubectl delete pvc task-pvc

kubectl get pv task-pv

6.2、persistentVolumeReclaimPolicy: Delete 时删除 PVC 查看 PV 状态

persistentVolumeReclaimPolicy: Delete 时删除 PVC 与其绑定的 PV 处于 Failed 状态(清理失败)

kubectl get pv

6.3、persistentVolumeReclaimPolicy: Recycle 时删除 PVC 查看 PV 状态

persistentVolumeReclaimPolicy: Recycle 时删除 PVC 与其绑定的 PV 处于 Failed 状态(清理失败)

kubectl get pv

7、手动删除 PVC 引用

7.1、查看 PV 的 claimRef 属性

通过查看 PV 的 claimRef 属性,会发现其中还保留着 PVC 的绑定信息

kubectl get pv task-pv -o yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"PersistentVolume","metadata":{"annotations":{},"name":"task-pv"},"spec":{"accessModes":["ReadWriteOnce"],"capacity":{"storage":"1Gi"},"local":{"path":"/mnt/data/my-pv"},"nodeAffinity":{"required":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"kubernetes.io/hostname","operator":"In","values":["k8s-node1"]}]}]}},"persistentVolumeReclaimPolicy":"Retain","storageClassName":"manual"}}
    pv.kubernetes.io/bound-by-controller: "yes"
  creationTimestamp: "2024-08-13T08:38:42Z"
  finalizers:
  - kubernetes.io/pv-protection
  name: task-pv
  resourceVersion: "98232"
  uid: 74442248-2aea-436d-9e66-45af7b36405a
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 1Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: task-pvc
    namespace: default
    resourceVersion: "98206"
    uid: e0cb8efc-68a5-4044-8b63-9c633eeb4e6f
  local:
    path: /mnt/data/my-pv
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k8s-node1
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  volumeMode: Filesystem
status:
  phase: Released

7.2、删除 claimRef 对 PVC 的引用

由于PVC只能和Available的状态的PV进行绑定。删除 claimRef 对 PVC 的引用,这个时候 Kubernetes 的 PV Controller watch 到 PV 变化后,就会将 PV 修改为 Available 状态,Available 状态的 PV 就可以被其他 PVC 绑定了。

删除 claimRef 部分

PV 会从 Released 状态变为 Available 状态

kind: PersistentVolume
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"PersistentVolume","metadata":{"annotations":{},"name":"task-pv"},"spec":{"accessModes":["ReadWriteOnce"],"capacity":{"storage":"1Gi"},"local":{"path":"/mnt/data/my-pv"},"node
Affinity":{"required":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"kubernetes.io/hostname","operator":"In","values":["k8s-node1"]}]}]}},"persistentVolumeReclaimPolicy":"Retain","storageClassName":"manu
al"}}
    pv.kubernetes.io/bound-by-controller: "yes"
  creationTimestamp: "2024-08-13T08:52:58Z"
  finalizers:
  - kubernetes.io/pv-protection
  name: task-pv
  resourceVersion: "99447"
  uid: f89d6765-88fb-4b33-8dc1-157f25c7d798
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 1Gi
  local:
    path: /mnt/data/my-pv
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k8s-node1
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  volumeMode: Filesystem
status:
  phase: Released

7.3、重建之前的 PVC 进行绑定

会发现集群中的 PV 与 PVC 立即进行了绑定都变为 Bound 状态

kubectl apply -f task-pvc.yaml

kubectl get pvc,pv

四、状态迁移图

1、PV 状态迁移图

1、创建好一个 PV 后 PV 就处于一个 Available 状态,当一个 PV 与 一个 PVC 绑定的时候,这个 PV 就会进入 Bound 状态

2、一个处于 Bound 状态且回收策略时 Retain 的 PV ,其关联的 PVC 删除后,变为 Released ;回收策略为 Recycle/Delete 时清理失败会变为 Failed 状态

3、当删除 PV 的 claimRef (对 PVC 的引用)时,PV 由 Released 变为 Available

4、当 Recycle 失败时状态变为 Failed

5、通过手动删除 PVC 信息,状态由 Failed 变为 Available

2、PVC 状态迁移图

1、当 PVC 被创建时会短暂处于 Pending 状态等待集群中由匹配的 PV 与其绑定。当一个 Pending 的 PVC 成功与 PV 绑定时 PVC 的状态变为 Bound

2、当删除 PV 时分两种情况:第一种没有删除 PV 中的 Finalizer 属性时 PV 不会被删除 PVC 仍处于 Bound 状态;第二种删除了 PV 中的 Finalizer 属性时 PV 被强制删除导致 PVC 由 Bound 状态变为 Lost 状态

3、处于 Lost 状态的 PVC 再次与一个 PV 绑定后变为 Bound 状态

热门相关:入伍前夕   名门极致宠妻   爆萌宠妃:狼性邪帝,吃不够   弃妃不承欢:腹黑国师别乱撩   全能王妃:偷个王爷生宝宝