Kubernetes PV 在删除/重新创建后拒绝绑定

sta*_*wed 3 kubernetes

鉴于以下 PVC 和 PV:

  • PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: packages-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  volumeName: packages-volume
Run Code Online (Sandbox Code Playgroud)
  • 光伏:
apiVersion: v1
kind: PersistentVolume
metadata:
  name: packages-volume
  namespace: test
spec:
  claimRef:
    name: packages-pvc
    namespace: test
  accessModes:
    - ReadWriteMany
  nfs:
    path: {{NFS_PATH}}
    server: {{NFS_SERVER}}
  capacity:
    storage: 1Gi
  persistentVolumeReclaimPolicy: Retain
Run Code Online (Sandbox Code Playgroud)

如果我创建 PV,那么 PVC,它们会绑定在一起。但是,如果我删除 PVC 然后重新创建它,它们不会绑定(pvc 挂起)。为什么?

mar*_*rio 12

注意删除后PVCPV保持Released状态:

$ kubectl get pv packages-volume
NAME              CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM                  STORAGECLASS   REASON   AGE
packages-volume   1007Gi     RWX            Retain           Released   default/packages-pvc                           10m
Run Code Online (Sandbox Code Playgroud)

它应该有状态,Available以便它可以被另一个PersistentVolumeClaim实例重用。

为什么不是Available

如果您显示 的当前yaml定义PV,您可以通过执行以下操作轻松完成:

kubectl get pv packages-volume -o yaml
Run Code Online (Sandbox Code Playgroud)

您可能会注意到,在claimRef它包含uid最近删除的部分PersistentVolumeClaim

  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: packages-pvc
    namespace: default
    resourceVersion: "10218121"
    uid: 1aede3e6-eaa1-11e9-a594-42010a9c0005
Run Code Online (Sandbox Code Playgroud)

您可以通过发出以下命令轻松验证它:

kubectl get pvc packages-pvc -o yaml | grep uid
Run Code Online (Sandbox Code Playgroud)

就在您删除您的PVC并将其与PV定义所包含的内容进行比较之前。您会看到这与uid您删除PV后仍然引用的完全相同PVC。这个剩余的参考是PV保持Released状态的实际原因。

为什么新创建的PVC仍然处于一个Pending状态?

尽管您新创建的对象PVC看起来与您PVC刚刚删除的完全相同,因为您正在使用相同的yaml文件创建它,但从Kubernetes它的角度来看,它是一个全新的PersistentVolumeClaim对象实例,它具有完全不同的uid. 这就是它保持Pending状态并且无法绑定到PV.

解决方案:

PV Available再次制作,您只需要删除提到的uid引用,例如通过发出:

kubectl patch pv packages-volume --type json -p '[{"op": "remove", "path": "/spec/claimRef/uid"}]'
Run Code Online (Sandbox Code Playgroud)

或者通过删除整个claimRef部分,可以按如下方式完成:

kubectl patch pv packages-volume --type json -p '[{"op": "remove", "path": "/spec/claimRef"}]'
Run Code Online (Sandbox Code Playgroud)