pod 自身具有生命周期,因此其内部运行的容器及相关数据无法完成持久化,docker支持配置容器使用存储卷将数据持久存储于自身文件系统之外的存储系统,其可以是节点文件系统或网络文件系统。相应的kubernetes 提供的存储卷属于pod资源级别,共享与pod内的所有容器,可用于在勇气的文件系统之外存储应用程序的相关数据,甚至还可独立于pod生命周期之外实现数据持久化
存储卷: 定义在pod资源之上,可被其内部的所有容器挂载的共享目录,它关联至某外部的存储设备之上的存储空间,从而独立于容器自身的文件系统,而数据是否具有持久能力则取决于存储卷自身能否支持持久化
empty: 其生命周期和pod资源相同 hostpath:其虽然可实现持久化存储,但若pod被调度至其他节点,则该节点的存储资源需要被迁移到指定节点,否则将无法持久化
nfs ceph glusterfs ... 其可实现数据的持久化存储
secret: 用于向pod传递某些敏感信息,如密码、私钥、证书等。 configmap:用于向pod中注入非敏感数据,如配置文件,其可实现容器配置文件集中化定义和管理
pod中定义的存储有两部分组成: 1 pods.spec.volumes: 用于定义在pod之上挂载的存储卷列表,及存储的来源 核心字段 pods.spec.volumes.name : 用于定义此存储卷的名称,下面的挂载中需要通过此名称关联此存储卷 pods.spec.volumes.type:用于指定此存储卷的类型, 如emptydir、nfs、gitrepo等
2 pods.spec.containers.volumemounts : 用于定义存储卷被挂载到pod的位置及其相关的挂载形式 pods.spec.containers.volumemounts.mountpath :用于定义挂载到目标容器的具体位置,如/usr/share/nginx/html pods.spec.containers.volumemounts.name: 用于引用上述存储卷名称。 pods.spec.containers.volumemounts.readonly : 指定存储卷是否为只读存储卷。默认为false,及为读写存储卷。 pods.spec.containers.volumemounts.subpath: 定义挂载存储卷时使用的子路径,及在mountpath指定的路径下使用一个子路径作为其挂载点。
emptydir 存储卷生命周期与其pod相同,其长用于对数据缓存或临时存储,数据的共享等。 gitrepo 存储卷可以看做是emptydir存储卷的一种实际应用,使用该存储卷的pod创建资源可以通过挂载目录访问指定的代码仓库中的数据,使用gitrepo存储卷的pod资源在创建时,会首先创建一个空目录(emptydir)并克隆(clone)一份指定的git仓库中的数据到该目录,而后再创建容器并挂载该存储卷。
pods.spec.volumes.emptydir 其主要包含两个字段 pods.spec.volumes.emptydir.medium:此目录所在的存储介质类型,取值有"default"或 "memory",默认为"default",表示使用节点的默认存储介质。"memory"则表示基于ram的临时文件系统tmpfs,空间受限于内存,但性能好,通常用于为容器中提供缓存空间。 pods.spec.volumes.emptydir.sizelimit: 用于指定当前存储卷的限额,默认为nil,表示不限制。
实例
部署
查看
测试
pods.spec.volumes.gitrepo.repository: git仓库url,其是必选字段 pods.spec.volumes.gitrepo.directory: 目标目录名称,名称中不能包含".."字符,"."表示将仓库中的数据直接复制到卷目录中,否则,为复制到卷目录中以用户指定的字符串为名称的子目录中。 pods.spec.volumes.gitrepo.revision: 特定的revision提交的哈希码。 使用gitrepo存储卷的pod资源运行的工作节点上必须安装git程序,否则克隆仓库的操作将无法完成,在1.12起,gitrepo存储卷已经被废弃。
yum -y install git
hostpath 类型的存储卷时将工作节点上某个文件系统的目录或文件挂载到pod中的一种存储卷,可独立于pod资源的生命周期,因此具有持久性,但其在本地,因此只能应用于特定情况下的存储卷的使用需求。
配置 hostpath 存储卷的嵌套字段共有两个: 1 用于指定工作节点上的目录路径的必选字段 pods.spec.volumes.hostpath.path 2 指定存储卷类型type,它支持使用的卷类型包含 pods.spec.volumes.hostpath.type a directoryorcreate: 指定的路径不存在时自动将其创建为权限为0755的空目录,属主属组均为kubelet; b directory: 必须存在的文件路径 c fileorcreate: 指定的路径不存在时自动将其创建的权限为0644的空文件,属主和属组同样是kubelet。 d file: 必须存在的文件路径 e socket: 必须存在的socket 文件路径 f chardevice: 必须存在的字符设备文件路径 g blockdevice: 必须存在的块设备文件路径
这类pod资源通常受控于daemonset类型的pod控制器,起运行与集群中的每个工作节点上,负责收集工作节点上系统级别的相关数据,但其不同节点的文件或许不完全相同,于是,那些要求事先必须存在的文件或目录的满足状态也可能会不同,在节点中创建的文件或目录默认仅有root可写,若期望容器内的进程有写权限,则要么将其设置为特权容器,要么修改节点上的目录路径权限。
专用的网络存储卷: 1 传统的nas或sam设备(如 nfs,iscsi,fc) 2 分布式存储 (clusterfs,rbd) 3 云端存储 4 构建在各类存储系统上的抽象管理层等
pods.spec.volumes.nfs nfs 存储卷在pod对象终止后仅仅是被卸载而非删除,其能够实现调度的持久化存储 核心字段: pods.spec.volumes.nfs.server : 用于指定nfs服务器的ip地址或主机名,必选字段 pods.spec.volumes.nfs.path: nfs 服务到处的文件系统路径,必选字段 pods.spec.volumes.nfs.readonly:是否以只读方式挂载,默认为false。
1 部署无密码的nfs 服务。部署结果如下
2 配置相关实例并进行部署
配置相关网页
测试结果
.
glusterfs (cluster filesystem)是一个开源的分布式文件系统,是水平扩展存储解决方案gluster的核心, glusterfs 通过扩展能够支持数pb存储容量和处理数千客户端,glusterfs 借助tcp/ip 或 infiniband rdma网络将物理分布式的存储资源聚集在一起,使用单一全局名称空间来管理数据,另外,glusterfs 基于可堆叠的用户空间设计,可为各种不同数据负载提供优异的性能,是另一种流行的分布式存储解决方案,要配置pod资源使用glusterfs存储卷,需满足: 1 存在某可用的glusterfs 存储集群 2 glusterfs 集群中创建一个能满足pod资源数据存储需要的卷 3 在k8s 集群内的各个节点上安装glusterfs客户端程序包
另外,若需要基于glusterfs使用存储卷的动态供给机制,还需要事先部署heketi,他用于为glusterfs集群提供restful 风格的管理接口,glusterfs 几圈及hekei 的配置包含
endpoints<string>: endpoints 资源的名称,此资源要事先存在,用于提供gluster集群的部分节点信息作为其访问入口,必选字段 path <string>: 用于到glusterfs集群的卷路径,如kube-redis,必选字段 readonly<boolean>: 是否为只读卷
注意 部署实例请参考 :https://blog.csdn.net/phn_csdn/article/details/75153913?utm_source=debugrun&utm_medium=referral 需在节点上安装 yum install -y glusterfs glusterfs-fuse
一个节点创建一个文件夹,其他节点均可见
在其中注入内容
对象存储节点查看
访问测试
上述网络存储卷的缺点是:管理员用户必须清晰了解所用到的网络存储系统的访问细节才能完成存储卷相关的配置任务,这与kubernetes的向用户和开发隐藏底层架构的目标相背离,对于存储资源的好是能够像计算资源一样,用户和开发人员无需了解pod资源挂载情况,无需了解存储系统是什么设备以及位于何处,为此,kubernetes的persistentvolume子系统在用户与管理员之间添加了一个抽象层,从而使得存储系统的使用和管理直接解耦
对底层共享存储的抽象,将共享存储作为一种可由用户申请使用的资源,实现了"存储消费"机制,通过存储插件,pv支持使用多种网络存储或云端存储等多种后端存储系统。如nfs、rbd和cinder等。pv 是集群级别的资源,其不属于任何名称空间,用户对pv资源的使用需要pvc(persistendvolumeclaim)提出申请来完成绑定,是pv资源的消费者,其向pv申请特定大小的空间及相关的访问模式,从而创建出pvc存储卷,而后再由pod资源通过persistentvolumeclaim 存储卷关联使用。
尽管pvc使得用户可以以抽象的方式访问存储资源,但很多时候还是会涉及pv的不少属性,其两者衔接方面的偏差必然导致用户的需求无法及时得到有效满足。自kubernetes 1.4 版本来时引入了storageclass资源类型,其可用于将存储资源定义为具有显著特性的类别(class)而不是具体的pv,用户通过pvc 直接向意向的类别发出申请,匹配由管理员事先创建的pv,或者由其按需为用户动态创建的pv,这样做便免去了事先创建pv的过程。
各存储卷支持的读写模式
available : 可用状态的自由资源,尚未被pvc绑定 bound: 已经被绑定的pvc released: 绑定的pvc已经被删除,但资源尚未被集群回收 failed : 因自动回收资源失败而处于故障状态
persistentvolumeclaim 是存储卷类型资源,通过申请占用某个pv 而创建,其与pv是一对一的关系,用户无需关心底层实现细节,只需指定目标空间大小,访问模式、pv标签选择器和storageclass等相关信息即可。
创建pvc
查看服务
pods.spec.volumes.persistentvolumeclaim.claimname 绑定的pvc的名称,必选字段 pods.spec.volumes.persistentvolumeclaim.readonly 绑定的模式
存储类(storageclass)简称sc,其是kubernetes资源类型中的一种,是由管理员为管理pv方便而按需创建的类别,其可理解为pv的特性描述 通过向后端存储传输信息而达到和前端匹配的效果 存储类的好处之一就是支持pv的动态创建,用于用到持久性存储时,需要通过创建pvc来绑定匹配的pv,此类操作需求量较大,或当管理员创建的pv无法满足pvc 需求时,系统按pvc 的需求标准动态创建适配的pv会为存储管理带来极大灵活性。 pvc 通过对存储类的申请而获取到pv
存储类对象的名称至关重要,是用户调用的标识,创建存储类,除了名称外,还需要为其定义三个关键字段 : provisioner(sc.provisioner 供给方)、parameter (参数 sc.provisioner)和 reclaimpolicy(回收策略sc.reclaimpolicy)
上述所需的环境请参考 :https://www.cnblogs.com/breezey/p/8849466.html kubernetes 节点上须有heketi 的key,需要有heketi-client 软件,必须要加载内核模块modprobe dm_thin_pool
如果有密码认证,则编码之前hekei的密码
下属实例中有密码认证
2 动态pv供给
动态pv供给的启用,需要实现由管理员创建至少一个存储类,不同的provisoner 的创建方式各不相同。
支出存储类的存储资源
目前,在pvc的定义中指定使用的存储类资源的方式有两种:一种是使用pvc.spec.storageclassname,另一种是使用"volume.beta.kubernetes.io/storage-class" 资源注解,建议使用第一种方式,以免出现设置不同导致的错误配置问题。 任何支持pv动态供给的存储系统都可以在定义为存储类后由pvc动态申请使用,存储卷是必备资源,随着规模的变化,其也会随之而变动
配置pvc
pv 是集群级别资源,而pvc则是资源需求,pvc发起对pv的申请,则两个绑定,其pv和pvc是一一对应的关系,可用于响应pvc的pv必须能够容纳pvc的请求条件
静态供给是由集群管理员手动创建的一定数量的pv的资源供给方式,这些pv负责处理存储系统的细节,并将由其抽象成易用的存储资源供用户使用,静态提供的pv可能属于某存储类,也可能没有存储类
不存在某静态的pv匹配到用户的pvc申请时,kubernetes集群会尝试为pvc动态创建符合需求的pv,此即为动态供给,这种方式依赖于存储类的绑定,pvc必须向一个事先存在的存储类发起动态分配pv的请求,没有指定存储类的pvc请求将会被禁止使用动态创建pv的方式。
用户基于一系列存储需求和访问模式定义好pvc后,kubernetes系统的控制器即会为其查找匹配的pv,并于找到之后二者之间建立其关系,而后他们二者状态转换为绑定状态,若pv是为pvc而动态创建的,则该pv专用于其pvc。 若是无法为pvc找到可匹配的pv,则pvc将一直处于未绑定状态,直到符合条件的pv出现并完成绑定方才可用
1 存储使用 pod资源基于pod.spec.volumes.persistentvolumeclaim卷类型的定义,将选定的pvc关联为存储卷,而后即可为内部的容器使用,对于支持多中访问方式的存储卷来说,用户需要额外指定使用模式,一旦完成将存储卷挂载至pod对象内的容器中,其应用即可使用关联的pv提供存储空间
2 pvc 保护 为了避免使用中的存储卷被移除而导致数据丢失,自kubernetes 1.9 开始当pod资源占用此pvc时,其不能删除pvc。
完成存储卷的使用目标之后,即可删除pvc对象以便进行资源回收,策略如下
留存就是在删除pvc后,kubernetes不会自动删除pvm而仅仅是将其置于释放状态,不过,此状态的pv尚且不能被其他pvc申请绑定,因为之前绑定成功的数据来存在,需要由管理员手动决定其后续处理方案,这就意味着,如果想要再次使用此类pv资源,则需要由管理员进行下面操作 1 删除pv,这之后,此pv的数据仍然存在于外部存储 2 手工清理存储之上遗留的数据 3 手工删除存储系统级的存储卷释放空间,以便再次创建或直接重新创建pv
如果可被底层存储插件支持,资源回收策略会在存储卷上执行数据删除操作并让pv资源再次变为可被claim。另外,管理员可配置一个自定义的回收器pod模板,以便执行自定义回收操作
对于支持delete回收策略的存储插件来说,在pvc被删除后会直接移除pv对象,同时移除的还有pv相关的外部存储系统上的存储资产,支持这种操作的存储系统有aws ebs、gce pd、azure disk 或 cinder,动态创建的pv资源的回收区别于相关存储类上的定义,存储类上相关的默认策略为delete。
kubernetes 从1.8版本开始增加了扩展pv空间的特定,目前其支持的扩展pvc 机制的存储卷有: gcepersistentdisk awselasticblockstore cinder rbd "persistentvolumeclaimresize"准入插件负责对支持空间大小变动的存储卷执行更多的验证操作,管理员需要事先启用此插件才能使用pvc扩展机制, 对于包含文件系统的存储卷来说,只有在新的pod资源基于读写模式开始使用pvc时才会执行文件系统大小的调整工作,换句话说,如果某被扩展的存储卷已经由pod资源使用,则需要重新创建此pod对象才能出发文件系统大小的调整操作。支持空间调整的文件系统有xfs、ext3和ext4