浅谈Kubernetes的持久化存储方案

Posted 琦彦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈Kubernetes的持久化存储方案相关的知识,希望对你有一定的参考价值。

浅谈Kubernetes的持久化存储方案

一、存储的一些基本概念

在谈到K8s的存储之前,我们首先介绍一下存储的一些基本分类概念。

存储分类

存储介质角度

从存储介质角度,可分为两大类:

  • 机械硬盘:泛指采用磁头寻址的磁盘设备,包括SATA硬盘和SAS硬盘。由于采用磁头寻址,机械硬盘性能一般。
  • 固态硬盘:是指采用Flash/DRAM芯片+控制器组成的设备,根据协议的不同,又分为SATA SSD,SAS SSD,PCIe SSD和NVMe SSD等,性能较机械硬盘大幅提升。

产品定义角度

从产品定义角度,可分为四大类:

  • DAS(Direct-attached Storage):就是本地盘,直接插到服务器上。
  • NAS(Network Attached Storage):是指提供NFS协议的NAS设备,通常采用磁盘阵列+协议网关的方式。
  • SAN(Storage Area Network):跟NAS类似,提供SCSI/iSCSI协议,后端是磁盘阵列。
  • SDS(Software Defined Storage):是一种泛指,包括分布式NAS,ServerSAN等。

物理存储形态角度

从物理存储形态角度,可分为两大类:

  • 集中式存储(传统存储):以磁盘阵列为主,一向以可靠性高、稳定性好、功能丰富而著称,但与此同时,传统存储也暴露出横向扩展性差、价格昂贵、数据连通困难等不足,容易形成数据孤岛,导致数据中心管理和维护成本居高不下。
  • 分布式存储:以软件定义存储为主,将数据分散存储在网络上的多台独立设备上,一般采用标准x86服务器,并在其上运行相关存储软件,系统对外作为一个整体提供存储服务。分布式存储不仅提高了存储空间的利用率,还实现了弹性扩展,降低了运营成本,避免了资源浪费,更适合大数据时代场景。

应用场景角度

从应用场景角度,存储可分为块存储,文件存储,和对象存储三大类。

块存储

典型代表就是DAS和SAN存储

块存储主要是将裸磁盘空间整个映射给主机使用的

比如磁盘阵列里面有5块硬盘,然后可以通过划逻辑盘、做Raid、或者LVM等方式逻辑划分出N个逻辑的硬盘,就比如说划了3个逻辑硬盘。接着块存储会采用映射的方式将这几个逻辑盘映射给主机,主机上面的操作系统会识别到有3块硬盘,但是操作系统是无法区分到底是物理盘还是逻辑盘,它一概就认为只是3块裸的物理硬盘而已,跟直接拿3块物理硬盘挂载到操作系统没区别,至少操作系统感知上没有区别的。在此方式下,操作系统还需要对挂载的裸硬盘进行分区、格式化后,才能使用,与平常主机内置的硬盘无差异。

优点

1)这种方式的好处当然是因为通过了Raid与LVM等手段,对数据提供了保护;

2)可以将多块廉价的硬盘组合起来,称为一个大容量的逻辑盘对外提供服务,提高了容量;

3)写入数据时,由于是多块磁盘组合出来的逻辑盘,所以几块硬盘可以并行写入的,提升了读写效率;

4)很多时候块存储采用SAN架构组网,传输速度以及封装协议的原因,使得传输速度和读写效率得到提升。

缺点

1)采用SAN架构组网时,需要额外为主机购买光纤通道卡,还要购买光纤交换机,造价成本高;

2)主机之间数据无法共享,在服务器不做集群的情况下,块存储裸盘映射给主机,在格式化使用后,对于主机来说相当于本地盘,那么主机A的本地盘根本不能给主机B去使用,无法共享数据;

3)**不利于不同操作系统主机间的数据共享:**因为操作系统使用不同的文件系统,格式化后,不同的文件系统间的数据是共享不了的。例如一台win7,文件系统是FAT32/NTFS,而linux是EXT4,EXT4是无法识别NTFS的文件系统的;

4)可扩展性较差,已不能满足成千上万个CPU规模的系统。

文件存储

典型代表就是NAS存储(这块主要针对传统集中式存储)

**为了克服文件无法共享的问题,所以有了文件存储。**文件存储也有软硬一体化的设备,但是其实一台普通的PC机,只要装上合适的操作系统和软件,就可以架设NFS服务了,架上该类服务之后的服务器,就是文件存储的一种了。

主机A可以直接对文件存储进行文件的上传和下载,与块存储不同,主机A是不需要再对文件存储进行格式化的,因为文件管理功能已经由文件存储自己搞定了。

优点

1)造价低:随便一台机器就可以,另外普通的以太网就可以,根本不需要专用的SAN网络,所以造价低;

2)方便文件共享。

缺点

1)**NFS协议开销高、带宽低、延迟大。**尤其是传统NAS架构来说,一套存储设备如果要为几百甚至上千个应用提供服务,网络带宽会成为明显的瓶颈;而如果文件数量足够大的话,单台存储设备的处理能力也会成为很大的问题。

对象存储

典型设备就是内置大容量硬盘的分布式服务器

对象存储最大的特点就是扁平化的存储方式,不受复杂目录系统对性能的影响。

首先,一个文件包含了属性(即元数据,metadata,例如该文件的大小、修改时间、存储路径等)以及内容(数据),然后对象存储将元数据独立出来了,控制节点叫元数据服务器(Metadata Server , MDS),主要负责存储对象的属性,而其他负责存储数据的分布式服务器叫做OSD(Object-based Storage Device),主要负责存储对象的数据。当用户访问对象,会先访问MDS,MDS只负责反馈对象在哪个OSD,假设反馈对象A存储在B、C、D三台OSD,那么用户就会再次直接访问3台OSD服务器去读取数据。由于是3台OSD同时对外传输数据,所以传输速度就加快了,OSD服务器数量越多,这种读写速度的提升就越大。

优点:

1)高度的灵活性,支持横向在线扩展;

2)高可靠性;

3)对于海量非结构化数据有着不可比拟性能优势。

缺点:

1)最终一致性:由于不同节点的位置不同,数据同步时可能会有一定时间的延迟或者错误。


几种不同类型的存储介绍完了,现在可以把他们串起来烤了。

先扔一张图,来说明各个不同类型存储比较适用的区域:

再扔一张图:

我们从底层往上看,最底层就是硬盘,多个硬盘可以做成RAID组,无论是单个硬盘还是RAID组,都可以做成PV,多个PV物理卷捏在一起构成VG卷组,这就做成一块大蛋糕了。

接下来,可以从蛋糕上切下很多块LV逻辑卷,这就到了存储用户最熟悉的卷这层。

到这一层为止,数据一直都是以Block块的形式存在的,这时候提供出来的服务就是块存储服务。你可以通过FC协议或者iSCSI协议对卷访问,映射到主机端本地,成为一个裸设备。在主机端可以直接在上面安装数据库,也可以格式化成文件系统后交给应用程序使用,这时候就是一个标准的SAN存储设备的访问模式,网络间传送的是块。

如果不急着访问,也可以在本地做文件系统,之后以NFS/CIFS协议挂载,映射到本地目录,直接以文件形式访问,这就成了NAS访问的模式,在网络间传送的是文件。

如果不走NAS,在本地文件系统上面部署OSD服务端,把整个设备做成一个OSD,这样的节点多来几个,再加上必要的MDS节点,互联网另一端的应用程序再通过HTTP协议直接进行访问,这就变成了对象存储的访问模式。当然对象存储通常不需要专业的存储设备,前面那些LV/VG/PV层也可以统统不要,直接在硬盘上做本地文件系统,之后再做成OSD,这种才是对象存储的标准模式,对象存储的硬件设备通常就用大盘位的服务器。

二、Kubernetes的存储系统介绍

Kubernetes中存储的应用场景

在Kubernetes中部署和运行的服务大致分为:

无状态服务

Kubernetes使用ReplicaSet来保证一个服务的实例数量,如果说某个Pod实例由于某种原因挂掉或崩溃,ReplicaSet会立刻用这个Pod的模版新启一个Pod来替代它。由于是无状态的服务,新Pod与旧Pod一模一样。此外Kubernetes通过Service(一个Service后面可以挂多个Pod)对外提供一个稳定的访问接口,实现服务的高可用。

普通有状态服务

和无状态服务相比,它多了状态保存的需求。Kubernetes提供了以Volume和Persistent Volume为基础的存储系统,可以实现服务的状态保存。

有状态集群服务

和普通有状态服务相比,它多了集群管理的需求。要运行有状态集群服务要解决的问题有两个,一个是状态保存,另一个是集群管理。

分析以上的服务类型,Kubernetes中对于存储的使用主要集中在以下几个方面:

  1. 服务的基本配置文件读取、密码密钥管理等;

  2. 服务的存储状态、数据存取等;

  3. 不同服务或应用程序间共享数据。

Kubernetes中几种常见的存储系统

目前Kubernetes所支持的Volume Plugins如下表所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zMpdpyVX-1650962387032)(https://cdn.jsdelivr.net/gh/Fly0905/note-picture@main/img/202204261631863.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GgWRUOxw-1650962387032)(https://cdn.jsdelivr.net/gh/Fly0905/note-picture@main/img/202204251435555.jpeg)]

Kubernetes已经提供非常丰富的Volume和Persistent Volume插件,我们可以根据自己业务的需要,使用这些插件给容器提供存储服务。

容器存储接口(Container Storage Interface,CSI )是一项跨行业标准倡议,旨在降低云原生存储开发工作的门槛,从而进一步确保兼容性水平。Kubernetes v1.9已经引入了 CSI 的一套alpha实现版本,将新分卷插件的安装流程简化至与安装pod相当,并允许第三方存储供应商在无需接触核心Kubernetes代码库的前提下开发自己的解决方案。

Kubernetes存储的设计与基本架构

Kubernete存储在设计的时候遵循着Kubernetes的一贯哲学,即声明式(Declarative)架构。同时为了尽可能多地兼容各种存储平台,Kubernetes以in-tree plugin的形式来对接不同的存储系统,满足用户可以根据自己业务的需要使用这些插件给容器提供存储服务。同时兼容用户使用CSI定制化插件。

Kubernetes中mount 一个PV的基本过程包括:

1)用户通过API创建一个包含PVC的Pod;

2)Scheduler把这个Pod分配到某个节点,比如Node1;

3)Node1上的Kubelet开始等待Volume Manager准备device;

4)PV controller调用相应Volume Plugin(in-tree或者out-of-tree),创建PV,并在系统中与对应的PVC绑定;

5)Attach/Detach controller或者Volume Manager通过Volume Plugin实现device挂载(Attach);

6)Volume Manager等待device挂载完成后,将卷挂载到节点指定目录(mount),比如/var/lib/kubelet/pods/xxxxxxxxxxx/volumes/aws-ebs/vol-xxxxxxxxxxxxxxxxx;

7)Node1上的Kubelet此时被告知volume已经准备好后,开始启动Pod,通过volume mapping将PV已经挂载到相应的容器中去。

Persistent Volume与Persistent Volume Claim

一个运行中的容器,缺省情况下,对文件系统的写入,都是发生在其分层文件系统的可写层的(Copy-on-Write)。当迁移的应用程序从开发到生产环境时候,开发人员面临着巨大的挑战。当容器挂掉、崩溃或运行结束时,任何与之相关的数据都会丢失。为了解决这个问题引发的数据丢失,我们需要将数据存储持久化,也可以称为Persistent Volume。

Kubernetes使用两种资源管理存储:

PersistentVolume(简称PV):由管理员添加的的一个存储的描述,是一个全局资源,包含存储的类型,存储的大小和访问模式等。它的生命周期独立于Pod,例如当使用它的Pod销毁时对PV没有影响。

PersistentVolumeClaim(简称PVC):是Namespace里的资源,描述对PV的一个请求。请求信息包含存储大小,访问模式等。

Kubernetes中的Volume则是基于Docker进行扩展,使用Docker Volume挂载宿主机上的文件目录到容器中。

了解了PV和PVC概念,那么Kubernetes中Pod是通过何种方式来访问存储资源的呢?一般来说有如下三种:

直接访问

该种方式移植性较差,可扩展能力差,把Volume的基本信息完全暴露给用户,有严重的安全隐患,同时需要协调不同users对Volume的访问。

静态provision

通过静态配置,管理员提供了他们认为Pod在发出实际请求之前可能需要的PV,并且这些PV通过显式PVC手动绑定到特定的Pod。这违背了Kubernetes的思想:CPU和内存不是预先分配的,而是绑定到Pod或容器中,它们是动态授予的。

放两张图,看哪张更容易理解吧。

动态provision

动态配置是通过StorageClass完成的。集群管理员不需要预先手动创建PV,而是创建多个存储配置文件,就像模板一样。当开发人员创建PVC时,根据请求的要求,其中一个模板在请求时创建,并附加到Pod。

StorageClass将说明Volume将由哪种Volume Plugin创建、创建时参数以及从其他功能性/非功能性角度描述的后台volume的各种参数。

而PV和PVC的生命周期分为5个阶段:

1) Provisioning,即PV的创建,可以直接创建PV(静态方式),也可以使用StorageClass动态创建

2) Binding,将PV分配给PVC

3) Using,Pod通过PVC使用该Volume

4) Releasing,Pod释放Volume并删除PVC

5) Reclaiming,回收PV,可以保留PV以便下次使用,也可以直接从云存储中删除

根据这5个阶段,Volume的状态有以下4种:

1) Available:可用

2) Bound:已经分配给PVC

3) Released:PVC解绑但还未执行回收策略

4) Failed:发生错误

访问模式(Access Modes)

不同存储后端支持的访问模式不同,同一种存储后端的不同PV也可以各自设置访问模式。如NFS支持多客端read/write,但其某一个具体PV的访问模式可能是read-only。每个PV的访问模式取决于其PV对象中accessModes字段设置。

具体的访问模式有:

ReadWriteOnce – volume可以被单节点以read-write模式挂开。

ReadOnlyMany – volume可以被多节点以read-only模式挂载。

ReadWriteMany – volume可以被多个节点以read-write模式挂载。

Volume可以同时支持多种访问模式,但是在具体挂载时只能使用一种,这一点需要在pod中定义PVC类型的volume时说明。命令行支持缩写:

RWO - ReadWriteOnce

ROX - ReadOnlyMany

RWX - ReadWriteMany

不同存储后端对访问模式的支持:

Volume PluginRWOROXRWX
AWSElasticBlockStore--
AzureFile
AzureDisk--
CephFS
Cinder--
FC-
FlexVolume-
Flocker--
GCEPersistentDisk-
Glusterfs
HostPath--
iSCSI-
Quobyte
NFS
RBD-
VsphereVolume-(works when pods are collocated)
PortworxVolume-
ScaleIO-
StorageOS--

从这张表我们可以看到,像Cinder、FC、iSCSI、RBD(CephRBD)等,都最多只能支持到RWO、ROX,而他们都是块存储;

又比如像CephFS、Glusterfs、NFS等,都能够同时支持三种模式,而他们都是文件存储。

细心的同学可能发现,为啥这里面没有对象存储什么事儿?因为对象存储不需要PV/PVC来做资源抽象,应用可以直接访问和使用。

三、开源分布式存储系统对比

我们上文已经讲到,目前Kubernetes已经提供非常丰富的Volume和PV插件,几乎涵盖了所有热门的分布式存储系统:

如Ceph, GlusterFS, Sheepdog, Lustre, Swift,Cinder, TFS, HDFS, MooseFS, FastDFS, MogileFS等等。有兴趣了解全部类型,可以参阅https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes。

这里仅对几个开源分布式存储系统先做个简单对比:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e2U0XDjG-1650962387042)(https://cdn.jsdelivr.net/gh/Fly0905/note-picture@main/img/202204251435455.jpeg)]

Ceph

Ceph是一个可以按对象/块/文件方式存储的开源分布式文件系统,其设计之初,就将单点故障作为首先要解决的问题,因此该系统具备高可用性、高性能及可扩展等特点。

用一张图来说明。底层是RADOS,这是个标准的对象存储。以RADOS为基础,Ceph 能够提供文件,块和对象三种存储服务。其中通过RBD提供出来的块存储是比较有价值的地方,毕竟因为市面上开源的分布式块存储少见嘛(以前倒是有个sheepdog,但是现在不当红了)。当然它也通过CephFS模块和相应的私有Client提供了文件服务,这也是很多人认为Ceph是个文件系统的原因。另外它自己原生的对象存储可以通过RadosGW存储网关模块向外提供对象存储服务,并且和对象存储的事实标准Amazon S3以及Swift兼容。所以能看出来这其实是个大一统解决方案,啥都齐全。

现在我们来看数据访问路径,如果看Ceph的文件接口,自底层向上,经过了硬盘(块)->文件->对象->文件的路径;如果看RBD的块存储服务,则经过了硬盘(块)->文件->对象->块,也可能是硬盘(块)->对象->块的路径;再看看对象接口,则是经过了硬盘(块)->文件->对象或者硬盘(块)->对象的路径,感觉各种组合都齐全了。

特性

1)Ceph底层存储是基于RADOS(可靠的、自动的分布式对象存储),它提供了LIBRADOS/RADOSGW/RBD/CEPH FS方式访问底层的存储系统,如上图所示;

2)通过FUSE,Ceph支持类似的POSIX访问方式;Ceph分布式系统中最关键的MDS节点是可以部署多台,无单点故障的问题,且处理性能大大提升;

3)Ceph通过使用CRUSH算法动态完成文件inode number到object number的转换,从而避免再存储文件metadata信息,增强系统的灵活性。

优点

1)支持对象存储(OSD)集群,通过CRUSH算法,完成文件动态定位,处理效率更高;

2)支持通过FUSE方式挂载,降低客户端的开发成本,通用性高;

3)支持分布式的MDS/MON,无单点故障;

4)强大的容错处理和自愈能力;

5)支持在线扩容和冗余备份,增强系统的可靠性。

缺点

1)目前尚未大规模投入商用,尤其是CephRBD和RadosGW,系统稳定性有待考究。

GlusterFS

GlusterFS是Red Hat旗下的一款开源分布式文件系统,它具备高扩展、高可用及高性能等特性,由于其无元数据服务器的设计,使其真正实现了线性的扩展能力,使存储总容量可轻松达到PB级别,支持数千客户端并发访问;对于跨集群,其强大的Geo-Replication可以实现集群间数据镜像,而且是支持链式复制,这非常适用于垮集群的应用场景。

GlusterFS总体架构与组成部分如上图所示,它主要由存储服务器(Brick Server)、客户端以及NFS/Samba存储网关组成。不难发现,GlusterFS架构中没有元数据服务器组件,这是其最大的设计这点,对于提升整个系统的性能、可靠性和稳定性都有着决定性的意义。GlusterFS支持TCP/IP和InfiniBand RDMA高速网络互联,客户端可通过原生Glusterfs协议访问数据,其他没有运行GlusterFS客户端的终端可通过NFS/CIFS标准协议通过存储网关访问数据。

特性

1)目前GlusterFS支持FUSE方式挂载,可以通过标准的NFS/SMB/CIFS协议像访问本体文件一样访问文件系统,同时其也支持HTTP/FTP/GlusterFS访问,同时最新版本支持接入Amazon的AWS系统;

2)GlusterFS系统通过基于SSH的命令行管理界面,可以远程添加、删除存储节点,也可以监控当前存储节点的使用状态;

3)GlusterFS支持集群节点中存储虚拟卷的扩容动态扩容;同时在分布式冗余模式下,具备自愈管理功能,在Geo冗余模式下,文件支持断点续传、异步传输及增量传送等特点。

优点

1)系统支持POSIX(可移植操作系统),支持FUSE挂载通过多种协议访问,通用性比较高;

2)支持在线扩容机制,增强系统的可扩展性;

3)实现了软RAID,增强系统的并发处理能力及数据容错恢复能力;

4)强大的命令行管理,降低学习、部署成本;

5)支持整个集群镜像拷贝,方便根据业务压力,增加集群节点;

6)官方资料文档专业化,该文件系统由Red Hat企业级做维护,版本质量有保障。

缺点

1)通用性越强,其跨越的层次就越多,影响其IO处理效率;

2)频繁读写下,会产生垃圾文件,占用磁盘空间;

3)适合中大型文件,不适合处理海量小文件。

参考文献


1.http://www.gluster.org/

2.http://www.gluster.org/wp-content/uploads/2012/05/Gluster_File_System-3.3.0-Administration_Guide-en-US.pdf

3.http://blog.csdn.net/liuben/article/details/6284551

4.http://ceph.com/

5.https://blog.csdn.net/zzq900503/article/details/80020725

6.https://www.cnblogs.com/tcicy/p/8456170.html

7.http://www.dockone.io/article/3063

8.https://czero000.github.io/2016/04/05/glusterfs-technical-explanation.html

9.http://gluster.readthedocs.org/en/latest/

10.https://mp.weixin.qq.com/s/e6xgQx49rtAg3V0t2tODsg

11.https://mp.weixin.qq.com/s/6yg_bt5mYKWdXS0CidY6Rg

3.http://blog.csdn.net/liuben/article/details/6284551

4.http://ceph.com/

5.https://blog.csdn.net/zzq900503/article/details/80020725

6.https://www.cnblogs.com/tcicy/p/8456170.html

7.http://www.dockone.io/article/3063

8.https://czero000.github.io/2016/04/05/glusterfs-technical-explanation.html

9.http://gluster.readthedocs.org/en/latest/

10.https://mp.weixin.qq.com/s/e6xgQx49rtAg3V0t2tODsg

11.https://mp.weixin.qq.com/s/6yg_bt5mYKWdXS0CidY6Rg

12.https://blog.csdn.net/qq_23348071/article/details/70232735

以上是关于浅谈Kubernetes的持久化存储方案的主要内容,如果未能解决你的问题,请参考以下文章

浅谈Linux磁盘与文件系统管理

[kubernetes] 持久化存储之emptyDir/HostPath/NFS

Rook:Kubernetes上提供Kubernetes云原生本地持久存储

2个Kubernetes使用同一个Ceph存储达到Kubernetes间持久化数据迁移

K8S专栏Kubernetes数据持久化管理

LinuxDay12——磁盘存储和文件系统