数据管理
pod和容器是短暂的,具有很短的生命周期,会被频繁的创建和销毁,容器销毁的时候,保存在容器内部的文件系统的数据也会被销毁。
为了持久化保存数据,可以使用kubernetes volume。本质上,它是一个目录,和docker类似,当它被mount到pod中的时候,pod中的所有容器都可以访问这个volume。它支持多种backend,像emptyDir,hostPath,NFS,Ceph等,它提供了各种backend的抽象,在使用的时候不需要关心数据是存放在本地还是云硬盘上。
1、emptyDir是最基础的volume类型,一个emptyDir volume是host主机上的一个空目录,它对于容器来说是持久化的,对于pod来说则不是,当pod从节点删除的时候,volume的内容也会被删除,但如果只是容器被销毁而pod还在,则volume还在,也就是说它的生命周期和pod保持一致。pod内的容器都可以共享mount,他们可以自定义各自的mount路径。
比如:
1 | apiVersion: v1 |
这里我们模拟了一个producer-consumer的场景,pod中存在两个容器,他们共享一个volume。producer负责写数据,consumer负责读数据。最下面定义了一个emptyDir类型volume:
- producer容器将shared-volume mount到producer_dir目录
- producer通过echo向其写数据
- consumer容器将其mount到consumer_dir目录
- consumer读取数据
我们可以通过kubectl logs查看:
然后kubectl describe查看一下:
从上面两张图可以看出,他们共享一个volume。
因为emptyDir是docker host文件系统的目录,相当于执行了docker run -v producer_dir和docker run -v consumer_dir。emptyDir是一个临时目录,其优点是能够方便的为pod内的容器临时提供共享存储,不需要额外的配置,它不具备持久性。
2、hostPath
hostPath是将docker host文件系统中已经存在的目录mount给容器。大部分应用都不会使用它,因为这个增加了pod与节点的耦合,限制了pod的使用。不过那些需要访问k8s或者docker内部数据的应用则需要使用hostPath(比如kube-apiserver和kube-controller-manager)
3、pv和pvc
persistentVolume(PV)和persistentVolumeClaim(PVC)是k8s提供的两种API资源,用于抽象存储细节,管理员关注于如何通过PV提供存储功能而无需关注用户如何使用,同样的,用户只需要挂载PVC到容器中而不需要关注存储卷采用何种技术实现。
PVC和PV的关系与pod和node关系类似,前者消耗后者的资源。PVC可以向PV申请指定大小的存储资源并设置访问模式。
PV和PVC遵循以下声明周期:
-
供应准备:通过集群外的存储系统或者云平台来提供存储持久化支持。
- 静态提供:管理员手动创建多个PV,供PVC使用
- 动态提供,动态提供:动态创建PVC特定的PV,并绑定
-
绑定:用户创建PVC并指定需要的访问资源的访问模式,在找到可用的PV之前 ,PVC会保持未绑定状态。
-
使用:用户可在pod中像volume一样使用PVC
-
释放:用户删除PVC来回收存储资源,PV将变成released状态,由于还保留着之前的这些数据,这些数据需要根据不同的策略来处理,否则这些存储资源无法被其他PVC使用。
-
回收:PV可以设置三种策略,(a)保留(Retain),允许人工处理保留的数据;(b)回收(Recycle),将执行清除策略,之后可以被新的PVC使用,需要插件支持;©删除(Delete),将删除PV和外部关联的存储资源
目前只有NFS和hostpath类型支持回收策略。
两种方式提供的PV资源供给:
1、static
通过集群管理者创建多个PV,为集群使用者提供存储能力而隐藏真实存储的细节,并且存在于kubernetes api中,可被直接使用。
2、dynamic
动态卷供给是kubernetes独有的功能,这一功能允许按需创建存储卷,在此之前,集群管理员需要事先在集群外由存储提供者或者云提供商创建。
存储卷成功之后再创建PV对象,才能够再kubernetes中使用。动态卷供给能让集群管理员不必进行预先创建存储卷,而是随着用户需求进行创建。
要使用pv/pvc的存储方式,就必须要有一个共享的文件目录,让k8s集群内的所有服务器全部都可以访问到,所以先搭建一个nfs服务。
1、搭建nfs
2、创建PV的配置文件
1 | apiVersion: v1 |
其中:
- accessModes:指定访问模式,支持三种:ReadWriteOnce,PV以read-write挂载到单个节点上;ReadOnlyMany,以read-only的方式挂载到多个节点上;ReadWriteMany,以read-write的方式挂载到多个节点上。
- persistentVolumeReclaimPolicy:指定PV的回收策略;
- storageClassName:指定PV的class,相当于为PV设置了一个分类,PVC可以指定class申请相应class的PV
默认的回收策略为reatain(保留),状态为available,是因为还没有绑定到任何的PVC上面,当定义好pvc以后,两个就可以进行绑定。
3、创建PVC
1 | apiVersion: v1 |
通过绑定PVC和PV,表明这个PVC希望使用 storageClassName: nfs 的PV。PVC向PV申请存储空间,并且通过selector指定与label名为nfs-pv的pv相匹配。
此时在查看:
4、将PVC挂载到相应的容器里面
1 | apiVersion: v1 |
5、验证
创建共享文件,并进入到容器查看: