本文来自IT168网站,作者/IT168网站。
随着容器为互联网应用提供的敏捷开发、快速交付,对传统金融IT带来了技术革新的挑战。针对数据爆炸式增长、应用复杂性提高、业务品种快速更新、应用系统软件快速迭代等一系列挑战,容器技术在金融行业数字化转型浪潮中越来越受到青睐。
本文主要从容器云对存储的使用方面做建议介绍。Kubernetes支持很多类型的卷,Pod可以同时使用任意数目的卷类型。临时卷类型的生命周期与Pod相同,但持久卷可以比Pod的存活期长。当Pod不再存在时,Kubernetes也会销毁临时卷;不过Kubernetes不会销毁持久卷。对于给定Pod中任何类型的卷,在容器重启期间数据都不会丢失,卷挂载在镜像中的指定路径下。容器对接存储,都会使用一个存储CSI插件进行连接和管理。
容器云中存储的分类
Kubernetes能使用的存储可以分为如下几类:
1)临时存储
常见的临时存储主要是emptyDir卷,当Pod分派到某个Node上时,emptyDir卷会被创建,并且Pod在该节点上运行期间,卷一直存在。当Pod因为某些原因被从节点上删除时,emptyDir卷中的数据也会被永久删除。一般情况下emptyDir存储都是用来充当临时存储空间。emptyDir常见的一些用途如:(1)缓存空间,例如基于磁盘的归并排序。(2)为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。(3)在Web服务器容器服务数据时,保存内容管理器容器获取的文件。
2)半持久存储
半持久化存储主要是HostPath。当使用HostPath卷时,它的范围应尽量限于所需的文件或目录,并以只读方式挂载。HostPath常见的一些用途如:(1)运行一个需要访问Docker内部机制的容器;可使用hostPath挂载/var/lib/docker路径。(2)在容器中运行cAdvisor时,以hostPath方式挂载/sys。(3)允许Pod指定给定的hostPath在运行Pod之前是否应该存在,是否应该创建以及应该以什么方式存在。
3)持久化存储
对于持久化存储,Kubernetest引入了StorageClass,Volume,PVC,PV的概念。Kubernetes支持的持久化存储包括主流的块存储、对象存储和网络文件存储等等。Kubernetes引入了两个新的API资源:PersistentVolume和PersistentVolumeClaim。持久卷(PersistentVolume,PV)是集群中的一块存储,可以由管理员事先制备,或者使用存储类(Storage Class)来动态制备。持久卷是集群资源,就像节点也是集群资源一样。
4)特殊存储
特殊存储类主要包括secret,configMap等。(1)secret卷用来给Pod传递敏感信息,例如密码。secret卷由tmpfs(基于RAM的文件系统)提供存储,因此它们永远不会被写入非易失性(持久化的)存储器。(2)ConfigMap提供了向Pod注入配置数据的方法,用来将非机密性的数据保存到键值对中,比如存储卷中的配置文件,以key-value的形式调用。
容器云中存储的使用
Kubernetes中,PV卷是集群中的资源。PVC申领是对这些资源的请求,也被用来执行对资源的申领检查。PV卷和PVC的使用过程一般如下:
1)制备:PV卷的制备有两种方式:静态制备或动态制备。(1)静态制备。集群管理员创建若干PV卷。这些卷对象带有真实存储的细节信息,并且对集群用户可用。(2)动态制备。动态制备操作是基于StorageClass来实现的:PVC申领必须请求某个存储类,同时集群管理员必须已经创建并配置了该类,这样动态制备卷的动作才会发生。如果PVC申领指定存储类为“”(空),则相当于为自身禁止使用动态制备的卷。
2)绑定:用户创建一个带有特定存储容量和特定访问模式需求的PersistentVolumeClaim对象;在动态制备场景下,这个PVC对象可能已经创建完毕。一旦PV与PVC的绑定关系建立,则PersistentVolumeClaim绑定就是排他性的,PVC申领与PV卷之间的绑定是一种一对一的映射。
如果找不到匹配的PV卷,PVC申领会无限期地处于未绑定状态。当与之匹配的PV卷可用时,PVC申领会被绑定。例如,即使某集群上制备了很多10 Gi大小的PV卷,也无法与请求20 Gi大小的存储的PVC匹配。当新的20 Gi PV卷被加入到集群时,该PVC才有可能被绑定。
3)使用:Pod将PVC申领当做存储卷来使用。集群会检查PVC申领,找到所绑定的卷,并为Pod挂载该卷。对于支持多种访问模式的卷,用户要在Pod中以卷的形式使用申领时指定期望的访问模式。
4)保护使用中的存储对象:保护使用中的存储对象(Storage Object in Use Protection)这一功能特性的目的是确保仍被Pod使用的PersistentVolumeClaim(PVC)对象及其所绑定的PersistentVolume(PV)对象在系统中不会被删除,因为这样做可能会引起数据丢失。
5)回收(Reclaiming):当用户不再使用其存储卷时,他们可以从API中将PVC对象删除,从而允许该资源被回收再利用。PersistentVolume对象的回收策略告诉集群,当其被从申领中释放时如何处理该数据卷。目前,数据卷可以被Retained(保留)、Recycled(回收)或Deleted(删除)。
保留(Retain):回收策略Retain使得用户可以手动回收资源。当PersistentVolumeClaim对象被删除时,PersistentVolume卷仍然存在,对应的数据卷被视为"已释放(released)"。
删除(Delete):对于支持Delete回收策略的卷插件,删除动作会将PersistentVolume对象从Kubernetes中移除,同时也会从外部基础设施(如AWS EBS、CEPH)中移除所关联的存储资产。
回收(Recycle):回收策略Recycle在Kubernetes新版本中已被废弃。取而代之的建议方案是使用动态制备。
容器云存储的落地实践
目前,我们银行已经在开发测试和生产环境部署了多套容器云集群平台,并已经承载运行了重要应用系统的服务。现阶段主要还是将无状态的应用容器化,数据库、中间件等一些有状态的组件仍在虚拟机中运行,将在未来逐步迁移。行内容器云平台涉及到的持久化存储主要分为如下几大块:
1)容器镜像类数据存储。在内网环境中,建立一套自己的私有镜像仓库,做好相关配置后容器云平台就可以从私有镜像库中拉取镜像。当有pod所在服务器宕机或故障,pod需要在新节点启动时,这时就会需要向私有镜像库拉取镜像,当生产环境pod数量达到一定规模时,需要考虑多镜像并行拉取导致的IO风暴。所以容器镜像类数据存储建议采用分布式块存储,能够承担一定的并发能力和有一定扩展能力的持久性存储,当然有存量集中式块存储也是可以利旧以节约投资,同时也要考虑做好该部分存储的备份或私有镜像仓库的冗余存储。
2)Pod/container类数据存储。容器云集群的Etcd的数据会时刻以日志的形式记录在内存和硬盘中,etcd对磁盘的延迟会非常敏感,建议将Etcd部署在物理机/虚拟机(视集群规模)中,底层存储配置SSD磁盘,保证低延迟、高性能的写入。大部分应用Pod/container对于存储性能要求不高,主要耗费计算资源,所以Pod/container在node上运行的镜像建议采用服务器本地盘存储即可。
3)应用之间共享类数据存储。不管是有状态还是无状态应用之间需要共享数据时,NFS是一个主流的文件共享服务器。NFS数据卷可以提供对NFS挂载支持,可以自动将NFS共享路径挂载到Pod中。在各应用pod中需文件共享时建议采用NAS双活存储提供的NFS文件系统以满足业务系统文件共享需求。
4)日志类数据存储。日志类数据收集,一般有如下常见几种方案。(1)app的镜像中自己集成日志收集组件,好处在于app应用的yaml文件不需要特殊配置,一个镜像解决问题,但是同时也造成耦合性强,未来组件或应用无法单独升级。(2)在同一个pod中运行app容器和日志收集组件容器,相较如上方案降低了耦合度,但是pod的yaml文件需单独编写、配置,较繁琐。(3)直接将pod的日志挂在到宿主机node,每台node起一个pod或者采用二进制进程进行日志收集,好处是收集日志与应用pod完全解耦,管理方便,只需要做好日志输出规范,统一日志目录和输出方式即可,此方式日志存储性能高。日志类数据存储建议可采用pod日志输出挂载在本地服务器的存储,通过Filebeat+Logstash+ElasticSearch+Kibana(ELK)或者Fluentd+Filebeat+Elasticsearch+Kibana(EFK)构建统一的日志采集、分类、分析、查询、展示平台。
在整个容器云平台的持久化存储选型过程中,比如在日志类数据存储我们也有考虑将其存放于分布式块存储(如ceph、longhorn等)上做日志统一存储平台,但是为沿用已有的ELK日志收集展示平台、初期容器规模较小等原因,暂将分布式块存储列为二期规划建设。一期主要完成无状态应用的容器化工作,二期将重点放在有状态应用(如redis、zk、轻载mysql等)的容器化,建议部署为StatefulSet,当节点重启漂移到其他机器上时,可通过挂载的PVC(PersistentVolumeClaim)拿到原来的完整数据,但是分布式存储带来的读写延迟需要根据不同的容器化应用敏感程度配置不同性能的分布式存储,以满足对业务发展的IO需求。
总而言之,容器云持久化存储最佳实践没有一个统一使用某种存储的完美方案,而是需要根据业务类型、系统重要等级、集群规模、扩展性等多方面进行综合考量,再结合本行的一个长远规划进行存储架构设计,以匹配科技战略,助力业务发展。