事情的起因是基于k8s集群搞东搞西搞项目时,使用脚本一键部署平台时突然僵住了,直接返回超时信息,通过各种手段对 shell 脚本进行debug,最终定位到是在使用yaml文件创建pod时一直卡在下面这步:PersistentVolumeClaim is not bond。
在这里插入图片描述

当然,这只是其中一条not boud的debug信息,整个部署中的和存储存储相关的组件,mysql、redis、mogodb和minio全都处于这种状态,查询相关pod,全都处于pending状态,等于压根没起来,查看pod的详细信息,得到如下Message:

对于k8s新手的我来说,无异于致命打击,pv和pvc是个啥都不知道。没关系!扶我起来!我还能学!

每个人出现这个问题的原因不尽相同,最终的解决方案不具有普适性,但是了解整个过程有助于类似问题的思考,因此记录下整个思考过程。这个问题中有几个比较关键的词语,个人觉得有必要说明一下。每个概念名词都分为官方解释和个人理解。

PersistentVolume

官方解释:持久卷(PersistentVolume,PV)是集群中的一块存储,可以由管理员事先供应,或者使用存储类(Storage Class)来动态供应。 持久卷是集群资源,就像节点也是集群资源一样。

个人理解:其实说白了,卷就是用来存储k8s容器数据的一个抽象概念,但是一般容器绑定的都是临时卷,容器重启之后就没了。有些数据在重启容器后可能仍然是被需要的,此时可以通过创建持久卷达到目的,它们拥有独立于任何使用pv的pod的生命周期。就像pod是集群的计算资源一样,pv则是集群中的存储资源。

PersistentVolumeClaim

官方解释:通过在 PersistentVolumeClaim 中指定PersistentVolume,你可以声明该特定 PV 与 PVC 之间的绑定关系。如果该 PersistentVolume 存在且未被通过其 claimRef 字段预留给 PersistentVolumeClaim,则该 PersistentVolume 会和该 PersistentVolumeClaim 绑定到一起。

个人理解:pvc的本质就是一个声明,某个pod可以先声明好需要怎样的存储资源,然后系统会根据策略和pv进行绑定。pvc和pv的关系与pod和node关系类似,pvc消耗pv的存储资源,pod消耗nod的计算资源,前者消耗后者的资源。用户只需要关注在容器中挂载pvc,而不需要关注pvc所绑定的pv底层存储是采用何种技术进行实现的。

StorageClass

官方解释:StorageClass 为管理员提供了描述存储 “类” 的方法。 不同的类型可能会映射到不同的服务质量等级或备份策略,或是由集群管理员制定的任意策略。 Kubernetes 本身并不清楚各种类代表的什么。这个类的概念在其他存储系统中有时被称为 “配置文件”。

个人理解:每个pv都是k8s集群中的存储资源,但是用户经常需要不同性能的pv,storageclass相当于隔离了不同性能的pv,集群管理员可以创建不同质量和策略的storageclass,对pv进行分类管理。

现在我们再回头看一下debug信息:PersistentVolumeClaim is not bound。毫无疑问,这句话的意思是说pvc没有绑定上pv。因为创建容器时指定的是pvc,pvc再去绑定相关的pv,应该是相关pv没有被创建出来,因此没有绑定上。于是研究了一番pv卷的供应过程,流程图如下图所示:

静态卷供应

根据上图其实可以看出,pvc和pv的绑定过程其实是一个系统自动适配的过程,容器用pvc声明说我想要10g,然后刚好有个10g的pv,系统就给它俩绑定上了,容器就可以用上这个pv的存储资源了,在这个过程中,是先创建好若干pv,在容器中使用pvc时才会自动绑定到pc,这是一个静态供应的过程。

动态卷供应

动态卷供应和静态卷供应的区别在于,动态卷供应的pv不是手动创建的,而是根据pvc的需求创建出来的。但是这个供应过程涉及到storageclass的定义,如果pvc中定义的storageclass为"",则直接使用默认的storageclass,此时需要看集群中是否有且只有一个默认的storageclass,并且如果没有启用Default准入控制器,则会直接禁用使用动态卷供应,只能通过静态卷供应方式给pvc绑定pv;如果pvc中已经指定了storageclass,则会直接基于该storageclass的配置生成pvc所需要的pv。这就是一个动态供应卷的过程。

基于以上背景,其实我们只要让这些容器通过动态卷供应的方式创建出pv,并将pvc绑定到对应pv即可,可以尝试进行以下几项排查。

1. 是否有且仅有一个default StorageClass

使用如下指令查看StorageClass状态:

kubectl get sc

上图代表cbs为默认的StorageClass,使用动态卷供应时,如果没有配置相关的StorageClass,则会默认基于该StorageClass的配置创建pv。

修改默认StorageClass的方式如下:

kubectl patch storageclass cbs -p ‘{“metadata”: {“annotations”:{“storageclass.kubernetes.io/is-default-class”:“false”}}}’

2. 是否启用DefaultStorageClass准入控制器

使用如下指令启用指令控制器:

kube-apiserver --enable-admission-plugins=DefaultStorageClass

该准入控制器会监测没有指定任何StorageClass的pv创建, 并自动向其添加默认存储类。因此在没有开启该控制器时,由于没有填入默认存储类,最终导致动态卷供应的禁用。

3. 查看所使用StorageClass Provisioner的日志

由于每个StorageClass其实都会启动一个对应的容器,因此可以通过查看当前使用的StorageClass(默认或指定)的日志,定位具体的问题。
使用如下指令查看所有pod的名称:

kubectl get pods -A

使用如下指令查看相关Provisioner的日志:

kubectl logs -f cbs-provisioner-5bf7bb45f-2q5fg -n kube-system

在日志中会输出具体的绑定失败原因。我所遇到问题的原因:默认的StorageClass定义的规则是必须创建10G以上的pv,而在pvc中声明的仅为8G,因此通过动态卷供应策略无法创建出满足pvc条件的pv,最终导致绑定失败。修改后pvc中的size为10G后问题解决。

概述事情的起因是基于k8s集群搞东搞西搞项目时,使用脚本一键部署平台时突然僵住了,直接返回超时信息,通过各种手段对 shell 脚本进行debug,最终定位到是在使用yaml文件创建pod时一直卡在下面这步:PersistentVolumeClaim is not bond。当然,这只是其中一条not boud的debug信息,整个部署中的和存储存储相关的组件,mysql、redis、mogodb和minio全都处于这种状态,查询相关pod,全都处于pending状态,等于压根没起来,查看pod的详细
pod 一直处于Pending 状态 pod has un bound immediate Persistent Volume Claim s kubectl logs nfs-client-provisionerxxx ( pv NFS) pod selfLink was empty, can’t make reference [root@hadoop03 NFS]# kubectl get pod -n nfs-client NAME R
1、环境介绍 K8S +openstack-cloud-controller-manager对接OpenStack Cinder 为 K8S 提供 PV 后端 storageclass已经创建好 # kubectl get sc NAME PROVISIONER RE CLAIM POLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION...
pod has un bound immediate Persistent Volume Claim s : statefulset挂载不上 pv 的另一种情况 问题 描述:第一次安装harbor的时候没有设置trivy的storageClass,后来修改statefulset的时候报错 Error: UPGRADE FAILED: cannot patch “harbor-harbor-trivy” with kind StatefulSet: StatefulSet.apps “harbor-harbor-trivy
v1.10.2 遇到 问题 : 使用 docker-compose down命令关闭harbor,然后使用./install.sh --with-chartmuseum命令重新安装带chart仓库的harbor,然后发现启动不了,报以下错误: [Step 5]: starting Harbor ... Creating network "harbor_harbor" with the default driver Creating network "harbor_harbor-chartmu https://kubernetes.io/zh/docs/concepts/storage/storage-classes/ https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application/ https://github.com/kubernetes-retired/external-storage/tree/master/nfs https://www.jianshu.com/p/65ed4 1、本次 问题 出现,新创建statefulset的pod无法正常创建 pv Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling <unknown> 这个报错是因为 pvc 没有和 pv 关联起来,我这边的 PVC 是创建pod的时候自动创建的,可以手动把 pv PVC 关联或者创建StorageClass让 pv PVC 自动关联 我这边是修改yaml手动关联 解决 的 在 pv 的yaml文件添加如下内容spec处添加 claim Ref: kind: Persistent Volume Claim namespace: 命名空...
导语:有一个需求 密钥需要挂载到不同容器,并且在代码里更新指定密钥文件,并重启对应容器。原先不需要更改和重启时,是使用configmap实现的。但是现在需要多个容器共享一个文件并且需要被更新,这个就无法使用configmap实现了。考虑使用 pv pvc 。 使用 pv pvc 遇到的 问题 ,疯狂报以下错 Warning FailedScheduling 28s default-scheduler 0/1 nodes are available: 1 pod has un bound immediate
你提到了一个 XML 异常,即 "Namespace 'wx' is not bound "。这个错误通常出现在 XML 文档中,表示命名空间 'wx' 没有绑定或声明。 在 XML 中,命名空间用于避免元素和属性名称的冲突。当使用命名空间时,需要在 XML 文档中声明或绑定命名空间。如果在使用命名空间时没有正确绑定,就会出现这个异常。 要 解决 这个 问题 ,你可以检查以下几个方面: 1. 确保在 XML 文档的根元素或相关元素上正确声明或绑定命名空间。例如,可以使用类似于以下的声明语句: xmlns:wx="http://example.com/wx" 2. 确保在使用命名空间前正确引用了声明的命名空间。例如,可以在使用 'wx' 命名空间的元素或属性前添加 'wx:' 前缀,以指示其所属的命名空间。 3. 检查命名空间的 URI 是否正确。可能存在 URI 拼写错误或命名空间定义不一致的情况。 希望这些提示能够帮助你 解决 "Namespace 'wx' is not bound " 这个异常 问题 。如果 问题 还没有 解决 ,请提供更多的上下文信息,我会尽力帮助你。