当前位置: 首页 > 科技观察

Kubernetes 存储的设计与基本架构

时间:2023-03-20 10:58:04 科技观察

Kubernetes存储架构的设计和基本架构。一、容器平台存储基础知识存储作为容器平台的重要组成部分,保证了容器数据的安全,在整个系统中起着举足轻重的作用,是整个设计的重中之重。容器中数据的存储是临时的。当容器消失时,数据也会消失。后来有持久化存储的研究;在Kubernetes平台上,Pod中有多个容器同时运行,这些容器往往需要共享数据存储,以保证数据安全。Kubernetes抽象出Volume对象来解决存储问题。Docker也有Volume的概念,但只有少量的松散管理。在Docker中,卷是磁盘上或另一个容器内的目录。后来又增加了Volume生命周期的管理和Volume的驱动,虽然功能还是很有限。Kubernetes卷具有明确定义的生命周期——与包装它的Pod相同。因此,卷的寿命比Pod中运行的任何容器都长,并且数据在容器重新启动时得以保留。当然,当一个pod不存在时,volume也将不存在。Kubernetes可以支持多种类型的卷,Pod可以同时使用任意数量的卷。卷的核心是一个目录,其中包含一些数据,Pod中的容器可以访问这些数据。一个特定的卷类型可以决定这个目录是如何形成的,并且可以决定它支持什么媒体,以及目录中存储什么内容。使用卷时,Pod声明需要提供卷类型(.spec.volumes字段)和挂载卷的位置(.spec.containers.volumeMounts字段)。容器中的进程会看到一个由其Docker映像和卷组成的文件系统视图。Docker镜像位于文件系统层次结构的根部,任何卷都安装在镜像内的指定路径。卷不能安装到其他卷或具有到其他卷的硬链接。Pod中的每个容器必须独立指定每个卷的安装位置。容器存储的类型容器架构中使用了三种存储:(1)镜像存储可以利用现有的共享存储,类似于虚拟化环境中虚拟机镜像的分布保护机制。容器镜像的优点是它的存储容量比完整的虚拟机镜像小得多,因为操作系统代码没有被复制。另外,容器镜像的运行在设计之初就固定下来,可以更高效的存储和共享。但正因为如此,容器镜像无法存储动态应用程序的数据。(2)配置数据存储这些配置数据用于管理容器,可以借助现有的存储来实现,主要是配置数据和日志记录等一些管理数据。(3)应用数据存储这些数据是重要的、临时的,也是最难存储的。与虚拟机相比,容器的设计寿命更短。一旦容器被销毁,所有的临时存储空间都会消失。因此,应用程序真正需要保存的数据可以写入到持久化Volume数据卷中。由于基于微服务的容器应用多位分布式系统,容器可以动态启动、停止、扩展或跨多个节点迁移。因此,当容器应用程序有持久化数据时,必须保证数据可以被不同的节点访问。另一方面,容器是面向应用的运行环境,数据通常保存在文件系统中,即以文件的形式存储接口更适合应用访问。持久化存储的数据量需要提前规划,支持容器迁移也需要存储支持。需要根据不同的业务需求提供不同的存储。etcd存储了平台的状态和配置信息,因此对性能、安全、稳定性的要求比较高。存储在平台中的应用场景Kubernetes中存储的使用主要集中在以下几个方面:服务的基础配置文件读取、密码密钥管理等;服务的存储状态、数据存储等;在不同的服务或应用程序之间共享数据;在Kubernetes中部署和运行的服务大致分为:(1)无状态服务Kubernetes使用ReplicateSet来保证一个服务的实例数。如果某个Pod实例由于某种原因挂起或崩溃,ReplicateSet将立即使用此Pod的模板来替换它。因为是无状态服务,所以新Pod和旧Pod完全一样。另外,Kubernetes通过Service提供稳定的访问接口(一个Service可以挂多个Pod),实现服务的高可用。(2)与无状态服务相比,普通有状态服务对状态保存的要求更高。Kubernetes提供了一个基于Volume和PersisettentVolume的存储系统,可以保存服务状态。(3)与普通的有状态服务相比,有状态集群服务对集群管理的要求更高。运行有状态的集群服务需要解决两个问题,一个是状态保存,另一个是集群管理。Kubernetes为此开发了StatefulSet,方便在Kubernetes上部署和管理有状态的集群服务。容器云存储设计的重要性数据是企业的重要资产。如何用好数据才能实现企业的繁荣,如何保存好数据是保证企业繁荣的坚强后盾。因此,在平台建设前的规划阶段,必须做好充分的技术准备和项目调研,将数据的重要性提升到重要的高度,引起重视。数据是企业的重要资产。只有保证数据不丢失、数据完整、数据一致,才能更好地开展业务。容器和虚拟机或者物理机的技术实现是不一样的。容器专注于无状态应用程序。为了支持有状态的应用程序,必须根据业务需求提前考虑和规划数据存储。容器云是一个基础平台,涉及到平台组件、镜像、应用、中间件等诸多方面,每个方面都可能有不同的存储需求。要想获得理想的性能和效果,需要综合考虑方方面面,而存储等作为基础设施资源更是必不可少。容器用于承载应用程序。各个应用层级的数据都有潜在的价值。捕获、处理、存储和分析这些数据是获得价值的步骤。因此,应用数据的持久化是容器云平台支撑业务应用的重要基础能力之一。只有打好基础,才能服务好应用。2.Kubernetes中几种常见的存储系统从Kubernetes官方提供的资料来看,Kubernetes支持的VolumePlugins如下表:Kubernetes提供了非常丰富的Volume和PersistentVolume插件,可以根据特性使用自己的事。这些插件为容器提供存储服务。各Plugin的使用及注意事项请参考:https://kuberne-tes.io/zh/docs/concepts/storage/容器存储接口(ContainerStorageInterface,CSI)是一个跨行业的标准倡议,旨在降低云原生存储开发的门槛,进一步保证兼容性。Kubernetes中的CSI将新卷插件的安装过程简化到与安装Pod相同的水平,并允许第三方存储提供商在不触及Kubernetes核心代码库的情况下开发自己的解决方案。3.持久化存储设计如前所述,数据是业务发展和进一步价值获取的源泉,是核心资产。重要数据必须根据法规/业务要求持久存储和备份。容器持久化存储一般可以通过两种形式实现:一是本地磁盘形式,优点是简单易用,缺点是难以迁移、共享和扩展;二是以共享存储集群的形式,具有数据共享的优势,可以提供多种存储接口,并且可以弹性伸缩。缺点是架构略显复杂。针对不同的场景,持久化存储需要有不同的选择策略:4Kubernetes存储设计和基本架构4.1PersistentVolume和PersistentVolumeClaim概念介绍一个运行的容器,默认写入文件系统,都发生在其可写层分层文件系统(写时复制)。在将应用程序从开发迁移到生产时,开发人员面临着巨大的挑战。当容器死亡、崩溃或终止时,与其关联的所有数据都会丢失。为了解决这个问题造成的数据丢失,我们需要将数据存储持久化,也可以称为PersistentVolume。Kubernetes使用两种资源来管理存储:PersistentVolume(简称PV):管理员添加的存储描述,是一种全局资源,包括存储的类型、存储的大小和访问方式。它的生命周期是独立于Pod的,比如当前使用它的Pod销毁时,对PV没有影响。PersistentVolumeClaim(简称PVC):是Namespace中的资源,描述了对PV的请求。请求信息包括存储大小、访问方式等。Kubernetes中的Volume是基于Docker扩展的,DockerVolume用于将宿主机上的文件目录挂载到容器中。一般来说,Kubernetes中的Pod通过以下三种方式访问??存储:(1)直接访问,可移植性和扩展性差,将Volume的基本信息完全暴露给用户,存在严重的安全隐患。同时需要协调不同用户对Volume的访问。(2)静态提供(3)动态提供显然,动态提供比静态提供更灵活,而且这种方式也解耦了Kubernetes系统的计算层和存储层,更重要的是它为存储提供者提供了可插拔的开发模式,存储提供商只需要根据该模型开发相应的volume插件即可为Kubernetes提供存储服务。实现方式分为三种:In-treeVolumePluginOut-of-treeProvisionerOut-of-treeCSIDriver首先,在Kubernetes内部代码中实现了一些存储插件,以支持一些主流的网络存储。其次,如果官方插件无法满足需求,存储提供商可以根据需要定制或优化存储插件,并将其集成到Kubernetes系统中。第三种是容器存储接口CSI,是Kubernetes对外开放的存储接口。实现这个接口后,就可以集成到Kubernetes系统中了。社区此前已经宣布不再继续intree/outoftree开发,将现有功能全部迁移至CSI。因此,第三种CSI方案更推荐存储提供商和用户使用。一般来说,PV和PVC的生命周期分为五个阶段:(1)Provisioning,即PV的创建,可以直接创建(静态),也可以使用StorageClass动态创建;(2)Binding,将PV赋值给PVC;(3)Using,Pod通过PVC使用Volume;(4)Releasing,Pod释放Volume,删除PVC;(5)Reclaiming,回收PV,可以保留PV以备下次使用,也可以直接从storage中删除。根据这5个阶段,Volume的状态有以下4种:Available:AvailableBound:已经分配给PVCRelease:PVC未绑定但还没有执行恢复策略Failed:发生错误4.2Kubernetes基本存储架构Kubernetes存储被设计为遵循声明式架构。同时,为了尽可能兼容各种存储平台,Kubernetes使用in-treeplugins连接不同的存储系统,用户可以根据自己的业务需求使用这些plugins为容器提供存储服务.同时兼容用户使用FlexVolume和CSI自定义插件。与DockerVolume相比,支持的存储功能更加丰富多样。Kubernetes挂载一个PV的基本过程包括:(1)用户通过API创建一个包含PVC的Pod;(2)Scheduler将Pod分配给一个节点Node;(3)节点Node上的Kublet开始等待VolumeManager准备好Device;(4)PVcontroller调用对应的VolumePlugin(in-treeorout-of-tree),创建PV,并与系统中对应的PVC进行绑定;(5)通过VolumePlugin实现设备挂载(Attach),Attach/Detachcontroller或VolumeManager;(6)VolumeManager等待Device挂载,然后将volume挂载到节点的指定目录;(7)Node节点上的Kublet收到Volume准备好的通知,启动Pod,通过Volume映射将PV挂载到对应的容器中。Kubernetes存储架构设计图