【文章主体共计5436字,阅读约需15分钟,其中涉及实际部署操作,建议先收藏再看。】
概述Kubernetes(下称k8s)作为目前行业内使用最广泛的容器编排工具,已经深入到各个技术领域,正在彻底改变应用程序的开发和部署方式;但从另一个方面讲,k8s的架构是不断变化的。容器的创建和销毁,从本质上讲,它们的生命周期是短暂的。因而,K8s的发展历程势必无法绕开持久化的问题,本文就将从这一点出发,为大家讲解k8s在持久化存储方面所提供的解决方案,帮助大家更好的理解k8s的整体技术生态。
本文的章节内容分配如下:
概述
K8s有哪些持久化方案
Docker存储
K8s原生存储
开源存储项目CephRook
总结
K8s有哪些持久化方案外部存储方案:
先抛一张CNCF(云原生计算基金会)公布的云原生存储解决方案一览图,这里只截取了存储的部分。
图中列举的存储方案,目前都可以集成到Kubernetes平台,
Docker存储卷
当使用Docker作为K8s的容器方案时,Docker自身所支持的存储卷也就成为了可选方案之一。Docker存储卷是容器服务在单节点的存储组织形式,作为解决数据存储、容器运行时的技术方案;
K8s存储卷
下面,我们就对这几种存储方案一一进行解释。
Docker存储容器的读写层
为了提高节点存储的使用效率,容器不光在不同运行的容器之间共享镜像资源,而且还实现了在不同镜像之间共享数据。共享镜像数据的实现原理:镜像是分层组合而成的,即一个完整的镜像会包含多个数据层,每层数据相互叠加、覆盖组成了最终的完整镜像。
为了实现多个容器间共享镜像数据,容器镜像每一层都是只读的。而容器使用镜像时,在多个镜像分层的最上面还添加了一个读写层。每一个容器在运行时,都会基于当前镜像在其最上层挂载一个读写层,用户针对容器的所有操作都在读写层中完成。一旦容器销毁,这个读写层也随之销毁。
容器的数据卷
容器中的应用读写数据都是发生在容器的读写层,镜像层+读写层映射为容器内部文件系统、负责容器内部存储的底层架构。当我们需要容器内部应用和外部存储进行交互时,还需要一个外置存储,容器数据卷即提供了这样的功能。
另一方面,容器本身的存储数据都是临时存储,在容器销毁的时候数据会一起删除。而通过数据卷将外部存储挂载到容器文件系统,应用可以引用外部数据,也可以将自己产出的数据持久化到数据卷中,因此容器数据卷是容器实现数据持久化的主要实现方式。
容器存储组成:只读层(容器镜像)+读写层+外置存储(数据卷)
容器数据卷从作用范围可以分为:单机数据卷和集群数据卷。其中单机数据卷即为容器服务在一个节点上的数据卷挂载能力,dockervolume是单机数据卷的代表实现;
DockerVolume是一个可供多个容器使用的目录,它绕过UFS,包含以下特性:
1)Docker数据卷类型
Bind:将主机目录/文件直接挂载到容器内部。
Volume:使用第三方数据卷的时候使用这种方式。
Tmpfs:非持久化的卷类型,存储在内存中。
2)数据卷使用语法
Bind挂载语法
-v:src:dst:opts只支持单机版。
示例:
$dockerrun-d--namedevtest-v/home:/data:ro,rslavenginx$dockerrun-d--namedevtest--mounttype=bind,source=/home,target=/data,readonly,bind-propagation=rslavenginx$dockerrun-d--namedevtest-v/home:/data:znginx
Volume挂载方式语法
-v:src:dst:opts只支持单机版。
示例:
$dockerrun-d--namedevtest-vmyvol:/app:ronginx$dockerrun-d--namedevtest--mountsource=myvol2,target=/app,readonlynginx3)Docker数据卷插件
Docker数据卷实现了将容器外部存储挂载到容器文件系统的方式。为了扩展容器对外部存储类型的需求,docker提出了通过存储插件的方式挂载不同类型的存储服务。扩展插件统称为VolumeDriver,可以为每种存储类型开发一种存储插件。
可以查看官方文档链接:
其特性简单来说可以总结为2点:
关于Volumeplugin的代码实现,可以参考这篇小文章:源码解析
DockerPlugin是以WebService的服务运行在每一台DockerHost上的,通过HTTP协议传输RPC风格的JSON数据完成通信。Plugin的启动和停止,并不归Docker管理,DockerDaemon依靠在缺省路径下查找UnixSocket文件,自动发现可用的插件。
当客户端与Daemon交互,使用插件创建数据卷时,Daemon会在后端找到插件对应的socket文件,建立连接并发起相应的API请求,最终结合Daemon自身的处理完成客户端的请求。
DockerDaemon与Volumedriver通信方式有:
Sock文件:linux下放在/run/docker/plugins目录下
Spec文件:/etc/docker/plugins/定义
Json文件:/usr/lib/docker/plugins/定义
实现接口:
使用示例:
$dockervolumecreate--drivernas-odiskid=""-ohost="10.46.225.247"-opath=”/nas1"-omode=""--namenas1
DockerVolumeDriver适用在单机容器环境或者swarm平台进行数据卷管理,随着K8s的流行其使用场景已经越来越少,这里不做赘述。
K8s原生存储卷
Kubernetes提供是卷存储类型,从存在的生命周期可分为临时和持久卷。从卷的类型分,又可以分为本地存储、网络存储、Secret/ConfigMap、CSI/Flexvolume、PVC;有兴趣的小伙伴可以参考一下官方文档:
【Kubernetes文档-卷】
这里就以一幅图来展示各个存储的存在形式。
如上图所示:
最上层的pod和PVC由用户管理,pod创建volume卷,并指定存储方式。
中间部分由集群管理者创建StorageClass对象,StorageClass只需确定PV属性(存储类型,大小等)及创建PV所需要用的的存储插件;K8s会自动根据用户提交的PVC来找到对应的StorageClass,之后根据其定义的存储插件,创建出PV。
最下层指代各个实际的存储资源。
PV和PVC
这里单独来聊聊PV和PVC,也是实际应用场景中最常用的一组概念,其中:
PV是PersistentVolume的缩写,译为持久化存储卷;PV在K8s中代表一个具体存储类型的卷,其对象中定义了具体存储类型和卷参数。即目标存储服务所有相关的信息都保存在PV中,K8s引用PV中的存储信息执行挂载操作。
使用方法
PVC只有绑定了PV之后才能被Pod使用,而PVC绑定PV的过程即是消费PV的过程,这个过程是有一定规则的,下面规则都满足的PV才能被PVC绑定:
VolumeMode:被消费PV的VolumeMode需要和PVC一致;
AccessMode:被消费PV的AccessMode需要和PVC一致;
StorageClassName:如果PVC定义了此参数,PV必须有相关的参数定义才能进行绑定;
LabelSelector:通过label匹配的方式从PV列表中选择合适的PV绑定;
storage:被消费PV的capacity必须大于或者等于PVC的存储容量需求才能被绑定。
PVC模板:
apiVersion:v1kind:PersistentVolumeClaimmetadata:name:disk-1spec:accessModes:-ReadWriteOnceresources:requests:storage:20GistorageClassName:test-diskvolumeMode:Filesystem
PV模板:
apiVersion:v1kind:PersistentVolumemetadata:labels:/region:/zone:cn-znname:d-wz9g2j5qbo37r2lamkg4spec:accessModes:-ReadWriteOncecapacity:storage:30GiflexVolume:driver:alicloud/diskfsType:ext4options:VolumeId:d-wz9g2j5qbo37r2lamkg4persistentVolumeReclaimPolicy:DeletestorageClassName:test-diskvolumeMode:Filesystem开源存储项目CephRook
围绕云原生技术的工具和项目正在大量涌现。作为生产中最突出的问题之一,有相当一部分开源项目致力于解决“在云原生架构上处理存储”这个问题。
目前最受欢迎的存储项目是Ceph和Rook。
Ceph是一个动态管理的、水平可伸缩的分布式存储集群。Ceph提供了对存储资源的逻辑抽象。它被设计成不存在单点故障、可自我管理和基于软件的。Ceph同时为相同的存储集群提供块、对象或文件系统接口。它能够提供非常稳定的块存储系统,并且K8S对Ceph放出了完整的生态,几乎可以说是全面兼容。
Ceph的架构非常复杂,有许多底层技术,如RADOS、librados、RADOSGW、RDB,它的CRUSH算法和监视器、OSD和MDS等组件。这里不深入解读其架构,关键在于,Ceph是一个分布式存储集群,它可提供更高的可伸缩性,在不牺牲性能的情况下消除了单点故障,并提供了对对象、块和文件的访问的统一存储。
对于Rook,我们可以从以下几点来了解这个有趣的项目。它旨在聚合Kubernetes和Ceph的工具——将计算和存储放在一个集群中。
Rook是一个开源的cloud-nativestorage编排,提供平台和框架;为各种存储解决方案提供平台、框架和支持,以便与云原生环境本地集成。
Rook将存储软件转变为自我管理、自我扩展和自我修复的存储服务,它通过自动化部署、引导、配置、置备、扩展、升级、迁移、灾难恢复、监控和资源管理来实现此目的。
Rook使用底层云本机容器管理、调度和编排平台提供的工具来实现它自身的功能。
Rook目前支持Ceph、NFS、MinioObjectStore和CockroachDB。
Rook使用Kubernetes原语使Ceph存储系统能够在Kubernetes上运行。
所以在ROOK的帮助之下我们甚至可以做到一键编排部署Ceph,同时部署结束之后的运维工作ROOK也会介入自动进行实现对存储拓展,即便是集群出现了问题ROOK也能在一定程度上保证存储的高可用性,绝大多数情况之下甚至不需要Ceph的运维知识都可以正常使用。
安装方法
1.获取rook仓库:
2.获取部署yaml文件
rook仓库中,cluster/examples/kubernetes/ceph/文件。
运行文件
4.安装完成之后,需要等待所有操作器正常运行之后才能继续还是ceph分部署集群的安装
这里是最重要的,mon是存储集群的监控器,我们K8S里面有多少主机这里的就必须使用多少个moncount:3allowMultiplePerNode:falsedashboard:监控面板是否使用SSL,如果是使用8443端口,不是则使用7000端口,由于这是运维人员使用建议不启用ssl:truemonitoring:enabled:falserulesNamespace:rook-cephnetwork:hostNetwork:falserbdMirroring:workers:0crashCollector:disable:falseannotations:resources:removeOSDsIfOutAndSafeToRemove:falsestorage:useAllNodes:trueuseAllDevices:trueconfig:disruptionManagement:managePodBudgets:falseosdMaintenanceTimeout:30manageMachineDisruptionBudgets:falsemachineDisruptionBudgetNamespace:openshift-machine-api
dashboard没有启用安装Ceph工具
8,创建存储系统与存储类
集群搭建完毕之后便是存储的创建,目前Ceph支持块存储、文件系统存储、对象存储三种方案,K8S官方对接的存储方案是块存储,他也是比较稳定的方案,但是块存储目前不支持多主机读写;文件系统存储是支持多主机存储的性能也不错;对象存储系统IO性能太差不考虑,所以可以根据要求自行决定。
存储系统创建完成之后对这个系统添加一个存储类之后整个集群才能通过K8S的存储类直接使用Ceph存储。
块存储系统+块存储类yaml文件:
apiVersion:/v1kind:CephBlockPoolmetadata:name:replicapoolnamespace:rook-cephspec:failureDomain:hostreplicated:size:3这里的数字分部署数量,一样有几台主机便写入对应的值dataPools:-replicated:size:3#这里的数字分部署数量,一样有几台主机便写入对应的值preservePoolsOnDelete:truemetadataServer:activeCount:1activeStandby:true
文件系统存储类yaml文件:
apiVersion:/v1kind:StorageClassmetadata:name:csi-cephfsprovisioner::clusterID:rook-cephfsName:myfspool:/provisioner-secret-name:/provisioner-secret-namespace:/node-stage-secret-name:/node-stage-secret-namespace:rook-cephreclaimPolicy:Delete总结
本文通过介绍并图解K8s中各个存储方案实现方式以及可选择的开源项目,为读者呈现更全面的K8s存储方案选择。在我们实际的使用场景中,亦需要根据特定的需求来制定符合项目要求的存储方案,从而达到最好的实现效果。也希望有更多的朋友能够加入到kubernetes的队伍中来,让kubernetes真正深入到众多的用户和企业中去。





