PV的全称是:PersistentVolume(持久化卷),是对底层的共享存储的一种抽象,PV由管理员进行创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如Ceph、GlusterFS、NFS等,都是通过插件机制完成与共享存储的对接.
但是通过PVC请求一定的存储空间也很有可能不足以满足对于存储设备的各种需求,而且不同的应用程序对于存储性能的要求也能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes又为我们引入了一个新的资源对象:StorageClass,通过StorageClass的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据StorageClass的描述就可以非常直观的知道各种存储资源特性了,这样就可以根据应用的特性去申请合适的存储资源了.
Kubernetes支持两种资源的供应模式:静态模式(Staic)和动态模式(Dynamic)。资源供应的结果就是创建好的PV.
静态模式:管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置
在用户定义好PVC后,系统将根据PVC对存储资源的请求(存储空间和访问模式)在已存在的PV中选择一个满足PVC要求的PV,一旦找到,就将PV与用户定义的PVC进行绑定,然后用户的应用就可以使用这个PVC了。如果系统中没有满足PVC要求的PV,PVC则会无限期处于Pending状态,直到等到系统管理员创建了一个符合要求的PV。PV一旦绑定在某个PVC上,就被这个PVC独占,不能再与其他PVC进行绑定了。在这种情况下,当PVC申请的存储空间比PV的少时,整个PV的空间都能够为PVC所用,可能会造成资源的浪费。如果资源供应使用的是动态模式,则系统在PVC找到合适的StorageClass后,将会自动创建PV并完成PVC的绑定
Pod使用volume的定义,将PVC挂载到容器内的某个路径进行使用。volume的类型为persistentVoulumeClaim,在容器应用挂载了一个PVC后,就能被持续独占使用。不过,多个Pod可以挂载同一个PVC,应用程序需要考虑多个实例共同访问一块存储空间的问题
当用户对存储资源使用哪个完毕后,用户可以删除PVC,与该PVC绑定的PV将会被标记为已释放,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还留在存储设备上,只有在清除之后该PV才能继续使用.
对于PV,管理员可以设定回收策略(ReclaimPolicy)用于设置与之绑定的PVC释放资源之后,对于遗留数据如何处理。只有PV的存储空间完成回收,才能供新的PVC绑定和使用。
1.静态资源下,通过PV和PVC完成绑定,并供Pod使用的存储管理机制
2.动态资源下,通过StorageClass和PVC完成资源动态绑定(系统自动生成PV,并供Pod使用的存储管理机制
由于容器本身是非持久化的,因此需要解决在容器中运行应用程序遇到的一些问题。首先,当容器崩溃时,kubelet将重新启动容器,但是写入容器的文件将会丢失,容器将会以镜像的初始状态重新开始;第二,在通过一个Pod中一起运行的容器,通常需要共享容器之间一些文件。Kubernetes通过存储卷解决上述的两个问题。
spec.volumes:通过此字段提供指定的存储卷spec.containers.volumeMounts:通过此字段将存储卷挂载到容器中
当前Kubernetes支持如下所列的存储卷类型,并以hostPath、nfs和persistentVolumeClaim类型的存储卷为例,介绍如何定义存储卷,以及如何在Pod中被使用.
*awsElasticBlockStore*azureDisk*azureFile*cephfs*configMap*csi*downwardAPI*emptyDir*fc(fibrechannel)*flocker*gcePersistentDisk*gitRepo*glusterfs*hostPath*iscsi*local*nfs*persistentVolumeClaim*projected*portworxVolume*quobyte*rbd*scaleIO*secret*storageos*vsphereVolumexample1EmptyDir(两个Pod目录互相挂载)EmptyDir是一个空目录,他的生命周期和所属的Pod是完全一致的,他用处是把同一Pod内的不同容器之间共享工作过程产生的文件,
Pv和Pvc是K8s的一种标准资源,Pvc被Pv调用后就会被绑定起来,取决于用户怎么绑,
因为pvc属于集群资源级别的不能定义在名成空间
通过PV的capacity属性来设置存储空间,目前仅支持storage=数据大小,未来可能会加入IOPS、吞吐量等指标配置
AccessModes访问模式
AccessModes是用来对PV进行访问模式的设置,用于描述用户应用对存储资源的访问权限
ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
ReadOnlyMany(ROX):只读权限,可能被多个节点挂载
ReadWriteMany(RWX):读写权限,可以被多个节点挂载
注意:一些pv可能支持多种访问模式,但挂载时候只可以使用一种访问模式,多种访问模式不奏效
PV实际上没有存储,相当于我们node一样,还需要创建Pod进行消费,接下来我们进行PVC的创建与配置
由于我们的index.html直接挂在到了/data1/k8s目录下面,如果有很多个pod都使用pvc进行挂载,会造成我们数据目录的文件比较乱
这里我们添加一个subpathsubPath的目的是为了在单一Pod中多次使用同一个volume而设计的。
NFS存储的缺点
不支持动态创建持久卷,只能手工创建先手工创建PV,再通过PV手工创建PVC,PVC就是真正可用的持久卷
PVC是和PV进行绑定的:PVC会根据自己需求空间的大小自动选择合适的PV,比如需要一个5G的PVC,PV分别为2G,7G和10G,那么PVC会自动选择7G的,但是剩余的空间不是浪费了么?原因如下:一个被绑定的PV只能用于一个PVC,他们是一对一绑定的,如果PVC大小只需要5G,但是所选的PV有7G,那么剩余的2G是没办法使用的,如果不想这样浪费空间只能使用动态创建的方式.