Kubernetes持久卷索赔无限期处于挂起状态

73

我创建了一个永久卷,它的来源是已经格式化并提供了数据的 Google Compute Engine 持久磁盘。Kubernetes 表示该永久卷可用。

kind: PersistentVolume
apiVersion: v1
metadata:
  name: models-1-0-0
  labels:
    name: models-1-0-0
spec:
  capacity:
    storage: 200Gi
  accessModes:
    - ReadOnlyMany
  gcePersistentDisk:
    pdName: models-1-0-0
    fsType: ext4
    readOnly: true

然后我创建了一个PersistentVolumeClaim,以便我可以将该卷附加到多个Pod跨多个节点。然而,kubernetes无限期地表示它处于待处理状态。


kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: models-1-0-0-claim
spec:
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 200Gi
  selector:
    matchLabels:
      name: models-1-0-0

有什么见解吗?我感觉选择器可能出了点问题......

预配置一个带有数据的持久磁盘,并让分布在多个节点上的Pod都能够从中读取,这是否可能?

12个回答

87

我很快意识到,如果没有指定storageClassName字段,PersistentVolumeClaim会将其默认设置为standard。然而,在创建PersistentVolume时,storageClassName没有默认值,所以选择器找不到匹配项。

对于我来说,以下内容有效:

kind: PersistentVolume
apiVersion: v1
metadata:
  name: models-1-0-0
  labels:
    name: models-1-0-0
spec:
  capacity:
    storage: 200Gi
  storageClassName: standard
  accessModes:
    - ReadOnlyMany
  gcePersistentDisk:
    pdName: models-1-0-0
    fsType: ext4
    readOnly: true
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: models-1-0-0-claim
spec:
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 200Gi
  selector:
    matchLabels:
      name: models-1-0-0

22
运行命令 kubectl describe pvc 确认是否存在此问题,您将得到以下信息:"Cannot bind to requested volume "YOUR_PV_NAME": storageClasseName does not match"。请注意,翻译保持原意并尽可能易懂。 - s12chung
有相同的问题。奇怪的是,K8 仪表板只会保持挂起状态,而不报告错误! - nir
3
+1 我在使用kops设置AWS EC2集群时也遇到了这个问题。为了正确连接PV/PVC,我不得不在两者中都添加storageClassName: gp2。关于为您的AWS集群设置存储类可用的EBS卷类型有一些相关文档。出于某种原因,我没有收到@s12chung提到的错误消息。 - wronk
在GCP中,对于我来说,将storageClassName: standard添加到pv和pvc中也起了作用。 - undefined

17

17

我也遇到了同样的问题,不过是由于另一个原因。因此我在这里分享解决方法来帮助社区。

如果你删除了PersistentVolumeClaim,并且再次使用相同的定义重新创建它,它将一直处于待定状态,为什么呢?

PersistentVolume中的persistentVolumeReclaimPolicy默认为Retain。如果我们删除了PersistentVolumeClaim,则PersistentVolume仍然存在,该卷被视为已释放。但它还不能供另一个声明使用,因为先前申请者的数据仍存储在该卷上。

所以,您需要手动使用以下步骤回收该卷:

  1. 删除PersistentVolume(相关联的底层存储资源,如EBS、GCE PD、Azure Disk等不会被删除,仍然存在)

  2. (可选)根据需要手动清理关联存储资源上的数据

  3. (可选)手动删除关联的存储资源(如EBS、GCE PD、Azure Disk等)

如果您仍然需要相同的数据,则可以跳过第2和第3步(清理和删除关联存储资源),只需使用相同的存储资产定义简单地重新创建一个新的PersistentVolume,然后您就可以再次创建PersistentVolumeClaim了。

还有一件需要提及的事情,Retain并不是persistentVolumeReclaimPolicy的唯一选项,以下是一些其他选项,您可能需要根据用例场景使用或尝试:

Recycle:对卷执行基本的擦除(例如rm -rf //*)- 使其再次可用以进行新索赔。仅NFSHostPath支持回收。

Delete:删除关联的存储资产,例如AWS EBS、GCE PD、Azure Disk或OpenStack Cinder...等卷。

更多信息,请查阅Kubernetes文档

如果仍需要更多澄清或有任何问题,请随时留下评论,我很乐意进行澄清和协助。


仅仅从 PV 中删除数据就能解决这个问题吗?由于某些限制,我无法删除 PV 并创建新的 PV。但是由于我已经删除了 PVC,我现在无法创建新的 PVC,而且它一直处于挂起状态。 - iRunner
@iRunner,你不必删除数据本身,但仍然需要删除PV(逻辑卷而非实际数据)-(如果你决定删除PV,不用担心相关的底层存储将不会被删除)。 - Muhammad Soliman
@MuhammadSoliman 如果我没有访问PV的权限,因为您需要集群管理员权限来删除,那么应该怎么办呢?我想要的行为是:如果我删除了PVC,那么我希望将PV再次可用于另一个声明。或者您建议只删除Pod并保留PVC,以便可以在Pod中再次重用它吗? - zaf187
如果我删除了已定义sc/pv/pvc的命名空间,然后再次运行密钥和卷yaml文件的脚本会怎样?我的情况是KinD集群,Azure文件共享。同样的脚本适用于AKS集群。 - soMuchToLearnAndShare

13
如果您正在使用Microk8s,则必须在成功启动PersistentVolumeClaim之前启用存储。
只需执行以下操作:
microk8s.enable storage

您需要删除您的部署并重新开始。

您可能还需要手动删除“pending”持久卷声明,因为我发现卸载创建它们的Helm chart没有清除PVCs。

您可以先查找名称列表,然后执行此操作:

kubectl get pvc --all-namespaces

然后使用以下方法删除每个名称:

kubectl delete pvc name1 name2 etc...

启用存储后,重新应用您的部署应该可以使事情继续运行。


1
在microk8s/ubuntu 19.10中运行得非常顺利。 - Ragen Dazs
在Ubuntu 20.04上使用microk8s对我有效。 - Malachi Bazar
小心不要删除其他的pvcs,第一个注释将显示所有进程中存在的pvc。 - Solaiman Salvi
哇,这个回复在互联网上真是太棒了!谢谢兄弟,让我有所进步。 - simPod

8

我遇到了同样的问题,并意识到 k8s 实际上是按需分配的,即

  • 创建 pvc 后,它会保持在 PENDING 状态,而不会创建相应的 pv。
  • 只有在创建使用 pvc 的 deployment 后,才会创建 pvc 和相应的 pv(EBS 卷)。

我正在使用版本为 1.16 的 kubernetes 的 EKS,并且该行为由 StorageClass Volume Binding Mode 控制。


3

我有同样的问题。我的PersistentVolumeClaim yaml最初如下:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc
spec:
  storageClassName: “”
  accessModes:
     ReadWriteOnce 
  volumeName: pv
  resources:
    requests:
      storage: 1Gi

我的PVC状态是:

在这里输入图片描述

移除volumeName后:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc
spec:
  storageClassName: “”
  accessModes:
     ReadWriteOnce 
  resources:
    requests:
      storage: 1Gi

enter image description here


2
当您想要手动将带有现有磁盘的PVC绑定到PV时,不应指定storageClassName...但是...云提供商默认设置了“标准”StorageClass,使其无论何时在修补PVC / PV时都会被输入。
您可以通过执行kubectl get storageclass来检查提供程序是否将其设置为默认值(它将被写入“(default)”)。
要解决此问题,最好获取现有的StorageClass YAML并添加此注释:
  annotations:
    storageclass.kubernetes.io/is-default-class: "false"

应用和良好 :)

1

我正在使用microk8s

通过运行以下命令,解决了问题

systemctl start open-iscsi.service

(之前使用apt install open-iscsi安装了open-iscsi,但尚未启动)

然后按以下方式启用存储

microk8s.enable storage

然后,我从Lens中删除了Stateful Sets和挂起的Persistence Volume Claims,以便重新开始。

之后工作得很好。


1

当两个 PersistentVolume 具有相同的 spec/hostPath/path 值时,我在 microk8s 1.14.1 中看到了这种行为,例如:

kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv-name
  labels:
    type: local
    app: app
spec:
  storageClassName: standard
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/k8s-app-data"

似乎 microk8s 是基于事件的(这在单节点集群上并不必要),并且会丢弃有关任何失败操作的信息,导致几乎所有故障都会产生不必要的可怕反馈。

1
我在使用Apache Airflow(stable)的Helm Chart时遇到了问题,将storageClass设置为azurefile有帮助。在云服务提供商出现这种情况时,你应该怎么做呢?只需搜索支持所需访问模式的存储类即可。ReadWriteMany表示同时有多个进程读写该存储。在这种情况下(Azure),需要使用azurefile存储类。
path: /opt/airflow/logs

  ## configs for the logs PVC
  ##
  persistence:
    ## if a persistent volume is mounted at `logs.path`
    ##
    enabled: true

    ## the name of an existing PVC to use
    ##
    existingClaim: ""

    ## sub-path under `logs.persistence.existingClaim` to use
    ##
    subPath: ""

    ## the name of the StorageClass used by the PVC
    ##
    ## NOTE:
    ## - if set to "", then `PersistentVolumeClaim/spec.storageClassName` is omitted
    ## - if set to "-", then `PersistentVolumeClaim/spec.storageClassName` is set to ""
    ##
    storageClass: "azurefile"

    ## the access mode of the PVC
    ##
    ## WARNING:
    ## - must be: `ReadWriteMany`
    ##
    ## NOTE:
    ## - different StorageClass support different access modes:
    ##   https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes
    ##
    accessMode: ReadWriteMany

    ## the size of PVC to request
    ##
    size: 1Gi

非常感谢。希望Airflow文档更加详细。 - Subha_26

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接