一、PVC:

(1)

背景:

k8s到底支持多少种存储。我们使用kubectl explain pods.spec.

kubectl explain pods.spec.volumes 查看pod支持哪些存储

 

当一个用户去使用K8s功能,在集群中创建pod时,为了实现持久能力,我们得在Pod中定义持久卷。我们需要定义一些参数,以rbd为例:kubectl explain pods.spec.volumes.rbd为例

我们为了写一个pod的配置清单,你首先得是rbd的用户,得知道是哪个存储服务,你的存储服务地址是什么,认证信息是什么等等。你得对目标存储非常了解才行,这样会阻断一大部分用户没办法使用k8s的。存储又很多种,rbd只是其中一种,如果我们使用的glusterfs,用户得对glusterfs了解,怎么用,怎么接,什么意思呀,有什么关系。这样对我们的用户要求就太高了。

我们要怎么转化为傻瓜的形式。这个时候就需要用到PVC了。

概念:

PVC指的是什么,当你要使用存储卷的时候,用户只需要告诉我需要来个存储卷,所以叫做存储卷创建申请。用户不需要底层的存储系统是什么。用户只需要明确需求就行:比如需要多少G的存储空间,用户不用管存储存放在哪个存储系统之上,这叫存储即服务。用户想要,只需要一条命令来一个就行。让我们的pod创建与底层的存储解耦了。

(2)PVC与PV的绑定:

(3)编辑PVC:

 

 (四)使用:

二、PV:

 (1)理论

POD关键要与PVC建立关联关系,PVC关键要与pv建立关联关系,PV关键要与存储系统建立关联关系。

静态PV:

这里有个节点,创建pod的时候刚好调度到这个节点上,我们要在这个pod定义的时候定义pvc。这个pvc要怎么做呢,这个PVC要关联到pod所在的名称空间,在当前的名称空间建立一个pvc真正存在的资源,pod用PVC,这个PVC在名称空间存在才行。

以上是第一个,第二个,pvc只是一个申请,申请要与谁建立关联关系呀,要与PV建立关联关系。PVC也只是一个形式,这个事情不是pod事情的,或者pod一申请,就要到pod所在的名称空间创建一个PVC,这个PVC要真正实现存储,需要与PV建立关联关系。

PV是什么,PV才是真正存储系统之上的一段存储空间。这样子会使得路径增长了,结果就是以后pod的创建者只需要声明需要pvc就行,我需要创建存储卷,需要多大,叫什么名字就行了。要怎么创建呢,要管理员而不是用户,比如运维工程师或者程序员创建PVC、pv来(手动)

而后,这个PV的创建需要与后端的存储建立关联关系。

 

动态PV:

大家发现这个事情就很麻烦,你不知道用户什么时候去创建POD,你不知道POD创建需要多少存储,因此,这个PVC请求与哪个PV建立关联关系时,怎么可能刚好有个PV好好等你用它,要做到这一步,用户在创建之前先提需求,然后后端存储工程师或者k8s管理员把PV创建好,随后用户创建Pod时,激活PVC,绑定PV(手动)。但是,如果你是公有云呢,你有很多租户在你系统上跑,压根不知道他什么时候创建pod,这就麻烦大了。因此,如果要做到按需创建,还有个办法,我们把所有的存储抽象出来,抽象为一个存储层,叫做存储类,当用户创建PVC需要用到PV时,它能够向抽存储类申请说,你帮我创建出来,存储这会自动帮他生成刚好符合用户需要的PV。这种PV由用户的请求触发而动态生成,我们称为PV的动态供给。

(2)PV的访问模式:

ReadWriteOnce  (RWO)  ---  可以由单个节点以读写方式挂载

ReadWriteMany(RWX) ---   卷可以被许多节点以读写方式挂载

ReadOnlyMany(ROM) ---    卷可以被多个节点以只读方式挂载

备注:即使volume支持很多种访问模式,但它同时只能使用一种方式来映射。

eadWriteOncePod——卷可以由单个 Pod 以读写方式挂载。这仅支持 CSI 卷和 Kubernetes 1.22+ 版。

1)

readWriteOnce 中的 Once 指的是可以使用PVC的节点数,而不是Pod数(HPA或没有HPA);

果PVC指定 ReadWriteOnce ,则在第一个Pod被调度之后,任何其他Pod将需要在同一节点上被调度或者根本不被调度(最常见的情况:没有 节点上有足够的资源)。 

在只有一台可调度节点的情况,即使RWO也是能够被多个Pod同时使用的,但除了开发测试,有谁会这么用呢?

2)

RWX

应用场景:文件类的存储能够支持ReadWriteMany而所有的块存储,无论是公有云,还是Ceph, iSCSI,都无法支持

一般用于:主节点上可读可写

3)ROX的应用场景:一般用于从节点上。

重要:一个“卷”一次只能使用一种访问模式挂载,即使它支持多种访问模式。例如,GCEPersistentDisk可以由单个节点挂载为ReadWriteOnce或由多个节点挂载为ReadOnlyMany,但不能同时挂载。

例子:

多个实例之间需要一个共享的卷作为挂载目录。这个共享卷就是一个典型的readrwritemany的需求,当wordpress实例需要快速横向扩展的时候,新扩展的实例可以直接访问原有的用户上传的数据,不需要复制等操作,因为大家共享的是一份数据,这种需求对于不支持readwritemany的块存储来说,就非常尴尬了。比如有人需要一个容器平台上运行wordpress的方案,需要在多个pods上同时访问同一份数据(master上可读可写,其他节点只读

(3)控制器与卷的模式:

建议使用statefulset,以便每个副本都有自己的PV。

建议不要使用一个“readwriteonce”卷的“副本”进行部署。因为默认部署策略将在重新第一个pod之前创建第二个pod。部署可能在死锁中失败,因为第二个pod无法启动,因为readwriteonce volume已经在使用中,并且第一个pod不会被删除,因为第二个Pod尚未启动。而是使用带有readwriteonce卷的stateful。

statefuleset是部署有状态应用程序的推荐方法,这些应用程序需要每个副本具有唯一的卷。通过将statefuleset与持久卷声明模板一起使用,你可以使用与每个副本pod关联的唯一持久卷声明制动扩展的应用程序。

(4)PV和PVC的生命周期

供应---绑定---使用---释放---回收:

1)一个PV创建完成后状态会变成available,等待被PVC绑定。一旦被PVC绑定,PV的状态会变成bound,就可以被定义了相应PVC的pod使用。pod使用完后被释放PV,PV的状态变成

released。变成released的PV会根据定义的回收策略做相应的回收工作。有三种回收策略,retain、delete和recycle。retain就是保留线程,k8s什么也不做,等待用户爽去处理PV里的数据,处理完成后,在手动删除PV。delete策略,k8s会自动删除改PV以及里面的数据。recycle方式,k8s会将PV里的数据删除,然后把PV的状态变成available,又可以被新的PVC绑定使用。

2) 创建PV和pvc,pvc和pv之间没有依靠ID、名称或者label匹配,而是靠容量和访问模式 ,PVC的容量和访问模式需要是某个PV的子集才能自动匹配上。

注意:PVC和PV是一对一的,也就是一个PV被一个PVC自动匹配后,不会再被其他PVC匹配了,即使PVC需求能够完全满足。

 

 

 三、存储类(storageclass实验)

(一)理论

动态PV需要依赖一个前提,我们需要定义好存储类。什么叫做存储类呢:

不同的存储类型。它可以动态的自动的创建所需要的PV

volumeClaimTemplates实现了pvc的自动化(stateful控制器),StorageClass实现了pv的自动化

 

(2)创建StorageClass

1)StorageClass对象会定义下面两部分内容:

 第一,PV的属性。比如,存储类型,Volume的大小等:每个 StorageClass 都包含 存储插件供给者provisioner、供给者参数parameters 和回收策略 reclaimPolicy 字段。

 第二,创建这种PV需要用到的存储插件,即存储制备器。

有了这两个信息之后,Kubernetes就能够根据用户提交的PVC,找到一个对应的StorageClass,之后Kubernetes就会调用该StorageClass声明的存储插件,进而创建出需要的PV。

 

2)但是其实使用起来是一件很简单的事情,你只需要根据自己的需求,编写YAML文件即可,然后使用kubectl create命令执行即可。

(二)实验:

可以了解到Kubernets实现数据持久化的流程为:搭建NFS底层存储——>创建PV——>创建PVC——>创建pod

静态(手动):

(1)搭建NFS后端存储

(2)创建PV、PVC

 

(3)使用pvc创建Pod。Pod通过volumes来声明使用哪个PVC,直接使用PVC的名字即可,可见在创建Pod时无需再关心共享存储的细节了。Pod会向存储卷中写入数据。 

(4)在NFS服务器中查看,确实有文件生成:

 动态(自动):

(1)搭建NFS后端存储

(2)

 1)创建Service Account:这是用来管控NFS Provisioner 在k8s集群中运行的权限

2)创建StorageClass:负责建立PVC并调用NFS provisioner进行预定的工作,并让PV与PVC建立关联

3)创建NFS provisioner:有两个功能,一个是在NFS共享目录下创建挂载点(volume),另一个则是建了PV并将PV与NFS的挂载点建立关联

 

 (3)测试

1)创建pod,申请PVC进行测试

2)集合StatefulSet测试

 

 

 

 

 

 

 

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐