持久化存储
关于k8s中的存储字段信息介绍可以通过该命令进行查看:kubectl explain pods.spec.volumes 如下图(只截图了部分内容)
在k8s中使用存储卷通常需要经历如下两个步骤:
1、创建pod时定义volume,并指定这个volume关联到哪个存储上
2、在容器中使用volumemounts挂载对应需要被关联的存储
一、存储类型 emptyDir
该字段属于是存储方案中的临时目录,常用于测试时使用,存放的数据可有可无,pod删除后该存放的数据也会一起删除,生产中不建议使用该字段进行存储数据。
定义的存储卷会在创建pod时在pod所在的节点上创建一个临时目录,它的数据与容器内指定挂载存储的路径中的数据是同步的。
缺点:数据会随着pod删除一起消失,无法有效保存
1.1 创建pod
1.2 查看node节点存储挂载路径
通过创建pod的yaml文件查找pod所在节点生成的临时目录路径
1.3 验证数据同步
在pod所在node节点上的临时目录中创建/删除数据验证容器内的数据是否同步
二、存储类型 hostPath
该字段类型是指pod挂载宿主机的目录或文件,当pod调度到节点1上时,指定该节点上的一个目录或文件给这个pod使用,与emptyDir不同的是,pod删除后节点1上挂载的存储卷不会被删除依然存在。
如果再次创建一个pod时还想使用节点1上的这个存储卷,那么就需要将pod调度到这个存储卷所在的节点1上,即使调度到k8s集群内的其它节点上且其他节点上也有相同路径,但是数据也不会同步,只有将pod调度到相同的节点上才可以。
缺点:单节点,想要数据一直与某pod同步,就需要pod更新或创建时必须要在volumes所在的node节点上。
总而言之,如果删除pod之后,再次创建pod想要数据不丢失,就需要将pod还重建在之前所删除时所在的节点上。
hostPath 字段下的type类型具有如下类型 (默认为空)
官方文档地址: https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/
取值 | 行为 |
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。 | |
DirectoryOrCreate | 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。 |
Directory | 在给定路径上必须存在的目录。 |
FileOrCreate | 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。 |
File | 在给定路径上必须存在的文件。 |
Socket | 在给定路径上必须存在的 UNIX 套接字。 |
CharDevice | 在给定路径上必须存在的字符设备。 |
BlockDevice | 在给定路径上必须存在的块设备。 |
2.1 创建pod
需求,pod中创建两个容器,使它们的存储数据同步
将pod所在节点宿主机的/test001 目录做成存储卷,将/test001挂载到pod中第一个容器的/nginx-test路径下和第二个容器的/httpd-test路径下,并使它们之间的数据同步。
2.2 验证同步数据
创建删除数据验证pod所在宿主机及pod中容器内的数据是否同步
2.3 测试删除/创建pod数据是否保留
测试删除pod之后创建pod在另一个节点,及恢复pod到原来的节点,测试数据同步状态。
三、存储类型 NFS
使用nfs类型的方式进行存储数据,可以避开hostPath方式不能随机在node节点上创建pod的缺点,
但是nfs的缺点是,如果做nfs共享存储的节点挂掉,那么数据一样也会丢失。
需要在k8s集群中的控制节点和工作节点都安装nfs-utils
3.1 安装配置 nfs
3.2 创建pod
使用deployment控制器来创建pod
3.3 验证数据同步
在配置了nfs共享的控制节点中创建\删除来验证nginx容器内的挂载路径是否达到数据同步
3.4 删除pod创建新pod测试数据同步
由于是使用的deployment控制器来管理的pod,删除一个会自动创建一个新的pod出来,测试删除一个pod,重新创建pod之后,验证数据是否同步。
四、存储类型 PVC/storageclass
PVC简介:
PersistentVolume(PV)
它是k8s集群中的一块存储,由管理员配置的或者使用存储类动态配置。
它是集群中的资源,就像pod是k8s集群资源一样。
PV是容量插件,如Volumes,其生命周期独立于使用PV的任何单个pod,也就是说想要在k8s集群中使用PV的话,就需要宿主机的存储目录,或者是nfs共享的目录。
PersistentVolumeClaim(PVC)
它是一个持久化存储卷,创建pod的时候可以将pvc做成存储卷,pvc使用的是pv的资源,
使用pvc时需要有一个符合条件的pv来让pvc申请使用,这样pvc才能做成卷挂到pod中给容器使用,就像创建pod时需要找node节点去调度一样。
PVC和PV的工作原理
PV是集群中的资源。 PVC是对这些资源的请求。
PV和PVC之间的相互作用遵循以下生命周期:
1、pv的供应方式:
可以通过两种方式配置PV:静态或动态。
静态:需要手动创建很多pv,它们包含可供群集用户使用的实际存储的详细信息。它们存在于Kubernetes API中,在创建pvc的时候才能找到事先创建好的pv来使用。
动态:不用事先创建pv,在创建pvc的时候指定一个存储类,需要多大的pv就申请多大的,存储类会自动划分出来以供pvc使用。
2、绑定:
pvc使用pv的时候,pvc必须要找到符合条件的pv才可使用,否则会显示保持未绑定状态。
3、使用方式:
a. 需要有一个存储服务器,把它划分多个存储空间并做成pv
b. 在创建pod定义使用存储卷的时候,可以先创建pvc,让pvc与事先准备好的pv做一个绑定,然后在定义pod的时候把pvc做成卷挂到pod容器里就可以了。
c. pvc与pv关系一一对应,如果创建的pv被其中一个pvc绑定使用了,那么其他的pvc就不能再使用这个pv
d. 如果创建pvc的绑定pv的时候没有任何一个pv满足条件,那么这个pvc就会处于Pending状态。
4、回收策略:
创建pod时使用pvc,pvc与pv进行绑定,删除pod时,绑定的pvc与pv就会解除,
解除之后的pv有常用的两种处理方式:
a. Retain //保留:(默认配置)当解除pvc的时候,pv依然存在,处于released状态,但是它不能被其他pvc绑定使用,里面数据依然存在。
b. Delete //删除:解除删除pvc的时候,pv也会一并被删除,数据也会消失。
pv和pvc字段信息可通过如下命令进行查看:
kubectl explain pv
kubectl explain pvc
4.1静态创建pv
静态创建pv需要手动的指定创建pv,然后在创建pvc时进行绑定,下面演示步骤及效果。
4.1.1创建pv
使用nfs共享目录做存储pv(上方标题三已配置nfs,在增加些路径即可)
(可以先删除上方NFS测试时配置的pod及nfs文件路径)
4.1.2 创建pvc
pv创建好之后,创建pvc进行与pv的绑定
4.1.3 创建pod
pvc创建并绑定好创建的pv之后,创建pod将pvc挂载到pod中
4.1.4 验证pvc数据同步
如上方创建pv -->创建pvc绑定pv --> 创建pod挂载pvc得知,pod中指定的挂载路径是/usr/share/nginx/html,共享的是做了nfs共享的控制节点下的/nfs/volumes001/pv01 (其他的pv0210还未挂载,0310还未创建pvc并绑定),如下在nfs主机上的pv01路径下测试创建/删除数据是否会与容器内同步。
4.1.5 测试pvc是否支持新创建pod使用
再次创建一个pod仍然挂载mypvc01,测试是否可以使用并数据同步
4.1.6 pv、pvc的删除回收
如果想要删除pv 或者 pvc,需要先删除pod,否则由于pod在使用pvc和pv,pv和pvc将无法删除。
4.1.6.1 pv、pvc删除重建步骤
4.1.6.2 pv、pvc的回收
(下面只是测试回收策略是否生效,其实在当前k8s集群的版本中(1.26)不管有没有设置回收策略,在删除pod、pvc及pv之后宿主机上共享的数据都不会被删除,感兴趣的可以看下或者自己测试下。)
创建pv时如果不定义回收策略,默认的策略是Retain(保留),下面测试回收策略delete
回收策略字段定义:persistentVolumeReclaimPolicy
kubectl explain pv.spec.persistentVolumeReclaimPolicy 可通过该命令查看字段详细介绍
ps:为保持测试方便,可将创建的pod及pvc、pv全部删除
4.2 动态创建pv
存储类(storageclass),使用类型可以动态的自动创建pv,k8s管理员通过创建storageclass可以动态生成一个存储卷pv供pvc使用。
kubectl explain storageclass 使用该命令可以查看该字段信息。
其中比较重要的字段解释如下
provisioner
可理解为提供商,使用storageclass时需要有一个供应者用来动态的生成符合条件的pv,然后由该字段指定供应者来创建pv
reclaimPolicy
定义回收策略,默认的是delete
4.2.1 创建nfs 提供商
以nfs共享存储为例进行创建,将nfs作为提供商,从nfs共享目录中划分存储。
nfs属于是k8s外部供应商,要想使用nfs需要安装一个自动装载程序--nfs-client,称之为provisioner,这个程序会使用已经配置好的nfs服务在配置nfs共享目录的服务器上自动创建持久卷,也就是自动创建pv。
创建nfs提供商需要使用到这个镜像,可在docker上拉取下载
4.2.2 创建运行nfs-provisioner需要的sa账号
因为nfs 提供商是以pod中的容器形式在k8s中运行的,所以需要创建一个sa账号并赋权,让他能有权限操作k8s并与k8s api通信
才能从k8s中创建存储出来。
sa的全称是serviceaccount。
serviceaccount是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。
指定了serviceaccount之后,我们把pod创建出来了,我们在使用这个pod时,这个pod就有了我们指定的账户的权限了。
4.2.3 创建nfs提供商
创建nfs提供商之前,先找一个集群内的机器做服务端,我这里仍然使用控制节点,配置方法如上方3.1标题中的步骤一致
4.2.4 创建存储类 pvc
创建pvc之前,需要先创建一个存储类(storageclass ),通过它动态生成pv
4.2.5 创建存储类(torageclass)
创建storageclass,动态供给pv,(可以理解为创建了动态的pv)
4.2.6 创建pvc
创建pvc 与 存储类绑定
4.2.7 创建pod
创建一个pod,挂载上面创建好的pvc,{也就是存储类(storageclass),动态生成的pvc(test-pvc)}
4.2.8 测试共享
测试绑定的pvc是否生效
经上方步骤:
创建的pod 中nginx容器的/usr/share/nginx/html 绑定了test-pvc
test-pvc绑定了存储类(storageclass),
存储类指定了宿主机上的/nfs/test001/并在其下自动生成了一个目录,而这个目录就是pv
而这个/nfs/test001/下生成的随机目录(pv)就是与nginx容器中绑定的路径做了共享存储。