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 状态