9.k8s持久化存储
在k8s 中为什么要做持久化存储?
在k8s 中部署的应用都是以pod 容器的形式运行的,假如我们部署MySQL、Redis 等数据库,需要 对这些数据库产生的数据做备份。因为Pod 是有生命周期的,如果pod 不挂载数据卷,那pod 被删除或 重启后这些数据会随之消失,如果想要长久的保留这些数据就要用到pod 数据持久化存储。
9.1 k8s持久化存储:emptyDir
常用的如下:
emptyDir
hostPath
nfs
persistentVolumeClaim
glusterfs
cephfs
configMap
secret
我们想要使用存储卷,需要经历如下步骤:
定义pod 的volume,这个volume 指明它要关联到哪个存储上的
在容器中要使用volumemounts 挂载对应的存储
经过以上两步才能正确的使用存储卷
emptyDir类型的Volume是在Pod分配到Node上时被创建,Kubernetes会在Node上自动分配一个目录,因此无需指定宿主机Node上对应的目录文件。这个目录的初始内容为空,当Pod从Node上移除时,emptyDir中的数据会被永久删除。emptyDir Volume主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。
#创建一个pod,挂载临时目录emptyDir
Emptydir 的官方网址: https://kubernetes.io/docs/concepts/storage/volumes#emptydir
由上可知,临时目录在本地的/var/lib/kubelet/pods/40dd430d-38ea-45c9-a6e7-5cf471853f44/volumes/kubernetes.io~ empty-dir/cache-volume下
9.2 k8s持久化存储: hostPath
hostPath Volume 是指Pod 挂载宿主机上的目录或文件。 hostPath Volume 使得容器可以使用宿主 机的文件系统进行存储,hostpath( 宿主机路径):节点级别的存储卷,在pod 被删除,这个存储卷还是 存在的,不会被删除,所以只要同一个pod 被调度到同一个节点上来,在pod 被删除重新被调度到这个 节点之后,对应的数据依然是存在的。
#创建一个pod,挂载hostPath 存储卷.
DirectoryOrCreate 表示本地有/data1 目录,就用本地的,本地没有就会在pod 调度到的节点自 动创建一个.
查看pod在哪个物理节点上
进入指定节点的物理机上,可以看到已经创建了存储目录/data1,这个/data1 会作为pod 的持久化存储目录
9.2.1 hostpath 存储卷缺点:
pod 删除之后重新创建必须调度到同一个node 节点,数据才不会丢失 可以用分布式存储: nfs,cephfs,glusterfs
9.3 k8s持久化存储:nfs
上节说的hostPath 存储,存在单点故障,pod 挂载hostPath 时,只有调度到同一个节点,数据才不会丢失。那可以使用nfs 作为持久化存储。
9.3.1 搭建nfs服务
9.3.1.1 以k8s的控制节点作为NFS服务端
1. 安装nfs服务器软件包
2. 创建共享目录
3.配置nfs共享
*(rw):允许所有客户端读写访问
sync:数据同步写入磁盘
no_root_squash:客户端 root 用户具有服务器 root 权限
no_subtree_check:关闭子目录检查(提高性能)
4. 重启服务并配置生效
5.客户端软件包
6.创建本地目录
7.手动挂载NFS共享
8.自动挂载
Pod 挂载nfs 的官方地址: https://kubernetes.io/zh/docs/concepts/storage/volumes/
注:path: /data/volumes #nfs 的共享目录 server:10.0.72.4 机器的ip,这个是安装nfs 服务的地址
进入容器验证一下
#上面说明挂载nfs 存储卷成功了,nfs 支持多个客户端挂载,可以创建多个pod,挂载同一个nfs 服务器共享出来的目录;但是nfs 如果宕机了,数据也就丢失了,所以需要使用分布式存储,常见的分 布式存储有glusterfs 和cephfs
9.4 k8s持久化 pvc
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes
9.4.1 k8s PV是什么
PersistentVolume(PV)是群集中的一块存储,由管理员配置或使用存储类动态配置。 它是集群中的资源,就像pod 是k8s 集群资源一样。 PV 是容量插件,如Volumes,其生命周期独立于使用PV 的任 何单个pod。
9.4.2 k8sPVC是什么?
PersistentVolumeClaim(PVC)是一个持久化存储卷,我们在创建pod 时可以定义这个类型的存储 卷。 它类似于一个pod。 Pod 消耗节点资源,PVC 消耗PV 资源。 Pod 可以请求特定级别的资源(CPU 和 内存)。 pvc 在申请pv 的时候也可以请求特定的大小和访问模式( 例如,可以一次读写或多次只读)。
9.4.3 k8s PVC和PV的工作原理
PV是群集中的资源。PVC是对这些资源的请求。 PV和PVC之间的相互作用遵循以下生命周期:
pv的供应方式
可以通过两种方式配置PV:静态或动态
静态
集群管理员创建了许多PV。它们包含可供群集用户使用的实际存储的详细信息。它们存在于 Kubernetes API 中,可供使用。
动态
当管理员创建的静态PV 都不匹配用户的PersistentVolumeClaim 时,群集可能会尝试为PVC 专门动 态配置卷。此配置基于StorageClasses,PVC 必须请求存储类,管理员必须创建并配置该类,以便进行 动态配置。
绑定
用户创建pvc 并指定需要的资源和访问模式。在找到可用pv 之前,pvc 会保持未绑定状态
使用
需要找一个存储服务器,把它划分成多个存储空间
k8s管理员可以把这些存储空间定义成多个pv
在pod中使用pvc类型的存储卷之前需要先创建pvc,通过定义需要使用的pv的大小和对应的访问模式,找到合适的pv;
pvc被创建之后,就可以当成存储卷来使用了,我们在定义pod时就可以使用这个pvc的存储卷
pvc和pv它们是一一对应的关系,pv如果被pvc绑定了,就不能被其他pvc使用了。
我们在创建pvc的时候,应该确保和底下的pv能绑定,如果没有合适的pv,那么pvc就会处在pending状态。
回收策略
当我们创建pod 时如果使用pvc 做为存储卷,那么它会和pv 绑定,当删除pod,pvc 和pv 绑定就会 解除,解除之后和pvc 绑定的pv 卷里的数据需要怎么处理,目前,卷可以保留,回收或删除: retain recycle delete。
retain
当删除pvc 的时候,pv 仍然存在,处于released 状态,但是它不能被其他pvc 绑定使用,里面的数 据还是存在的,当我们下次再使用的时候,数据还是存在的,这个是默认的回收策略
delete 删除pvc 时即会从Kubernetes 中移除PV,也会从
相关的外部设施中删除存储资产
9.4.3.1 创建pod,使用pvc作为持久化存储卷
9.4.3.1.1 创建nfs共享目录
9.4.3.1.2 如何编写pv的资源清单文件
9.4.3.1.3 创建pv
参考:https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/#reclaiming
STATUS是Available,表示pv是可用的。
9.4.3.1.4 创建pvc 和符合条件的pv绑定
9.4.3.1.5 创建pod,挂载pvc
9.4.3 k8s存储:storagecalss
上面介绍的PV 和PVC 模式都是需要先创建好PV,然后定义好PVC 和pv 进行一对一的Bond,但是如 果PVC 请求成千上万,那么就需要创建成千上万的PV,对于运维人员来说维护成本很高,Kubernetes 提 供一种自动创建PV 的机制,叫StorageClass,它的作用就是创建PV 的模板。k8s 集群管理员通过创建 storageclass 可以动态生成一个存储卷pv 供k8s pvc 使用。
每个StorageClass 都包含字段provisioner,parameters 和reclaimPolicy。
具体来说,StorageClass 会定义以下两部分:
PV的属性,比如存储的大小,类型等;
创建这种PV需要使用到的存储插件,比如Ceph ,NFS等
有了这两部分信息,Kubernetes 就能够根据用户提交的PVC,找到对应的StorageClass,然后 Kubernetes 就会调用 StorageClass 声明的存储插件,创建出需要的PV。 每个StorageClass 都包含字段provisioner,parameters 和reclaimPolicy。 具体来说,StorageClass 会定义以下两部分:
PV 的属性 ,比如存储的大小、类型等;
创建这种PV 需要使用到的存储插件,比如Ceph、NFS 等
有了这两部分信息,Kubernetes 就能够根据用户提交的PVC,找到对应的StorageClass,然后 Kubernetes 就会调用 StorageClass 声明的存储插件,创建出需要的PV。
provisioner:供应商,storageclass 需要有一个供应者,用来确定我们使用什么样的存储来创建 pv,常见的provisioner 如下
(https://kubernetes.io/zh/docs/concepts/storage/storage-classes/):

provisioner 既可以由内部供应商提供,也可以由外部供应商提供,如果是外部供应商可以参考 https://github.com/kubernetes-incubator/external-storage/下提供的方法创建。
https://github.com/kubernetes-sigs/sig-storage-lib-external-provisioner
以NFS 为例,要想使用NFS,我们需要一个nfs-client 的自动装载程序,称之为provisioner,这 个程序会使用我们已经配置好的NFS 服务器自动创建持久卷,也就是自动帮我们创建PV。
reclaimPolicy:回收策略 allowVolumeExpansion:允许卷扩展,PersistentVolume 可以配置成可扩展。将此功能设置为true 时,允许用户通过编辑相应的 PVC 对象来调整卷大小。当基础存储类的allowVolumeExpansion 字段设 置为 true 时,以下类型的卷支持卷扩展。

注意:此功能仅用于扩容卷,不能用于缩小卷。
9.4.3.1 安装 nfs provisioner,用于配合存储类动态生成pv
9.4.3.1.1 创建运行 nfs-provisioner需要的sa账号
9.4.3.1.2 对sa授权
9.4.3.1.3 安装nfs-provisioner程序
查看是否运行正常
9.4.3.2 创建storageclass,动态供给pv
9.4.3.3 创建pvc,通过storageclass动态生成pv
步骤总结:
供应商: 创建一个nfs provisioner
创建storageclass,storageclass指定刚才创建的供应商
创建pvc,这个pvc指定storageclass